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