diff --git a/src/nbi/tests/data/agg-net-descriptor.json b/src/nbi/tests/data/agg-net-topology.json similarity index 70% rename from src/nbi/tests/data/agg-net-descriptor.json rename to src/nbi/tests/data/agg-net-topology.json index bde4db62844084c0674312a60d7c1cbf8357de52..bb27d6f258fb317662a30ab746bbe0d0ffff331f 100644 --- a/src/nbi/tests/data/agg-net-descriptor.json +++ b/src/nbi/tests/data/agg-net-topology.json @@ -41,7 +41,7 @@ "action": 1, "custom": { "resource_key": "_connect/address", - "resource_value": "10.10.10.10" + "resource_value": "10.0.58.29" } }, { @@ -56,7 +56,13 @@ "custom": { "resource_key": "_connect/settings", "resource_value": { - "endpoints": [], + "endpoints": [ + { + "uuid": "mgmt", + "name": "mgmt", + "type": "mgmt" + } + ], "scheme": "http", "username": "admin", "password": "admin", @@ -85,7 +91,7 @@ }, "device_operational_status": 1, "device_drivers": [ - 0 + 13 ], "device_config": { "config_rules": [ @@ -118,21 +124,9 @@ "uuid": "200", "name": "200", "type": "optical", - "ce-ip": "128.32.33.2", "address_ip": "128.32.33.254", "address_prefix": "24", - "site_location": "access", - "mtu": "1500", - "ipv4_lan_prefixes": [ - { - "lan": "128.32.10.0/24", - "lan_tag": "10" - }, - { - "lan": "128.32.20.0/24", - "lan_tag": "20" - } - ] + "site_location": "access" }, { "uuid": "500", @@ -166,7 +160,7 @@ }, "device_operational_status": 1, "device_drivers": [ - 0 + 13 ], "device_config": { "config_rules": [ @@ -227,7 +221,7 @@ }, "device_operational_status": 1, "device_drivers": [ - 0 + 13 ], "device_config": { "config_rules": [ @@ -288,7 +282,7 @@ }, "device_operational_status": 1, "device_drivers": [ - 0 + 13 ], "device_config": { "config_rules": [ @@ -321,17 +315,9 @@ "uuid": "200", "name": "200", "type": "optical", - "ce-ip": "172.10.33.2", "address_ip": "172.10.33.254", "address_prefix": "24", - "site_location": "cloud", - "mtu": "1500", - "ipv4_lan_prefixes": [ - { - "lan": "172.1.101.0/24", - "lan_tag": "101" - } - ] + "site_location": "cloud" }, { "uuid": "500", @@ -349,9 +335,185 @@ } ] } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.204.220" + } + }, + "device_type": "emu-datacenter", + "device_drivers": [ + 0 + ], + "device_endpoints": [], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "127.0.0.1" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "0" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "endpoints": [ + { + "sample_types": [], + "type": "optical", + "uuid": "500" + }, + { + "sample_types": [], + "type": "optical", + "uuid": "200" + }, + { + "sample_types": [], + "type": "optical", + "uuid": "201" + } + ] + } + } + } + ] + } } ], "links": [ + { + "link_id": { + "link_uuid": { + "uuid": "ip-net-controller/mgmt==172.16.182.25/mgmt" + } + }, + "name": "ip-net-controller/mgmt==172.16.182.25/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.182.25" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, + { + "link_id": { + "link_uuid": { + "uuid": "ip-net-controller/mgmt==172.16.185.31/mgmt" + } + }, + "name": "ip-net-controller/mgmt==172.16.185.31/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.31" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, + { + "link_id": { + "link_uuid": { + "uuid": "ip-net-controller/mgmt==172.16.185.33/mgmt" + } + }, + "name": "ip-net-controller/mgmt==172.16.185.33/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.33" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, + { + "link_id": { + "link_uuid": { + "uuid": "ip-net-controller/mgmt==172.16.185.32/mgmt" + } + }, + "name": "ip-net-controller/mgmt==172.16.185.32/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.32" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, { "link_id": { "link_uuid": { @@ -623,6 +785,74 @@ } } ] + }, + { + "link_id": { + "link_uuid": { + "uuid": "172.16.185.32-200" + } + }, + "name": "172.16.185.32-200", + "attributes": { + "total_capacity_gbps": 10, + "used_capacity_gbps": 0 + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.32" + } + }, + "endpoint_uuid": { + "uuid": "200" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.204.220" + } + }, + "endpoint_uuid": { + "uuid": "500" + } + } + ] + }, + { + "link_id": { + "link_uuid": { + "uuid": "172.16.204.220-500" + } + }, + "name": "172.16.204.220-500", + "attributes": { + "total_capacity_gbps": 10, + "used_capacity_gbps": 0 + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "172.16.204.220" + } + }, + "endpoint_uuid": { + "uuid": "500" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "172.16.185.32" + } + }, + "endpoint_uuid": { + "uuid": "200" + } + } + ] } ] -} \ No newline at end of file +} diff --git a/src/nbi/tests/data/camara-e2e-topology.json b/src/nbi/tests/data/camara-e2e-topology.json index 0b314e104ef4ae31cfdb7be11f9e3912287cf5ae..02a21e6918c5d8fb49016d7babe75a51bf751979 100644 --- a/src/nbi/tests/data/camara-e2e-topology.json +++ b/src/nbi/tests/data/camara-e2e-topology.json @@ -23,6 +23,59 @@ } ], "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-transport-controller" + } + }, + "name": "ip-transport-controller", + "device_type": "ietf-slice", + "device_operational_status": 1, + "device_drivers": [ + 14 + ], + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.58.9" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "80" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "endpoints": [ + { + "uuid": "mgmt", + "name": "mgmt", + "type": "mgmt" + } + ], + "scheme": "http", + "username": "admin", + "password": "admin", + "base_url": "/restconf/v2/data", + "timeout": 120, + "verify": false + } + } + } + ] + }, + "device_endpoints": [] + }, { "device_id": { "device_uuid": { @@ -94,7 +147,7 @@ "action": 1, "custom": { "resource_key": "_connect/address", - "resource_value": "10.10.10.10" + "resource_value": "1.1.1.1" } }, { @@ -139,7 +192,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -210,7 +263,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -272,7 +325,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -334,7 +387,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -748,6 +801,36 @@ } ], "links": [ + { + "link_id": { + "link_uuid": { + "uuid": "agg-net-controller/mgmt==ip-transport-controller/mgmt" + } + }, + "name": "agg-net-controller/mgmt==ip-transport-controller/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "agg-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "ip-transport-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, { "link_id": { "link_uuid": { @@ -841,15 +924,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.185.33/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.33/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.185.33/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.33/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -871,15 +954,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.185.31/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.31/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.185.31/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.31/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -901,15 +984,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.182.25/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.32/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.182.25/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.32/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -919,7 +1002,7 @@ { "device_id": { "device_uuid": { - "uuid": "172.16.182.25" + "uuid": "172.16.185.32" } }, "endpoint_uuid": { @@ -931,15 +1014,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.182.25/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.182.25/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.182.25/mgmt", + "name": "ip-transport-controller/mgmt==172.16.182.25/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { diff --git a/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json b/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json index 7ae2da79c0fe54f883c4c08b98fa0d05c7e74ee0..b2a8617e2c3e211a3e0ef1facb05b40788aa82cf 100644 --- a/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json +++ b/src/tests/ofc25-camara-e2e-controller/data/camara-e2e-topology.json @@ -23,6 +23,59 @@ } ], "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "ip-transport-controller" + } + }, + "name": "ip-transport-controller", + "device_type": "ietf-slice", + "device_operational_status": 1, + "device_drivers": [ + 14 + ], + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "AGG_NET_IP" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "AGG_NET_PORT" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "endpoints": [ + { + "uuid": "mgmt", + "name": "mgmt", + "type": "mgmt" + } + ], + "scheme": "http", + "username": "admin", + "password": "admin", + "base_url": "/restconf/v2/data", + "timeout": 120, + "verify": false + } + } + } + ] + }, + "device_endpoints": [] + }, { "device_id": { "device_uuid": { @@ -139,7 +192,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -210,7 +263,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -272,7 +325,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -334,7 +387,7 @@ "device_type": "emu-packet-router", "controller_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "device_operational_status": 1, @@ -748,6 +801,36 @@ } ], "links": [ + { + "link_id": { + "link_uuid": { + "uuid": "agg-net-controller/mgmt==ip-transport-controller/mgmt" + } + }, + "name": "agg-net-controller/mgmt==ip-transport-controller/mgmt", + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "agg-net-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "ip-transport-controller" + } + }, + "endpoint_uuid": { + "uuid": "mgmt" + } + } + ] + }, { "link_id": { "link_uuid": { @@ -841,15 +924,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.185.33/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.33/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.185.33/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.33/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -871,15 +954,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.185.31/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.31/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.185.31/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.31/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -901,15 +984,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.182.25/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.185.32/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.182.25/mgmt", + "name": "ip-transport-controller/mgmt==172.16.185.32/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { @@ -919,7 +1002,7 @@ { "device_id": { "device_uuid": { - "uuid": "172.16.182.25" + "uuid": "172.16.185.32" } }, "endpoint_uuid": { @@ -931,15 +1014,15 @@ { "link_id": { "link_uuid": { - "uuid": "agg-net-controller/mgmt==172.16.182.25/mgmt" + "uuid": "ip-transport-controller/mgmt==172.16.182.25/mgmt" } }, - "name": "agg-net-controller/mgmt==172.16.182.25/mgmt", + "name": "ip-transport-controller/mgmt==172.16.182.25/mgmt", "link_endpoint_ids": [ { "device_id": { "device_uuid": { - "uuid": "agg-net-controller" + "uuid": "ip-transport-controller" } }, "endpoint_uuid": { diff --git a/src/webui/service/slice/routes.py b/src/webui/service/slice/routes.py index 922f8af96dc916f0ca5658e120cdf3dfa4ec9b21..f56c50f46d8c9df083a943a91704e7d16352e5a2 100644 --- a/src/webui/service/slice/routes.py +++ b/src/webui/service/slice/routes.py @@ -12,12 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json +from typing import Dict, Optional, Tuple import grpc from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for -from common.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum +from common.method_wrappers.ServiceExceptions import InvalidArgumentsException +from common.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum, EndPointId, SliceConfig, ConfigRule from common.tools.context_queries.Context import get_context from common.tools.context_queries.EndPoint import get_endpoint_names -from common.tools.context_queries.Slice import get_slice_by_uuid +from common.tools.context_queries.Slice import get_slice_by_uuid, get_uuid_from_string +from common.Constants import DEFAULT_CONTEXT_NAME from context.client.ContextClient import ContextClient from slice.client.SliceClient import SliceClient @@ -26,6 +30,94 @@ slice = Blueprint('slice', __name__, url_prefix='/slice') context_client = ContextClient() slice_client = SliceClient() + +RUNNING_RESOURCE_KEY = "running_ietf_slice" +CANDIDATE_RESOURCE_KEY = "candidate_ietf_slice" + + +class ConfigRuleNotFoundError(Exception): + ... + +def get_custom_config_rule( + slice_config: SliceConfig, resource_key: str +) -> Optional[ConfigRule]: + """ + Retrieve the custom config rule with the given resource_key from a ServiceConfig. + """ + for cr in slice_config.config_rules: + if ( + cr.WhichOneof("config_rule") == "custom" + and cr.custom.resource_key == resource_key + ): + return cr + return None + + +def get_ietf_data_from_config(slice_request: Slice, resource_key: str) -> Dict: + """ + Retrieve the IETF data (as a Python dict) from a slice's config rule for the specified resource_key. + Raises an exception if not found. + """ + config_rule = get_custom_config_rule(slice_request.slice_config, resource_key) + if not config_rule: + raise ConfigRuleNotFoundError(f"IETF data not found for resource_key: {resource_key}") + return json.loads(config_rule.custom.resource_value) + + +def endpoint_get_uuid( + endpoint_id : EndPointId, endpoint_name : str = '', allow_random : bool = False +) -> Tuple[str, str, str]: + device_uuid = endpoint_id.device_id.device_uuid.uuid + topology_uuid = endpoint_id.topology_id.topology_uuid.uuid + raw_endpoint_uuid = endpoint_id.endpoint_uuid.uuid + + if len(raw_endpoint_uuid) > 0: + prefix_for_name = '{:s}/{:s}'.format(topology_uuid, device_uuid) + return topology_uuid, device_uuid, get_uuid_from_string(raw_endpoint_uuid, prefix_for_name=prefix_for_name) + if len(endpoint_name) > 0: + prefix_for_name = '{:s}/{:s}'.format(topology_uuid, device_uuid) + return topology_uuid, device_uuid, get_uuid_from_string(endpoint_name, prefix_for_name=prefix_for_name) + + raise InvalidArgumentsException([ + ('endpoint_id.endpoint_uuid.uuid', raw_endpoint_uuid), + ('name', endpoint_name), + ], extra_details=['At least one is required to produce a EndPoint UUID']) + +def get_slice_endpoints(slice_obj: Slice) -> list[EndPointId]: + ''' + Get the list of endpoint ids for a slice. + If the slice has a `running_ietf_slice` config rule, return the list of endpoint ids from the config rule, + otherwise return the slice's list of endpoint ids. + ''' + try: + first_slice_endpoint_id = slice_obj.slice_endpoint_ids[0] + topology_uuid = first_slice_endpoint_id.topology_id.topology_uuid.uuid + context_uuid = slice_obj.slice_id.context_id.context_uuid.uuid + running_ietf_data = get_ietf_data_from_config(slice_obj, RUNNING_RESOURCE_KEY) + slice_service = running_ietf_data["network-slice-services"]["slice-service"][0] + slice_sdps = slice_service["sdps"]["sdp"] + list_endpoint_ids = [] + for sdp in slice_sdps: + endpoint = EndPointId() + endpoint.topology_id.context_id.context_uuid.uuid = context_uuid + endpoint.topology_id.topology_uuid.uuid = topology_uuid + device_uuid = get_uuid_from_string(sdp["node-id"]) + endpoint.device_id.device_uuid.uuid = device_uuid + attachment_circuits = sdp["attachment-circuits"]["attachment-circuit"] + endpoint_name = attachment_circuits[0]["ac-tp-id"] + endpoint.endpoint_uuid.uuid = endpoint_name + _, _, endpoint_uuid = endpoint_get_uuid(endpoint) + endpoint.endpoint_uuid.uuid = endpoint_uuid + list_endpoint_ids.append(endpoint) + del slice_obj.slice_endpoint_ids[:] + slice_obj.slice_endpoint_ids.extend(list_endpoint_ids) + + except ConfigRuleNotFoundError: + # The slice does not have `running_ietf_slice` config rule, return slice's list of endpoint ids + list_endpoint_ids = slice_obj.slice_endpoint_ids + + return list_endpoint_ids + @slice.get('/') def home(): if 'context_uuid' not in session or 'topology_uuid' not in session: @@ -50,7 +142,8 @@ def home(): else: endpoint_ids = list() for slice_ in slices: - endpoint_ids.extend(slice_.slice_endpoint_ids) + slice_endpoint_ids = get_slice_endpoints(slice_) + endpoint_ids.extend(slice_endpoint_ids) device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) context_client.close() @@ -81,7 +174,8 @@ def detail(slice_uuid: str): flash('Context({:s})/Slice({:s}) not found'.format(str(context_uuid), str(slice_uuid)), 'danger') slice_obj = Slice() else: - device_names, endpoints_data = get_endpoint_names(context_client, slice_obj.slice_endpoint_ids) + slice_endpoint_ids = get_slice_endpoints(slice_obj) + device_names, endpoints_data = get_endpoint_names(context_client, slice_endpoint_ids) context_client.close() @@ -111,5 +205,5 @@ def delete(slice_uuid: str): flash('Slice "{:s}" deleted successfully!'.format(slice_uuid), 'success') except Exception as e: flash('Problem deleting slice "{:s}": {:s}'.format(slice_uuid, str(e.details())), 'danger') - current_app.logger.exception(e) + current_app.logger.exception(e) return redirect(url_for('slice.home')) diff --git a/src/webui/service/static/topology_icons/ietf-slice.png b/src/webui/service/static/topology_icons/ietf-slice.png new file mode 100644 index 0000000000000000000000000000000000000000..ed2232e8223a39eb0d829e0e50975a697b0660fc Binary files /dev/null and b/src/webui/service/static/topology_icons/ietf-slice.png differ diff --git a/src/webui/service/static/topology_icons/nce.png b/src/webui/service/static/topology_icons/nce.png new file mode 100644 index 0000000000000000000000000000000000000000..0c9af8f37fbb7249fbe570a920e0bcd281582655 Binary files /dev/null and b/src/webui/service/static/topology_icons/nce.png differ