Skip to content
Snippets Groups Projects
Commit 64714603 authored by Carlos Natalino Da Silva's avatar Carlos Natalino Da Silva
Browse files

Merge branch 'develop' into feat/opt-cybersecurity

parents 116056a5 d2dc573e
No related branches found
No related tags found
2 merge requests!142Release TeraFlowSDN 2.1,!97Optical cybersecurity scenario
...@@ -48,22 +48,25 @@ message ScalarOrRange { ...@@ -48,22 +48,25 @@ message ScalarOrRange {
message Parameters { message Parameters {
uint64 num_requests = 1; // if == 0, generate infinite requests uint64 num_requests = 1; // if == 0, generate infinite requests
repeated RequestTypeEnum request_types = 2; repeated RequestTypeEnum request_types = 2;
float offered_load = 3; string device_regex = 3; // Only devices and endpoints matching the regex expression will be considered as
float holding_time = 4; string endpoint_regex = 4; // source-destination candidates for the requests generated.
float inter_arrival_time = 5; float offered_load = 5;
repeated ScalarOrRange availability = 6; // one from the list is selected float holding_time = 6;
repeated ScalarOrRange capacity_gbps = 7; // one from the list is selected float inter_arrival_time = 7;
repeated ScalarOrRange e2e_latency_ms = 8; // one from the list is selected repeated ScalarOrRange availability = 8; // One from the list is selected to populate the constraint
uint32 max_workers = 9; repeated ScalarOrRange capacity_gbps = 9; // One from the list is selected to populate the constraint
bool do_teardown = 10; repeated ScalarOrRange e2e_latency_ms = 10; // One from the list is selected to populate the constraint
bool dry_mode = 11; uint32 max_workers = 11;
bool record_to_dlt = 12; bool do_teardown = 12;
string dlt_domain_id = 13; bool dry_mode = 13;
bool record_to_dlt = 14;
string dlt_domain_id = 15;
} }
message Status { message Status {
Parameters parameters = 1; Parameters parameters = 1;
uint64 num_generated = 2; uint64 num_generated = 2;
bool infinite_loop = 3; uint64 num_released = 3;
bool running = 4; bool infinite_loop = 4;
bool running = 5;
} }
...@@ -34,6 +34,8 @@ def main(): ...@@ -34,6 +34,8 @@ def main():
RequestType.SLICE_L2NM, RequestType.SLICE_L2NM,
RequestType.SLICE_L3NM, RequestType.SLICE_L3NM,
], ],
device_regex=r'.+',
endpoint_regex=r'.+',
offered_load = 50, offered_load = 50,
holding_time = 10, holding_time = 10,
availability_ranges = [[0.0, 99.9999]], availability_ranges = [[0.0, 99.9999]],
......
...@@ -20,16 +20,27 @@ from load_generator.tools.ListScalarRange import Type_ListScalarRange ...@@ -20,16 +20,27 @@ from load_generator.tools.ListScalarRange import Type_ListScalarRange
class Parameters: class Parameters:
def __init__( def __init__(
self, num_requests : int, request_types : List[str], offered_load : Optional[float] = None, self,
inter_arrival_time : Optional[float] = None, holding_time : Optional[float] = None, num_requests : int,
request_types : List[str],
device_regex : Optional[str] = None,
endpoint_regex : Optional[str] = None,
offered_load : Optional[float] = None,
inter_arrival_time : Optional[float] = None,
holding_time : Optional[float] = None,
availability_ranges : Type_ListScalarRange = DEFAULT_AVAILABILITY_RANGES, availability_ranges : Type_ListScalarRange = DEFAULT_AVAILABILITY_RANGES,
capacity_gbps_ranges : Type_ListScalarRange = DEFAULT_CAPACITY_GBPS_RANGES, capacity_gbps_ranges : Type_ListScalarRange = DEFAULT_CAPACITY_GBPS_RANGES,
e2e_latency_ms_ranges : Type_ListScalarRange = DEFAULT_E2E_LATENCY_MS_RANGES, e2e_latency_ms_ranges : Type_ListScalarRange = DEFAULT_E2E_LATENCY_MS_RANGES,
max_workers : int = DEFAULT_MAX_WORKERS, do_teardown : bool = True, dry_mode : bool = False, max_workers : int = DEFAULT_MAX_WORKERS,
record_to_dlt : bool = False, dlt_domain_id : Optional[str] = None do_teardown : bool = True,
dry_mode : bool = False,
record_to_dlt : bool = False,
dlt_domain_id : Optional[str] = None
) -> None: ) -> None:
self._num_requests = num_requests self._num_requests = num_requests
self._request_types = request_types self._request_types = request_types
self._device_regex = r'.*' if (device_regex is None or len(device_regex) == 0) else device_regex
self._endpoint_regex = r'.*' if (endpoint_regex is None or len(endpoint_regex) == 0) else endpoint_regex
self._offered_load = offered_load self._offered_load = offered_load
self._inter_arrival_time = inter_arrival_time self._inter_arrival_time = inter_arrival_time
self._holding_time = holding_time self._holding_time = holding_time
...@@ -62,6 +73,12 @@ class Parameters: ...@@ -62,6 +73,12 @@ class Parameters:
@property @property
def request_types(self): return self._request_types def request_types(self): return self._request_types
@property
def device_regex(self): return self._device_regex
@property
def endpoint_regex(self): return self._endpoint_regex
@property @property
def offered_load(self): return self._offered_load def offered_load(self): return self._offered_load
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import logging, json, random, re, threading import logging, json, random, re, threading, uuid
from typing import Dict, Optional, Set, Tuple from typing import Dict, Optional, Set, Tuple
from common.proto.context_pb2 import Empty, IsolationLevelEnum, TopologyId from common.proto.context_pb2 import Empty, IsolationLevelEnum, TopologyId
from common.tools.grpc.Tools import grpc_message_to_json from common.tools.grpc.Tools import grpc_message_to_json
...@@ -54,6 +54,7 @@ class RequestGenerator: ...@@ -54,6 +54,7 @@ class RequestGenerator:
self._parameters = parameters self._parameters = parameters
self._lock = threading.Lock() self._lock = threading.Lock()
self._num_generated = 0 self._num_generated = 0
self._num_released = 0
self._available_device_endpoints : Dict[str, Set[str]] = dict() self._available_device_endpoints : Dict[str, Set[str]] = dict()
self._used_device_endpoints : Dict[str, Dict[str, str]] = dict() self._used_device_endpoints : Dict[str, Dict[str, str]] = dict()
self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict() self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict()
...@@ -65,6 +66,9 @@ class RequestGenerator: ...@@ -65,6 +66,9 @@ class RequestGenerator:
@property @property
def num_generated(self): return self._num_generated def num_generated(self): return self._num_generated
@property
def num_released(self): return self._num_released
@property @property
def infinite_loop(self): return self._parameters.num_requests == 0 def infinite_loop(self): return self._parameters.num_requests == 0
...@@ -79,13 +83,21 @@ class RequestGenerator: ...@@ -79,13 +83,21 @@ class RequestGenerator:
if self._parameters.record_to_dlt: if self._parameters.record_to_dlt:
dlt_domain_id = TopologyId(**json_topology_id('dlt-perf-eval')) dlt_domain_id = TopologyId(**json_topology_id('dlt-perf-eval'))
re_device = re.compile(r'^{:s}$'.format(self._parameters.device_regex))
re_endpoint = re.compile(r'^{:s}$'.format(self._parameters.endpoint_regex))
devices = context_client.ListDevices(Empty()) devices = context_client.ListDevices(Empty())
for device in devices.devices: for device in devices.devices:
if self._parameters.record_to_dlt:
record_device_to_dlt(dlt_connector_client, dlt_domain_id, device.device_id)
if re_device.match(device.name) is None: continue
device_uuid = device.device_id.device_uuid.uuid device_uuid = device.device_id.device_uuid.uuid
self._device_data[device_uuid] = grpc_message_to_json(device) self._device_data[device_uuid] = grpc_message_to_json(device)
_endpoints = self._available_device_endpoints.setdefault(device_uuid, set()) _endpoints = self._available_device_endpoints.setdefault(device_uuid, set())
for endpoint in device.device_endpoints: for endpoint in device.device_endpoints:
if re_endpoint.match(endpoint.name) is None: continue
endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
endpoints = self._device_endpoint_data.setdefault(device_uuid, dict()) endpoints = self._device_endpoint_data.setdefault(device_uuid, dict())
endpoints[endpoint_uuid] = grpc_message_to_json(endpoint) endpoints[endpoint_uuid] = grpc_message_to_json(endpoint)
...@@ -94,12 +106,12 @@ class RequestGenerator: ...@@ -94,12 +106,12 @@ class RequestGenerator:
_endpoints.add(endpoint_uuid) _endpoints.add(endpoint_uuid)
self._endpoint_ids_to_types.setdefault((device_uuid, endpoint_uuid), endpoint_type) self._endpoint_ids_to_types.setdefault((device_uuid, endpoint_uuid), endpoint_type)
self._endpoint_types_to_ids.setdefault(endpoint_type, set()).add((device_uuid, endpoint_uuid)) self._endpoint_types_to_ids.setdefault(endpoint_type, set()).add((device_uuid, endpoint_uuid))
if self._parameters.record_to_dlt:
record_device_to_dlt(dlt_connector_client, dlt_domain_id, device.device_id)
links = context_client.ListLinks(Empty()) links = context_client.ListLinks(Empty())
for link in links.links: for link in links.links:
if self._parameters.record_to_dlt:
record_link_to_dlt(dlt_connector_client, dlt_domain_id, link.link_id)
for endpoint_id in link.link_endpoint_ids: for endpoint_id in link.link_endpoint_ids:
device_uuid = endpoint_id.device_id.device_uuid.uuid device_uuid = endpoint_id.device_id.device_uuid.uuid
endpoint_uuid = endpoint_id.endpoint_uuid.uuid endpoint_uuid = endpoint_id.endpoint_uuid.uuid
...@@ -115,9 +127,6 @@ class RequestGenerator: ...@@ -115,9 +127,6 @@ class RequestGenerator:
endpoint_key = (device_uuid, endpoint_uuid) endpoint_key = (device_uuid, endpoint_uuid)
if endpoint_key not in endpoints_for_type: continue if endpoint_key not in endpoints_for_type: continue
endpoints_for_type.discard(endpoint_key) endpoints_for_type.discard(endpoint_key)
if self._parameters.record_to_dlt:
record_link_to_dlt(dlt_connector_client, dlt_domain_id, link.link_id)
def dump_state(self) -> None: def dump_state(self) -> None:
with self._lock: with self._lock:
...@@ -192,23 +201,18 @@ class RequestGenerator: ...@@ -192,23 +201,18 @@ class RequestGenerator:
if not self.infinite_loop and (self._num_generated >= self._parameters.num_requests): if not self.infinite_loop and (self._num_generated >= self._parameters.num_requests):
LOGGER.info('Generation Done!') LOGGER.info('Generation Done!')
return True, None, None # completed return True, None, None # completed
self._num_generated += 1
num_request = self._num_generated
#request_uuid = str(uuid.uuid4()) request_uuid = str(uuid.uuid4())
request_uuid = 'svc_{:d}'.format(num_request)
# choose request type
request_type = random.choice(self._parameters.request_types) request_type = random.choice(self._parameters.request_types)
if request_type in { if request_type in {
RequestType.SERVICE_L2NM, RequestType.SERVICE_L3NM, RequestType.SERVICE_TAPI, RequestType.SERVICE_MW RequestType.SERVICE_L2NM, RequestType.SERVICE_L3NM, RequestType.SERVICE_TAPI, RequestType.SERVICE_MW
}: }:
return False, self._compose_service(num_request, request_uuid, request_type), request_type return False, self._compose_service(request_uuid, request_type), request_type
elif request_type in {RequestType.SLICE_L2NM, RequestType.SLICE_L3NM}: elif request_type in {RequestType.SLICE_L2NM, RequestType.SLICE_L3NM}:
return False, self._compose_slice(num_request, request_uuid, request_type), request_type return False, self._compose_slice(request_uuid, request_type), request_type
def _compose_service(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: def _compose_service(self, request_uuid : str, request_type : str) -> Optional[Dict]:
# choose source endpoint # choose source endpoint
src_endpoint_types = set(ENDPOINT_COMPATIBILITY.keys()) if request_type in {RequestType.SERVICE_TAPI} else None src_endpoint_types = set(ENDPOINT_COMPATIBILITY.keys()) if request_type in {RequestType.SERVICE_TAPI} else None
src = self._use_device_endpoint(request_uuid, request_type, endpoint_types=src_endpoint_types) src = self._use_device_endpoint(request_uuid, request_type, endpoint_types=src_endpoint_types)
...@@ -237,6 +241,10 @@ class RequestGenerator: ...@@ -237,6 +241,10 @@ class RequestGenerator:
self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) self._release_device_endpoint(src_device_uuid, src_endpoint_uuid)
return None return None
with self._lock:
self._num_generated += 1
num_request = self._num_generated
# compose endpoints # compose endpoints
dst_device_uuid,dst_endpoint_uuid = dst dst_device_uuid,dst_endpoint_uuid = dst
endpoint_ids = [ endpoint_ids = [
...@@ -383,7 +391,7 @@ class RequestGenerator: ...@@ -383,7 +391,7 @@ class RequestGenerator:
return json_service_l2nm_planned( return json_service_l2nm_planned(
request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules) request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules)
def _compose_slice(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: def _compose_slice(self, request_uuid : str, request_type : str) -> Optional[Dict]:
# choose source endpoint # choose source endpoint
src = self._use_device_endpoint(request_uuid, request_type) src = self._use_device_endpoint(request_uuid, request_type)
if src is None: if src is None:
...@@ -404,6 +412,10 @@ class RequestGenerator: ...@@ -404,6 +412,10 @@ class RequestGenerator:
self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) self._release_device_endpoint(src_device_uuid, src_endpoint_uuid)
return None return None
with self._lock:
self._num_generated += 1
num_request = self._num_generated
# compose endpoints # compose endpoints
dst_device_uuid,dst_endpoint_uuid = dst dst_device_uuid,dst_endpoint_uuid = dst
endpoint_ids = [ endpoint_ids = [
...@@ -505,8 +517,15 @@ class RequestGenerator: ...@@ -505,8 +517,15 @@ class RequestGenerator:
device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
self._release_device_endpoint(device_uuid, endpoint_uuid) self._release_device_endpoint(device_uuid, endpoint_uuid)
with self._lock:
self._num_released += 1
elif 'slice_id' in json_request: elif 'slice_id' in json_request:
for endpoint_id in json_request['slice_endpoint_ids']: for endpoint_id in json_request['slice_endpoint_ids']:
device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
self._release_device_endpoint(device_uuid, endpoint_uuid) self._release_device_endpoint(device_uuid, endpoint_uuid)
with self._lock:
self._num_released += 1
...@@ -57,6 +57,9 @@ class RequestScheduler: ...@@ -57,6 +57,9 @@ class RequestScheduler:
@property @property
def num_generated(self): return min(self._generator.num_generated, self._parameters.num_requests) def num_generated(self): return min(self._generator.num_generated, self._parameters.num_requests)
@property
def num_released(self): return min(self._generator.num_released, self._parameters.num_requests)
@property @property
def infinite_loop(self): return self._generator.infinite_loop def infinite_loop(self): return self._generator.infinite_loop
......
...@@ -37,6 +37,8 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): ...@@ -37,6 +37,8 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer):
self._parameters = LoadGen_Parameters( self._parameters = LoadGen_Parameters(
num_requests = request.num_requests, num_requests = request.num_requests,
request_types = [REQUEST_TYPE_MAP[rt] for rt in request.request_types], request_types = [REQUEST_TYPE_MAP[rt] for rt in request.request_types],
device_regex = request.device_regex,
endpoint_regex = request.endpoint_regex,
offered_load = request.offered_load if request.offered_load > 1.e-12 else None, offered_load = request.offered_load if request.offered_load > 1.e-12 else None,
holding_time = request.holding_time if request.holding_time > 1.e-12 else None, holding_time = request.holding_time if request.holding_time > 1.e-12 else None,
inter_arrival_time = request.inter_arrival_time if request.inter_arrival_time > 1.e-12 else None, inter_arrival_time = request.inter_arrival_time if request.inter_arrival_time > 1.e-12 else None,
...@@ -73,11 +75,14 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): ...@@ -73,11 +75,14 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer):
status = Status() status = Status()
status.num_generated = self._scheduler.num_generated status.num_generated = self._scheduler.num_generated
status.num_released = self._scheduler.num_released
status.infinite_loop = self._scheduler.infinite_loop status.infinite_loop = self._scheduler.infinite_loop
status.running = self._scheduler.running status.running = self._scheduler.running
stat_pars = status.parameters # pylint: disable=no-member stat_pars = status.parameters # pylint: disable=no-member
stat_pars.num_requests = params.num_requests # pylint: disable=no-member stat_pars.num_requests = params.num_requests # pylint: disable=no-member
stat_pars.device_regex = params.device_regex # pylint: disable=no-member
stat_pars.endpoint_regex = params.endpoint_regex # pylint: disable=no-member
stat_pars.offered_load = params.offered_load # pylint: disable=no-member stat_pars.offered_load = params.offered_load # pylint: disable=no-member
stat_pars.holding_time = params.holding_time # pylint: disable=no-member stat_pars.holding_time = params.holding_time # pylint: disable=no-member
stat_pars.inter_arrival_time = params.inter_arrival_time # pylint: disable=no-member stat_pars.inter_arrival_time = params.inter_arrival_time # pylint: disable=no-member
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
# limitations under the License. # limitations under the License.
from flask import render_template, Blueprint, flash, session, redirect, url_for from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for
from common.proto.context_pb2 import Empty, Link, LinkList from common.proto.context_pb2 import Empty, Link, LinkId, LinkList
from common.tools.context_queries.EndPoint import get_endpoint_names from common.tools.context_queries.EndPoint import get_endpoint_names
from common.tools.context_queries.Link import get_link from common.tools.context_queries.Link import get_link
from common.tools.context_queries.Topology import get_topology from common.tools.context_queries.Topology import get_topology
...@@ -65,3 +65,25 @@ def detail(link_uuid: str): ...@@ -65,3 +65,25 @@ def detail(link_uuid: str):
device_names, endpoints_data = get_endpoint_names(context_client, link_obj.link_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, link_obj.link_endpoint_ids)
context_client.close() context_client.close()
return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data) return render_template('link/detail.html',link=link_obj, device_names=device_names, endpoints_data=endpoints_data)
@link.get('<path:link_uuid>/delete')
def delete(link_uuid):
try:
# first, check if link exists!
# request: LinkId = LinkId()
# request.link_uuid.uuid = link_uuid
# response: Link = client.GetLink(request)
# TODO: finalize implementation
request = LinkId()
request.link_uuid.uuid = link_uuid # pylint: disable=no-member
context_client.connect()
context_client.RemoveLink(request)
context_client.close()
flash(f'Link "{link_uuid}" deleted successfully!', 'success')
except Exception as e: # pylint: disable=broad-except
flash(f'Problem deleting link "{link_uuid}": {e.details()}', 'danger')
current_app.logger.exception(e)
return redirect(url_for('link.home'))
...@@ -21,9 +21,12 @@ DEFAULT_AVAILABILITY = '0.0..99.9999' ...@@ -21,9 +21,12 @@ DEFAULT_AVAILABILITY = '0.0..99.9999'
DEFAULT_CAPACITY_GBPS = '0.1..100.00' #'10, 40, 50, 100, 400' DEFAULT_CAPACITY_GBPS = '0.1..100.00' #'10, 40, 50, 100, 400'
DEFAULT_E2E_LATENCY_MS = '5.0..100.00' DEFAULT_E2E_LATENCY_MS = '5.0..100.00'
DEFAULT_REGEX = r'.+'
class LoadGenForm(FlaskForm): class LoadGenForm(FlaskForm):
num_requests = IntegerField('Num Requests', default=100, validators=[DataRequired(), NumberRange(min=0)]) num_requests = IntegerField('Num Requests', default=100, validators=[DataRequired(), NumberRange(min=0)])
num_generated = IntegerField('Num Generated', default=0, render_kw={'readonly': True}) num_generated = IntegerField('Num Generated', default=0, render_kw={'readonly': True})
num_released = IntegerField('Num Released', default=0, render_kw={'readonly': True})
request_type_service_l2nm = BooleanField('Service L2NM', default=False) request_type_service_l2nm = BooleanField('Service L2NM', default=False)
request_type_service_l3nm = BooleanField('Service L3NM', default=False) request_type_service_l3nm = BooleanField('Service L3NM', default=False)
...@@ -32,6 +35,9 @@ class LoadGenForm(FlaskForm): ...@@ -32,6 +35,9 @@ class LoadGenForm(FlaskForm):
request_type_slice_l2nm = BooleanField('Slice L2NM', default=True) request_type_slice_l2nm = BooleanField('Slice L2NM', default=True)
request_type_slice_l3nm = BooleanField('Slice L3NM', default=False) request_type_slice_l3nm = BooleanField('Slice L3NM', default=False)
device_regex = StringField('Device selector [regex]', default=DEFAULT_REGEX)
endpoint_regex = StringField('Endpoint selector [regex]', default=DEFAULT_REGEX)
offered_load = FloatField('Offered Load [Erlang]', default=50, validators=[NumberRange(min=0.0)]) offered_load = FloatField('Offered Load [Erlang]', default=50, validators=[NumberRange(min=0.0)])
holding_time = FloatField('Holding Time [seconds]', default=10, validators=[NumberRange(min=0.0)]) holding_time = FloatField('Holding Time [seconds]', default=10, validators=[NumberRange(min=0.0)])
inter_arrival_time = FloatField('Inter Arrival Time [seconds]', default=0, validators=[NumberRange(min=0.0)]) inter_arrival_time = FloatField('Inter Arrival Time [seconds]', default=0, validators=[NumberRange(min=0.0)])
......
...@@ -62,26 +62,29 @@ def home(): ...@@ -62,26 +62,29 @@ def home():
_e2e_latency_ms = list_scalar_range__grpc_to_str(status.parameters.e2e_latency_ms) _e2e_latency_ms = list_scalar_range__grpc_to_str(status.parameters.e2e_latency_ms)
form = LoadGenForm() form = LoadGenForm()
set_properties(form.num_requests , status.parameters.num_requests , readonly=status.running) set_properties(form.num_requests , status.parameters.num_requests , readonly=status.running)
set_properties(form.offered_load , _offered_load , readonly=status.running) set_properties(form.device_regex , status.parameters.device_regex , readonly=status.running)
set_properties(form.holding_time , _holding_time , readonly=status.running) set_properties(form.endpoint_regex , status.parameters.endpoint_regex, readonly=status.running)
set_properties(form.inter_arrival_time , _inter_arrival_time , readonly=status.running) set_properties(form.offered_load , _offered_load , readonly=status.running)
set_properties(form.availability , _availability , readonly=status.running) set_properties(form.holding_time , _holding_time , readonly=status.running)
set_properties(form.capacity_gbps , _capacity_gbps , readonly=status.running) set_properties(form.inter_arrival_time , _inter_arrival_time , readonly=status.running)
set_properties(form.e2e_latency_ms , _e2e_latency_ms , readonly=status.running) set_properties(form.availability , _availability , readonly=status.running)
set_properties(form.max_workers , status.parameters.max_workers , readonly=status.running) set_properties(form.capacity_gbps , _capacity_gbps , readonly=status.running)
set_properties(form.do_teardown , status.parameters.do_teardown , disabled=status.running) set_properties(form.e2e_latency_ms , _e2e_latency_ms , readonly=status.running)
set_properties(form.record_to_dlt , status.parameters.record_to_dlt, disabled=status.running) set_properties(form.max_workers , status.parameters.max_workers , readonly=status.running)
set_properties(form.dlt_domain_id , status.parameters.dlt_domain_id, readonly=status.running) set_properties(form.do_teardown , status.parameters.do_teardown , disabled=status.running)
set_properties(form.request_type_service_l2nm, _request_type_service_l2nm , disabled=status.running) set_properties(form.record_to_dlt , status.parameters.record_to_dlt , disabled=status.running)
set_properties(form.request_type_service_l3nm, _request_type_service_l3nm , disabled=status.running) set_properties(form.dlt_domain_id , status.parameters.dlt_domain_id , readonly=status.running)
set_properties(form.request_type_service_mw , _request_type_service_mw , disabled=status.running) set_properties(form.request_type_service_l2nm, _request_type_service_l2nm , disabled=status.running)
set_properties(form.request_type_service_tapi, _request_type_service_tapi , disabled=status.running) set_properties(form.request_type_service_l3nm, _request_type_service_l3nm , disabled=status.running)
set_properties(form.request_type_slice_l2nm , _request_type_slice_l2nm , disabled=status.running) set_properties(form.request_type_service_mw , _request_type_service_mw , disabled=status.running)
set_properties(form.request_type_slice_l3nm , _request_type_slice_l3nm , disabled=status.running) set_properties(form.request_type_service_tapi, _request_type_service_tapi , disabled=status.running)
set_properties(form.num_generated , status.num_generated , disabled=True) set_properties(form.request_type_slice_l2nm , _request_type_slice_l2nm , disabled=status.running)
set_properties(form.infinite_loop , status.infinite_loop , disabled=True) set_properties(form.request_type_slice_l3nm , _request_type_slice_l3nm , disabled=status.running)
set_properties(form.running , status.running , disabled=True) set_properties(form.num_generated , status.num_generated , disabled=True)
set_properties(form.num_released , status.num_released , disabled=True)
set_properties(form.infinite_loop , status.infinite_loop , disabled=True)
set_properties(form.running , status.running , disabled=True)
form.submit.label.text = 'Stop' if status.running else 'Start' form.submit.label.text = 'Stop' if status.running else 'Start'
form_action = url_for('load_gen.stop') if status.running else url_for('load_gen.start') form_action = url_for('load_gen.stop') if status.running else url_for('load_gen.start')
...@@ -98,6 +101,8 @@ def start(): ...@@ -98,6 +101,8 @@ def start():
load_gen_params = Parameters() load_gen_params = Parameters()
load_gen_params.num_requests = form.num_requests.data load_gen_params.num_requests = form.num_requests.data
load_gen_params.device_regex = form.device_regex.data
load_gen_params.endpoint_regex = form.endpoint_regex.data
load_gen_params.offered_load = form.offered_load.data load_gen_params.offered_load = form.offered_load.data
load_gen_params.holding_time = form.holding_time.data load_gen_params.holding_time = form.holding_time.data
load_gen_params.inter_arrival_time = form.inter_arrival_time.data load_gen_params.inter_arrival_time = form.inter_arrival_time.data
......
...@@ -13,62 +13,92 @@ ...@@ -13,62 +13,92 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
{% extends 'base.html' %}
{% block content %}
<h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1>
<div class="row mb-3">
<div class="col-sm-3">
<button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('link.home') }}'">
<i class="bi bi-box-arrow-in-left"></i>
Back to link list
</button>
</div>
</div>
<br> {% extends 'base.html' %}
<div class="row mb-3">
<div class="col-sm-4"> {% block content %}
<b>UUID: </b>{{ link.link_id.link_uuid.uuid }}<br> <h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1>
<b>Name: </b>{{ link.name }}<br> <div class="row mb-3">
</div> <div class="col-sm-3">
<div class="col-sm-8"> <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('link.home') }}'">
<table class="table table-striped table-hover"> <i class="bi bi-box-arrow-in-left"></i>
<thead> Back to link list
<tr> </button>
<th scope="col">Endpoint UUID</th> </div>
<th scope="col">Name</th> <div class="col-sm-3">
<th scope="col">Device</th> <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete link</button> -->
<th scope="col">Endpoint Type</th> <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
</tr> <i class="bi bi-x-square"></i>
</thead> Delete link
<tbody> </button>
{% for endpoint in link.link_endpoint_ids %} </div>
<tr> </div>
<td>
{{ endpoint.endpoint_uuid.uuid }} <br>
</td> <div class="row mb-3">
<td> <div class="col-sm-4">
{{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }} <b>UUID: </b>{{ link.link_id.link_uuid.uuid }}<br>
</td> <b>Name: </b>{{ link.name }}<br>
<td> </div>
<a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}"> <div class="col-sm-8">
{{ device_names.get(endpoint.device_id.device_uuid.uuid, endpoint.device_id.device_uuid.uuid) }} <table class="table table-striped table-hover">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"> <thead>
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/> <tr>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/> <th scope="col">Endpoint UUID</th>
</svg> <th scope="col">Name</th>
</a> <th scope="col">Device</th>
</td> <th scope="col">Endpoint Type</th>
<td> </tr>
{{ endpoints_data.get(endpoint.endpoint_uuid.uuid, ('', '-'))[1] }} </thead>
</td> <tbody>
</tr> {% for endpoint in link.link_endpoint_ids %}
{% endfor %} <tr>
</tbody> <td>
</table> {{ endpoint.endpoint_uuid.uuid }}
</td>
<td>
{{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }}
</td>
<td>
<a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}">
{{ device_names.get(endpoint.device_id.device_uuid.uuid, endpoint.device_id.device_uuid.uuid) }}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>
</a>
</td>
<td>
{{ endpoints_data.get(endpoint.endpoint_uuid.uuid, ('', '-'))[1] }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Delete link?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Are you sure you want to delete the link "{{ link.link_id.link_uuid.uuid }}"?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
<a type="button" class="btn btn-danger"
href="{{ url_for('link.delete', link_uuid=link.link_id.link_uuid.uuid) }}"><i
class="bi bi-exclamation-diamond"></i>Yes</a>
</div> </div>
</div> </div>
</div>
</div>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -53,6 +53,21 @@ ...@@ -53,6 +53,21 @@
</div> </div>
<br /> <br />
<div class="row mb-3">
{{ form.num_released.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form.num_released.errors %}
{{ form.num_released(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.num_released.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form.num_released(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-2 col-form-label">Service Types:</div> <div class="col-sm-2 col-form-label">Service Types:</div>
<div class="col-sm-10"> <div class="col-sm-10">
...@@ -68,6 +83,36 @@ ...@@ -68,6 +83,36 @@
</div> </div>
<br /> <br />
<div class="row mb-3">
{{ form.device_regex.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form.device_regex.errors %}
{{ form.device_regex(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.device_regex.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form.device_regex(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3">
{{ form.endpoint_regex.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10">
{% if form.endpoint_regex.errors %}
{{ form.endpoint_regex(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in form.endpoint_regex.errors %}<span>{{ error }}</span>{% endfor %}
</div>
{% else %}
{{ form.endpoint_regex(class="form-control") }}
{% endif %}
</div>
</div>
<br />
<div class="row mb-3"> <div class="row mb-3">
{{ form.offered_load.label(class="col-sm-2 col-form-label") }} {{ form.offered_load.label(class="col-sm-2 col-form-label") }}
<div class="col-sm-10"> <div class="col-sm-10">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment