Loading my_deploy.sh +10 −9 Original line number Diff line number Diff line Loading @@ -20,19 +20,18 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. #export TFS_COMPONENTS="context device pathcomp service slice compute webui load_generator" export TFS_COMPONENTS="context device pathcomp service slice webui" export TFS_COMPONENTS="context device pathcomp service slice compute webui load_generator" # Uncoment to activate Monitoring export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" # Uncomment to activate Monitoring #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" # Uncoment to activate Automation and Policy Manager # Uncomment to activate Automation and Policy Manager #export TFS_COMPONENTS="${TFS_COMPONENTS} automation policy" # Uncoment to activate Optical CyberSecurity # Uncomment to activate Optical CyberSecurity #export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" # Uncoment to activate L3 CyberSecurity # Uncomment to activate L3 CyberSecurity #export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" # Set the tag you want to use for your images. Loading @@ -42,10 +41,12 @@ export TFS_IMAGE_TAG="dev" export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment #export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml manifests/servicemonitors.yaml" export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" # Uncoment when deploying Optical CyberSecurity # Uncomment to monitor performance of components export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" # Uncomment when deploying Optical CyberSecurity #export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" # Set the new Grafana admin password Loading src/service/service/service_handlers/l2nm_emulated/ConfigRules.py +9 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,12 @@ def setup_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode, endpoint_acls : List [Tuple] ) -> List[Dict]: if service_settings is None: return [] if endpoint_settings is None: return [] json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 Loading Loading @@ -80,6 +86,9 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: if service_settings is None: return [] if endpoint_settings is None: return [] #json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value Loading src/webui/service/device/forms.py +4 −2 Original line number Diff line number Diff line Loading @@ -18,10 +18,10 @@ from wtforms.validators import DataRequired, Length, NumberRange, ValidationErro from common.proto.context_pb2 import DeviceOperationalStatusEnum class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_type = SelectField('Type') operational_status = SelectField('Operational Status', coerce=int, validators=[NumberRange(min=0)]) device_drivers_undefined = BooleanField('UNDEFINED / EMULATED') device_drivers_openconfig = BooleanField('OPENCONFIG') device_drivers_transport_api = BooleanField('TRANSPORT_API') Loading @@ -31,9 +31,11 @@ class AddDeviceForm(FlaskForm): device_drivers_xr = BooleanField('XR') device_drivers_ietf_l2vpn = BooleanField('IETF L2VPN') device_drivers_gnmi_openconfig = BooleanField('GNMI OPENCONFIG') device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)]) device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)]) device_config_settings = TextAreaField('connect/settings',default='{}',validators=[DataRequired(), Length(min=2)]) submit = SubmitField('Add') def validate_operational_status(form, field): Loading src/webui/service/service/routes.py +139 −133 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ def home(): ste=ServiceTypeEnum, sse=ServiceStatusEnum, active_drivers=active_drivers) @service.route('add', methods=['GET', 'POST']) def add(): flash('Add service route called', 'danger') raise NotImplementedError() #return render_template('service/home.html') def get_hub_module_name(dev: Device) -> Optional[str]: for cr in dev.device_config.config_rules: if cr.action == ConfigActionEnum.CONFIGACTION_SET and cr.custom and cr.custom.resource_key == "_connect/settings": Loading @@ -103,139 +109,139 @@ def get_hub_module_name(dev: Device) -> Optional[str]: pass return None #@service.route('add-xr', methods=['GET', 'POST']) #def add_xr(): # ### FIXME: copypaste # if 'context_uuid' not in session or 'topology_uuid' not in session: # flash("Please select a context!", "warning") # return redirect(url_for("main.home")) # # context_uuid = session['context_uuid'] # topology_uuid = session['topology_uuid'] # # context_client.connect() # grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) # if grpc_topology is None: # flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') # return redirect(url_for("main.home")) # else: # topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} # grpc_devices= context_client.ListDevices(Empty()) # devices = [ # device for device in grpc_devices.devices # if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers # ] # devices.sort(key=lambda dev: dev.name) # # hub_interfaces_by_device = defaultdict(list) # leaf_interfaces_by_device = defaultdict(list) # constellation_name_to_uuid = {} # dev_ep_to_uuid = {} # ep_uuid_to_name = {} # for d in devices: # constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid # hm_name = get_hub_module_name(d) # if hm_name is not None: # hm_if_prefix= hm_name + "|" # for ep in d.device_endpoints: # dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid # if ep.name.startswith(hm_if_prefix): # hub_interfaces_by_device[d.name].append(ep.name) # else: # leaf_interfaces_by_device[d.name].append(ep.name) # ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name) # hub_interfaces_by_device[d.name].sort() # leaf_interfaces_by_device[d.name].sort() # # # Find out what endpoints are already used so that they can be disabled # # in the create screen # context_obj = get_context(context_client, context_uuid, rw_copy=False) # if context_obj is None: # flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') # return redirect(request.url) # # services = context_client.ListServices(context_obj.context_id) # ep_used_by={} # for service in services.services: # if service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: # for ep in service.service_endpoint_ids: # ep_uuid = ep.endpoint_uuid.uuid # if ep_uuid in ep_uuid_to_name: # dev_name, ep_name = ep_uuid_to_name[ep_uuid] # ep_used_by[f"{ep_name}@{dev_name}"] = service.name # # context_client.close() # # if request.method != 'POST': # return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by) # else: # service_name = request.form["service_name"] # if service_name == "": # flash(f"Service name must be specified", 'danger') # # constellation = request.form["constellation"] # constellation_uuid = constellation_name_to_uuid.get(constellation, None) # if constellation_uuid is None: # flash(f"Invalid constellation \"{constellation}\"", 'danger') # # hub_if = request.form["hubif"] # hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None) # if hub_if_uuid is None: # flash(f"Invalid hub interface \"{hub_if}\"", 'danger') # # leaf_if = request.form["leafif"] # leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None) # if leaf_if_uuid is None: # flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger') # # if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None: # return redirect(request.url) # # # json_context_uuid=json_context_id(context_uuid) # sr = { # "name": service_name, # "service_id": { # "context_id": {"context_uuid": {"uuid": context_uuid}}, # "service_uuid": {"uuid": service_name} # }, # 'service_type' : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, # "service_endpoint_ids": [ # {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}, # {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)} # ], # 'service_status' : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED}, # 'service_constraints' : [], # } # # json_tapi_settings = { # 'capacity_value' : 50.0, # 'capacity_unit' : 'GHz', # 'layer_proto_name': 'PHOTONIC_MEDIA', # 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', # 'direction' : 'UNIDIRECTIONAL', # } # config_rule = json_config_rule_set('/settings', json_tapi_settings) # # with connected_client(service_client) as sc: # endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], [] # try: # create_response = sc.CreateService(Service(**sr)) # except Exception as e: # flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger') # return redirect(request.url) # # sr['service_endpoint_ids'] = endpoints # sr['service_config'] = {'config_rules': [config_rule]} # # try: # update_response = sc.UpdateService(Service(**sr)) # flash(f'Created service {update_response.service_uuid.uuid}', 'success') # except Exception as e: # flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger') # return redirect(request.url) # # return redirect(url_for('service.home')) @service.route('add-xr', methods=['GET', 'POST']) def add_xr(): ### FIXME: copypaste if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) context_uuid = session['context_uuid'] topology_uuid = session['topology_uuid'] context_client.connect() grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') return redirect(url_for("main.home")) else: topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} grpc_devices= context_client.ListDevices(Empty()) devices = [ device for device in grpc_devices.devices if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers ] devices.sort(key=lambda dev: dev.name) hub_interfaces_by_device = defaultdict(list) leaf_interfaces_by_device = defaultdict(list) constellation_name_to_uuid = {} dev_ep_to_uuid = {} ep_uuid_to_name = {} for d in devices: constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid hm_name = get_hub_module_name(d) if hm_name is not None: hm_if_prefix= hm_name + "|" for ep in d.device_endpoints: dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid if ep.name.startswith(hm_if_prefix): hub_interfaces_by_device[d.name].append(ep.name) else: leaf_interfaces_by_device[d.name].append(ep.name) ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name) hub_interfaces_by_device[d.name].sort() leaf_interfaces_by_device[d.name].sort() # Find out what endpoints are already used so that they can be disabled # in the create screen context_obj = get_context(context_client, context_uuid, rw_copy=False) if context_obj is None: flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') return redirect(request.url) services = context_client.ListServices(context_obj.context_id) ep_used_by={} for service in services.services: if service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: for ep in service.service_endpoint_ids: ep_uuid = ep.endpoint_uuid.uuid if ep_uuid in ep_uuid_to_name: dev_name, ep_name = ep_uuid_to_name[ep_uuid] ep_used_by[f"{ep_name}@{dev_name}"] = service.name context_client.close() if request.method != 'POST': return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by) else: service_name = request.form["service_name"] if service_name == "": flash(f"Service name must be specified", 'danger') constellation = request.form["constellation"] constellation_uuid = constellation_name_to_uuid.get(constellation, None) if constellation_uuid is None: flash(f"Invalid constellation \"{constellation}\"", 'danger') hub_if = request.form["hubif"] hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None) if hub_if_uuid is None: flash(f"Invalid hub interface \"{hub_if}\"", 'danger') leaf_if = request.form["leafif"] leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None) if leaf_if_uuid is None: flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger') if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None: return redirect(request.url) json_context_uuid=json_context_id(context_uuid) sr = { "name": service_name, "service_id": { "context_id": {"context_uuid": {"uuid": context_uuid}}, "service_uuid": {"uuid": service_name} }, 'service_type' : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, "service_endpoint_ids": [ {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}, {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)} ], 'service_status' : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED}, 'service_constraints' : [], } json_tapi_settings = { 'capacity_value' : 50.0, 'capacity_unit' : 'GHz', 'layer_proto_name': 'PHOTONIC_MEDIA', 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', 'direction' : 'UNIDIRECTIONAL', } config_rule = json_config_rule_set('/settings', json_tapi_settings) with connected_client(service_client) as sc: endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], [] try: create_response = sc.CreateService(Service(**sr)) except Exception as e: flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger') return redirect(request.url) sr['service_endpoint_ids'] = endpoints sr['service_config'] = {'config_rules': [config_rule]} try: update_response = sc.UpdateService(Service(**sr)) flash(f'Created service {update_response.service_uuid.uuid}', 'success') except Exception as e: flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger') return redirect(request.url) return redirect(url_for('service.home')) @service.get('<path:service_uuid>/detail') def detail(service_uuid: str): Loading Loading
my_deploy.sh +10 −9 Original line number Diff line number Diff line Loading @@ -20,19 +20,18 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. #export TFS_COMPONENTS="context device pathcomp service slice compute webui load_generator" export TFS_COMPONENTS="context device pathcomp service slice webui" export TFS_COMPONENTS="context device pathcomp service slice compute webui load_generator" # Uncoment to activate Monitoring export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" # Uncomment to activate Monitoring #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" # Uncoment to activate Automation and Policy Manager # Uncomment to activate Automation and Policy Manager #export TFS_COMPONENTS="${TFS_COMPONENTS} automation policy" # Uncoment to activate Optical CyberSecurity # Uncomment to activate Optical CyberSecurity #export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" # Uncoment to activate L3 CyberSecurity # Uncomment to activate L3 CyberSecurity #export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" # Set the tag you want to use for your images. Loading @@ -42,10 +41,12 @@ export TFS_IMAGE_TAG="dev" export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment #export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml manifests/servicemonitors.yaml" export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" # Uncoment when deploying Optical CyberSecurity # Uncomment to monitor performance of components export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" # Uncomment when deploying Optical CyberSecurity #export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" # Set the new Grafana admin password Loading
src/service/service/service_handlers/l2nm_emulated/ConfigRules.py +9 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,12 @@ def setup_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode, endpoint_acls : List [Tuple] ) -> List[Dict]: if service_settings is None: return [] if endpoint_settings is None: return [] json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 Loading Loading @@ -80,6 +86,9 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: if service_settings is None: return [] if endpoint_settings is None: return [] #json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value Loading
src/webui/service/device/forms.py +4 −2 Original line number Diff line number Diff line Loading @@ -18,10 +18,10 @@ from wtforms.validators import DataRequired, Length, NumberRange, ValidationErro from common.proto.context_pb2 import DeviceOperationalStatusEnum class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) device_type = SelectField('Type') operational_status = SelectField('Operational Status', coerce=int, validators=[NumberRange(min=0)]) device_drivers_undefined = BooleanField('UNDEFINED / EMULATED') device_drivers_openconfig = BooleanField('OPENCONFIG') device_drivers_transport_api = BooleanField('TRANSPORT_API') Loading @@ -31,9 +31,11 @@ class AddDeviceForm(FlaskForm): device_drivers_xr = BooleanField('XR') device_drivers_ietf_l2vpn = BooleanField('IETF L2VPN') device_drivers_gnmi_openconfig = BooleanField('GNMI OPENCONFIG') device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)]) device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)]) device_config_settings = TextAreaField('connect/settings',default='{}',validators=[DataRequired(), Length(min=2)]) submit = SubmitField('Add') def validate_operational_status(form, field): Loading
src/webui/service/service/routes.py +139 −133 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ def home(): ste=ServiceTypeEnum, sse=ServiceStatusEnum, active_drivers=active_drivers) @service.route('add', methods=['GET', 'POST']) def add(): flash('Add service route called', 'danger') raise NotImplementedError() #return render_template('service/home.html') def get_hub_module_name(dev: Device) -> Optional[str]: for cr in dev.device_config.config_rules: if cr.action == ConfigActionEnum.CONFIGACTION_SET and cr.custom and cr.custom.resource_key == "_connect/settings": Loading @@ -103,139 +109,139 @@ def get_hub_module_name(dev: Device) -> Optional[str]: pass return None #@service.route('add-xr', methods=['GET', 'POST']) #def add_xr(): # ### FIXME: copypaste # if 'context_uuid' not in session or 'topology_uuid' not in session: # flash("Please select a context!", "warning") # return redirect(url_for("main.home")) # # context_uuid = session['context_uuid'] # topology_uuid = session['topology_uuid'] # # context_client.connect() # grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) # if grpc_topology is None: # flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') # return redirect(url_for("main.home")) # else: # topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} # grpc_devices= context_client.ListDevices(Empty()) # devices = [ # device for device in grpc_devices.devices # if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers # ] # devices.sort(key=lambda dev: dev.name) # # hub_interfaces_by_device = defaultdict(list) # leaf_interfaces_by_device = defaultdict(list) # constellation_name_to_uuid = {} # dev_ep_to_uuid = {} # ep_uuid_to_name = {} # for d in devices: # constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid # hm_name = get_hub_module_name(d) # if hm_name is not None: # hm_if_prefix= hm_name + "|" # for ep in d.device_endpoints: # dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid # if ep.name.startswith(hm_if_prefix): # hub_interfaces_by_device[d.name].append(ep.name) # else: # leaf_interfaces_by_device[d.name].append(ep.name) # ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name) # hub_interfaces_by_device[d.name].sort() # leaf_interfaces_by_device[d.name].sort() # # # Find out what endpoints are already used so that they can be disabled # # in the create screen # context_obj = get_context(context_client, context_uuid, rw_copy=False) # if context_obj is None: # flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') # return redirect(request.url) # # services = context_client.ListServices(context_obj.context_id) # ep_used_by={} # for service in services.services: # if service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: # for ep in service.service_endpoint_ids: # ep_uuid = ep.endpoint_uuid.uuid # if ep_uuid in ep_uuid_to_name: # dev_name, ep_name = ep_uuid_to_name[ep_uuid] # ep_used_by[f"{ep_name}@{dev_name}"] = service.name # # context_client.close() # # if request.method != 'POST': # return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by) # else: # service_name = request.form["service_name"] # if service_name == "": # flash(f"Service name must be specified", 'danger') # # constellation = request.form["constellation"] # constellation_uuid = constellation_name_to_uuid.get(constellation, None) # if constellation_uuid is None: # flash(f"Invalid constellation \"{constellation}\"", 'danger') # # hub_if = request.form["hubif"] # hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None) # if hub_if_uuid is None: # flash(f"Invalid hub interface \"{hub_if}\"", 'danger') # # leaf_if = request.form["leafif"] # leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None) # if leaf_if_uuid is None: # flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger') # # if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None: # return redirect(request.url) # # # json_context_uuid=json_context_id(context_uuid) # sr = { # "name": service_name, # "service_id": { # "context_id": {"context_uuid": {"uuid": context_uuid}}, # "service_uuid": {"uuid": service_name} # }, # 'service_type' : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, # "service_endpoint_ids": [ # {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}, # {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)} # ], # 'service_status' : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED}, # 'service_constraints' : [], # } # # json_tapi_settings = { # 'capacity_value' : 50.0, # 'capacity_unit' : 'GHz', # 'layer_proto_name': 'PHOTONIC_MEDIA', # 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', # 'direction' : 'UNIDIRECTIONAL', # } # config_rule = json_config_rule_set('/settings', json_tapi_settings) # # with connected_client(service_client) as sc: # endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], [] # try: # create_response = sc.CreateService(Service(**sr)) # except Exception as e: # flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger') # return redirect(request.url) # # sr['service_endpoint_ids'] = endpoints # sr['service_config'] = {'config_rules': [config_rule]} # # try: # update_response = sc.UpdateService(Service(**sr)) # flash(f'Created service {update_response.service_uuid.uuid}', 'success') # except Exception as e: # flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger') # return redirect(request.url) # # return redirect(url_for('service.home')) @service.route('add-xr', methods=['GET', 'POST']) def add_xr(): ### FIXME: copypaste if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) context_uuid = session['context_uuid'] topology_uuid = session['topology_uuid'] context_client.connect() grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False) if grpc_topology is None: flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger') return redirect(url_for("main.home")) else: topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids} grpc_devices= context_client.ListDevices(Empty()) devices = [ device for device in grpc_devices.devices if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers ] devices.sort(key=lambda dev: dev.name) hub_interfaces_by_device = defaultdict(list) leaf_interfaces_by_device = defaultdict(list) constellation_name_to_uuid = {} dev_ep_to_uuid = {} ep_uuid_to_name = {} for d in devices: constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid hm_name = get_hub_module_name(d) if hm_name is not None: hm_if_prefix= hm_name + "|" for ep in d.device_endpoints: dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid if ep.name.startswith(hm_if_prefix): hub_interfaces_by_device[d.name].append(ep.name) else: leaf_interfaces_by_device[d.name].append(ep.name) ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name) hub_interfaces_by_device[d.name].sort() leaf_interfaces_by_device[d.name].sort() # Find out what endpoints are already used so that they can be disabled # in the create screen context_obj = get_context(context_client, context_uuid, rw_copy=False) if context_obj is None: flash('Context({:s}) not found'.format(str(context_uuid)), 'danger') return redirect(request.url) services = context_client.ListServices(context_obj.context_id) ep_used_by={} for service in services.services: if service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: for ep in service.service_endpoint_ids: ep_uuid = ep.endpoint_uuid.uuid if ep_uuid in ep_uuid_to_name: dev_name, ep_name = ep_uuid_to_name[ep_uuid] ep_used_by[f"{ep_name}@{dev_name}"] = service.name context_client.close() if request.method != 'POST': return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by) else: service_name = request.form["service_name"] if service_name == "": flash(f"Service name must be specified", 'danger') constellation = request.form["constellation"] constellation_uuid = constellation_name_to_uuid.get(constellation, None) if constellation_uuid is None: flash(f"Invalid constellation \"{constellation}\"", 'danger') hub_if = request.form["hubif"] hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None) if hub_if_uuid is None: flash(f"Invalid hub interface \"{hub_if}\"", 'danger') leaf_if = request.form["leafif"] leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None) if leaf_if_uuid is None: flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger') if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None: return redirect(request.url) json_context_uuid=json_context_id(context_uuid) sr = { "name": service_name, "service_id": { "context_id": {"context_uuid": {"uuid": context_uuid}}, "service_uuid": {"uuid": service_name} }, 'service_type' : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, "service_endpoint_ids": [ {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}, {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)} ], 'service_status' : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED}, 'service_constraints' : [], } json_tapi_settings = { 'capacity_value' : 50.0, 'capacity_unit' : 'GHz', 'layer_proto_name': 'PHOTONIC_MEDIA', 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', 'direction' : 'UNIDIRECTIONAL', } config_rule = json_config_rule_set('/settings', json_tapi_settings) with connected_client(service_client) as sc: endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], [] try: create_response = sc.CreateService(Service(**sr)) except Exception as e: flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger') return redirect(request.url) sr['service_endpoint_ids'] = endpoints sr['service_config'] = {'config_rules': [config_rule]} try: update_response = sc.UpdateService(Service(**sr)) flash(f'Created service {update_response.service_uuid.uuid}', 'success') except Exception as e: flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger') return redirect(request.url) return redirect(url_for('service.home')) @service.get('<path:service_uuid>/detail') def detail(service_uuid: str): Loading