diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index 893f3464fabea2d1151c007a612e781d1f999093..21e5d49cb17400d3592cd742d9a470d85d3eccee 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -37,7 +37,7 @@ spec: ports: - containerPort: 10050 - containerPort: 9192 - - containerPort: 8761 + - containerPort: 8762 env: - name: LOG_LEVEL value: "INFO" @@ -49,6 +49,10 @@ spec: value: "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" - name: WS_E2E_PORT value: "8762" + - name: EXT_CONTROLLER1_ADD + value: "10.1.1.96" + - name: EXT_CONTROLLER1_PORT + value: "8003" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:10050"] @@ -81,5 +85,5 @@ spec: port: 9192 targetPort: 9192 - name: ws - port: 8761 - targetPort: 8761 + port: 8762 + targetPort: 8762 diff --git a/manifests/nbiservice.yaml b/manifests/nbiservice.yaml index 72cfde514341b0ef89b3b8eb91ab01b23a27c14b..ac9c9bec57d71ff010e79a8832a7d0e2e185a09a 100644 --- a/manifests/nbiservice.yaml +++ b/manifests/nbiservice.yaml @@ -38,14 +38,14 @@ spec: - containerPort: 8080 - containerPort: 9090 - containerPort: 9192 - - containerPort: 8762 + - containerPort: 8761 env: - name: LOG_LEVEL value: "INFO" - name: IETF_NETWORK_RENDERER value: "LIBYANG" - - name: WS_E2E_PORT - value: "8762" + - name: WS_IP_PORT + value: "8761" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:9090"] @@ -83,7 +83,7 @@ spec: protocol: TCP port: 9192 targetPort: 9192 - - name: ws + - name: websocket protocol: TCP - port: 8762 - targetPort: 8762 + port: 8761 + targetPort: 8761 diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index 1dd383d615bb167ae6de15ae03c404a50bdee942..bcfb47ee392d86b8a46d22e58f8efdd6e10da329 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -36,7 +36,7 @@ spec: - containerPort: 9192 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:3030"] diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index 6351f26e57d00e98ac5a011c5f22b5abf7066395..087e58b7673e752d208eaa82b30a697e4eb8d08c 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -300,7 +300,7 @@ class OCDriver(_Driver): self.__netconf_handler, self.__logger, resources, conditions, target='candidate', commit_per_rule=self.__netconf_handler.commit_per_rule ) - else: + else: results = edit_config( self.__netconf_handler, self.__logger, resources, conditions=conditions ) diff --git a/src/e2e_orchestrator/requirements.in b/src/e2e_orchestrator/requirements.in index 5732b1bf053301f73a37830e66eb211912d9e200..7ab2d5ded089fd55bffb8bbab0d154083729f976 100644 --- a/src/e2e_orchestrator/requirements.in +++ b/src/e2e_orchestrator/requirements.in @@ -14,3 +14,4 @@ networkx websockets==12.0 +requests==2.27.* diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index 4fc0ea3ba45a85bb3b1dccb18191dc1b4e380404..52b5a21f815739bc70a96c2acaed94a11f21cad6 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -13,6 +13,7 @@ # limitations under the License. import copy +import requests from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply from common.proto.context_pb2 import ( @@ -33,7 +34,7 @@ import networkx as nx from threading import Thread from websockets.sync.client import connect from websockets.sync.server import serve -from common.Constants import DEFAULT_CONTEXT_NAME +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME LOGGER = logging.getLogger(__name__) @@ -98,7 +99,6 @@ class SubscriptionServer(Thread): def _event_received(self, connection): - LOGGER.info("EVENT received!") for message in connection: message_json = json.loads(message) # LOGGER.info("message_json: {}".format(message_json)) @@ -142,7 +142,6 @@ class SubscriptionServer(Thread): connection.send(grpc_message_to_json_string(link)) # Link removal elif 'link_uuid' in message_json: - LOGGER.info('REMOVING VIRTUAL LINK') link_id = LinkId(**message_json) service_id = ServiceId() @@ -153,7 +152,6 @@ class SubscriptionServer(Thread): context_client.RemoveLink(link_id) # Topology received else: - LOGGER.info('TOPOLOGY') topology_details = TopologyDetails(**message_json) context = Context() @@ -181,10 +179,41 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): sub_server = SubscriptionServer() sub_server.start() LOGGER.debug("Servicer Created") - + self.retrieve_external_topologies() except Exception as ex: LOGGER.info("Exception!: {}".format(ex)) + def retrieve_external_topologies(self): + i = 1 + while True: + try: + LOGGER.info(f'Retrieving external controller #{i}') + ADD = str(get_setting(f'EXT_CONTROLLER{i}_ADD')) + PORT = str(get_setting(f'EXT_CONTROLLER{i}_PORT')) + except Exception as e: + break + try: + url = f'http://{ADD}:{PORT}/tfs-api/context/{DEFAULT_CONTEXT_NAME}/topology_details/{DEFAULT_TOPOLOGY_NAME}' + topo = requests.get(url).json() + except Exception as e: + LOGGER.info(f'Exception retrieven topology from external controler #{i}: {e}') + topology_details = TopologyDetails(**topo) + context = Context() + context.context_id.context_uuid.uuid = topology_details.topology_id.context_id.context_uuid.uuid + context_client.SetContext(context) + + topology = Topology() + topology.topology_id.context_id.CopyFrom(context.context_id) + topology.topology_id.topology_uuid.uuid = topology_details.topology_id.topology_uuid.uuid + context_client.SetTopology(topology) + + for device in topology_details.devices: + context_client.SetDevice(device) + + for link in topology_details.links: + context_client.SetLink(link) + + i+=1 @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) diff --git a/src/nbi/service/context_subscription/__init__.py b/src/nbi/service/context_subscription/__init__.py index d2ae85070eb5b5352db9690179b098cdb9781de0..e33728ece0d80e60cf5973363ce334c0db0b2e98 100644 --- a/src/nbi/service/context_subscription/__init__.py +++ b/src/nbi/service/context_subscription/__init__.py @@ -34,14 +34,14 @@ vnt_manager_client: VNTManagerClient = VNTManagerClient() context_client: ContextClient = ContextClient() ALL_HOSTS = "0.0.0.0" -WS_E2E_PORT = int(get_setting('WS_E2E_PORT', default='8762')) +WS_IP_PORT = int(get_setting('WS_IP_PORT', default='8761')) LOGGER = logging.getLogger(__name__) def register_context_subscription(): - with serve(subcript_to_vnt_manager, ALL_HOSTS, WS_E2E_PORT, logger=LOGGER) as server: - LOGGER.info("Running subscription server...: {}:{}".format(ALL_HOSTS, str(WS_E2E_PORT))) + with serve(subcript_to_vnt_manager, ALL_HOSTS, WS_IP_PORT, logger=LOGGER) as server: + LOGGER.info("Running subscription server...: {}:{}".format(ALL_HOSTS, str(WS_IP_PORT))) server.serve_forever() LOGGER.info("Exiting subscription server...") diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py index 28f94887a1aa9895a337baa40b3896e3d7e95dc1..58cf9aa014a959fa2bb694765041a368a44d4efc 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py @@ -177,6 +177,11 @@ class Topology(_Resource): def delete(self, context_uuid : str, topology_uuid : str): return format_grpc_to_json(self.context_client.RemoveTopology(grpc_topology_id(context_uuid, topology_uuid))) +class TopologyDetails(_Resource): + def get(self, context_uuid : str, topology_uuid : str): + return format_grpc_to_json(self.context_client.GetTopologyDetails(grpc_topology_id( + context_uuid, topology_uuid))) + class ServiceIds(_Resource): def get(self, context_uuid : str): return format_grpc_to_json(self.context_client.ListServiceIds(grpc_context_id(context_uuid))) diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/__init__.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/__init__.py index 41e8ff1ea634869e69258c20f81f7c3db9767eb5..984e0442ab229e54b18910b7622c8daa8886a044 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/__init__.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/__init__.py @@ -22,7 +22,7 @@ from .Resources import ( PolicyRule, PolicyRuleIds, PolicyRules, Service, ServiceIds, Services, Slice, SliceIds, Slices, - Topologies, Topology, TopologyIds + Topologies, Topology, TopologyIds, TopologyDetails ) URL_PREFIX = '/tfs-api' @@ -30,38 +30,39 @@ URL_PREFIX = '/tfs-api' # Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type. RESOURCES = [ # (endpoint_name, resource_class, resource_url) - ('api.context_ids', ContextIds, '/context_ids'), - ('api.contexts', Contexts, '/contexts'), - ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), - ('api.context', Context, '/context/<path:context_uuid>'), + ('api.context_ids', ContextIds, '/context_ids'), + ('api.contexts', Contexts, '/contexts'), + ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), + ('api.context', Context, '/context/<path:context_uuid>'), - ('api.topology_ids', TopologyIds, '/context/<path:context_uuid>/topology_ids'), - ('api.topologies', Topologies, '/context/<path:context_uuid>/topologies'), - ('api.topology', Topology, '/context/<path:context_uuid>/topology/<path:topology_uuid>'), + ('api.topology_ids', TopologyIds, '/context/<path:context_uuid>/topology_ids'), + ('api.topologies', Topologies, '/context/<path:context_uuid>/topologies'), + ('api.topology', Topology, '/context/<path:context_uuid>/topology/<path:topology_uuid>'), + ('api.topology_details', TopologyDetails, '/context/<path:context_uuid>/topology_details/<path:topology_uuid>'), - ('api.service_ids', ServiceIds, '/context/<path:context_uuid>/service_ids'), - ('api.services', Services, '/context/<path:context_uuid>/services'), - ('api.service', Service, '/context/<path:context_uuid>/service/<path:service_uuid>'), + ('api.service_ids', ServiceIds, '/context/<path:context_uuid>/service_ids'), + ('api.services', Services, '/context/<path:context_uuid>/services'), + ('api.service', Service, '/context/<path:context_uuid>/service/<path:service_uuid>'), - ('api.slice_ids', SliceIds, '/context/<path:context_uuid>/slice_ids'), - ('api.slices', Slices, '/context/<path:context_uuid>/slices'), - ('api.slice', Slice, '/context/<path:context_uuid>/slice/<path:slice_uuid>'), + ('api.slice_ids', SliceIds, '/context/<path:context_uuid>/slice_ids'), + ('api.slices', Slices, '/context/<path:context_uuid>/slices'), + ('api.slice', Slice, '/context/<path:context_uuid>/slice/<path:slice_uuid>'), - ('api.device_ids', DeviceIds, '/device_ids'), - ('api.devices', Devices, '/devices'), - ('api.device', Device, '/device/<path:device_uuid>'), + ('api.device_ids', DeviceIds, '/device_ids'), + ('api.devices', Devices, '/devices'), + ('api.device', Device, '/device/<path:device_uuid>'), - ('api.link_ids', LinkIds, '/link_ids'), - ('api.links', Links, '/links'), - ('api.link', Link, '/link/<path:link_uuid>'), + ('api.link_ids', LinkIds, '/link_ids'), + ('api.links', Links, '/links'), + ('api.link', Link, '/link/<path:link_uuid>'), - ('api.connection_ids', ConnectionIds, '/context/<path:context_uuid>/service/<path:service_uuid>/connection_ids'), - ('api.connections', Connections, '/context/<path:context_uuid>/service/<path:service_uuid>/connections'), - ('api.connection', Connection, '/connection/<path:connection_uuid>'), + ('api.connection_ids', ConnectionIds, '/context/<path:context_uuid>/service/<path:service_uuid>/connection_ids'), + ('api.connections', Connections, '/context/<path:context_uuid>/service/<path:service_uuid>/connections'), + ('api.connection', Connection, '/connection/<path:connection_uuid>'), - ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), - ('api.policyrules', PolicyRules, '/policyrules'), - ('api.policyrule', PolicyRule, '/policyrule/<path:policyrule_uuid>'), + ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), + ('api.policyrules', PolicyRules, '/policyrules'), + ('api.policyrule', PolicyRule, '/policyrule/<path:policyrule_uuid>'), ] def register_tfs_api(rest_server : RestServer): diff --git a/src/tests/ecoc24/.gitlab-ci.yml b/src/tests/ecoc24/.gitlab-ci.yml index af0646a0fda2968ef58e7b98d6363317ea975c62..412b25450aeffd67f26c5e4ee0d1906ea400954f 100644 --- a/src/tests/ecoc24/.gitlab-ci.yml +++ b/src/tests/ecoc24/.gitlab-ci.yml @@ -56,10 +56,6 @@ end2end_test ecoc24: - microk8s status --wait-ready - kubectl get pods --all-namespaces - # Deploy Optical Device Node Agents - #- > - # docker network create -d bridge --subnet=172.254.253.0/24 --gateway=172.254.253.254 - # --ip-range=172.254.253.0/24 na-br # Configure TeraFlowSDN deployment @@ -70,36 +66,45 @@ end2end_test ecoc24: #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/sliceservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml - - source src/tests/${TEST_NAME}/deploy_specs_e2e.sh - # Deploy TeraFlowSDN + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/e2eorchestratorservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/vntmservice.yaml + + + + # Deploy Optical TeraFlowSDN + - source src/tests/${TEST_NAME}/deploy_specs_opt.sh - ./deploy/crdb.sh - ./deploy/nats.sh - ./deploy/qdb.sh - ./deploy/expose_dashboard.sh - ./deploy/tfs.sh - ./deploy/show.sh - - ./src/tests/${TEST_NAME}/subscription_ws_e2e.sh + - cp /var/teraflow/tfs_runtime_env_vars.sh /var/teraflow/tfs_runtime_env_vars_opt.sh - - source src/tests/${TEST_NAME}/deploy_specs_opt.sh - # Deploy TeraFlowSDN + + # Deploy IP TeraFlowSDN + - source src/tests/${TEST_NAME}/deploy_specs_ip.sh - ./deploy/crdb.sh - ./deploy/nats.sh - ./deploy/qdb.sh - ./deploy/expose_dashboard.sh - ./deploy/tfs.sh - ./deploy/show.sh + - ./src/tests/${TEST_NAME}/subscription_ws_ip.sh + - cp /var/teraflow/tfs_runtime_env_vars.sh /var/teraflow/tfs_runtime_env_vars_ip.sh - - source src/tests/${TEST_NAME}/deploy_specs_ip.sh - # Deploy TeraFlowSDN + # Deploy E2E TeraFlowSDN + - source src/tests/${TEST_NAME}/deploy_specs_e2e.sh - ./deploy/crdb.sh - ./deploy/nats.sh - ./deploy/qdb.sh - ./deploy/expose_dashboard.sh - ./deploy/tfs.sh - ./deploy/show.sh - - ./src/tests/${TEST_NAME}/subscription_ws_ip.sh - + - ./src/tests/${TEST_NAME}/subscription_ws_e2e.sh + - cp /var/teraflow/tfs_runtime_env_vars.sh /var/teraflow/tfs_runtime_env_vars_e2e.sh + # Run end-to-end tests diff --git a/src/tests/ecoc24/deploy_e2e.sh b/src/tests/ecoc24/deploy_e2e.sh index da7ef252cca385109fbe92480f5f625b5a391a1e..a135835c7faee72260a142bb8a05ea87ded81c9b 100755 --- a/src/tests/ecoc24/deploy_e2e.sh +++ b/src/tests/ecoc24/deploy_e2e.sh @@ -25,7 +25,12 @@ kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml # Deploy TFS for E2E source src/tests/ecoc24/deploy_specs_e2e.sh + +# Change the name for the database +cp manifests/contextservice.yaml manifests/contextservice.yaml.bak +sed -i '/name: CRDB_DATABASE/{n;s/value: .*/value: "tfse2e_context"/}' manifests/contextservice.yaml ./deploy/all.sh +mv manifests/contextservice.yaml.bak manifests/contextservice.yaml #Configure Subscription WS ./src/tests/ecoc24/subscription_ws_e2e.sh diff --git a/src/tests/ecoc24/deploy_ip.sh b/src/tests/ecoc24/deploy_ip.sh index a6c5e82557d02c89f67bbbf0ee0a6f88650ba9d1..418a270bcebaa11861bce5e0a74abbc505e38aea 100755 --- a/src/tests/ecoc24/deploy_ip.sh +++ b/src/tests/ecoc24/deploy_ip.sh @@ -25,7 +25,12 @@ kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml # Deploy TFS for IP source src/tests/ecoc24/deploy_specs_ip.sh + +# Change the name for the database +cp manifests/contextservice.yaml manifests/contextservice.yaml.bak +sed -i '/name: CRDB_DATABASE/{n;s/value: .*/value: "tfsip_context"/}' manifests/contextservice.yaml ./deploy/all.sh +mv manifests/contextservice.yaml.bak manifests/contextservice.yaml #Configure Subscription WS ./src/tests/ecoc24/subscription_ws_ip.sh diff --git a/src/tests/ecoc24/deploy_opt.sh b/src/tests/ecoc24/deploy_opt.sh index 3a9523768ec21c2e177a3567a51cdc94f4db992b..ab2971fd5feac17e5c4154b3f77ae5c5ca89ba9e 100755 --- a/src/tests/ecoc24/deploy_opt.sh +++ b/src/tests/ecoc24/deploy_opt.sh @@ -25,5 +25,11 @@ kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-opt.yaml # Deploy TFS for OPT source src/tests/ecoc24/deploy_specs_opt.sh + +# Change the name for the database +cp manifests/contextservice.yaml manifests/contextservice.yaml.bak +sed -i '/name: CRDB_DATABASE/{n;s/value: .*/value: "tfsopt_context"/}' manifests/contextservice.yaml ./deploy/all.sh +mv manifests/contextservice.yaml.bak manifests/contextservice.yaml + mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_opt.sh diff --git a/src/tests/ecoc24/deploy_specs_e2e.sh b/src/tests/ecoc24/deploy_specs_e2e.sh index a8353db54a9518f504f16030d6d88b1e01f47137..3b287ba89eb62d70ef719303d39e249e3659091c 100755 --- a/src/tests/ecoc24/deploy_specs_e2e.sh +++ b/src/tests/ecoc24/deploy_specs_e2e.sh @@ -20,7 +20,7 @@ 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 nbi" +export TFS_COMPONENTS="context device pathcomp service nbi webui" # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -137,7 +137,7 @@ export CRDB_DATABASE="tfs_e2e" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="YES" +export CRDB_DROP_DATABASE_IF_EXISTS="NO" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" @@ -214,3 +214,4 @@ export KFK_SERVER_PORT="9092" # Set the flag to YES for redeploying of Apache Kafka export KFK_REDEPLOY="" + \ No newline at end of file diff --git a/src/tests/ecoc24/deploy_specs_ip.sh b/src/tests/ecoc24/deploy_specs_ip.sh index 52bd545ce3b40185c794db97182b3c1f5ab17ffc..114289f4daf7e69cb035378a1fb03c3c5c5337d3 100755 --- a/src/tests/ecoc24/deploy_specs_ip.sh +++ b/src/tests/ecoc24/deploy_specs_ip.sh @@ -20,7 +20,7 @@ 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 nbi" +export TFS_COMPONENTS="context device pathcomp service nbi webui" # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -137,7 +137,7 @@ export CRDB_DATABASE="tfs_ip" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="YES" +export CRDB_DROP_DATABASE_IF_EXISTS="NO" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" diff --git a/src/tests/ecoc24/deploy_specs_opt.sh b/src/tests/ecoc24/deploy_specs_opt.sh index 999fba04517b51700c217bb2dd4561a6d887e5b0..4c7997f5200e056e1d298a5d40b0fc610900f944 100755 --- a/src/tests/ecoc24/deploy_specs_opt.sh +++ b/src/tests/ecoc24/deploy_specs_opt.sh @@ -20,7 +20,7 @@ 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 nbi" +export TFS_COMPONENTS="context device pathcomp service nbi webui" # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -137,7 +137,7 @@ export CRDB_DATABASE="tfs_ip" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="YES" +export CRDB_DROP_DATABASE_IF_EXISTS="NO" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" diff --git a/src/tests/ecoc24/descriptors/link_mapping.json b/src/tests/ecoc24/descriptors/descriptor_e2e.json similarity index 99% rename from src/tests/ecoc24/descriptors/link_mapping.json rename to src/tests/ecoc24/descriptors/descriptor_e2e.json index d2e9f11d7487f0d703b05bb8d86d835e9fbf31ae..41649d92ebf6a4cdb854a8f523b9b0497d04fd59 100644 --- a/src/tests/ecoc24/descriptors/link_mapping.json +++ b/src/tests/ecoc24/descriptors/descriptor_e2e.json @@ -82,4 +82,5 @@ ] } ] - } \ No newline at end of file + } + \ No newline at end of file diff --git a/src/tests/ecoc24/descriptors/descriptor_ip.json b/src/tests/ecoc24/descriptors/descriptor_ip.json index b0909321c572a1da27cc92a637b1c37a5989c03b..11ad2d5c121925706f59486753504cf660cf27b1 100644 --- a/src/tests/ecoc24/descriptors/descriptor_ip.json +++ b/src/tests/ecoc24/descriptors/descriptor_ip.json @@ -209,4 +209,5 @@ } ], "dummy_mode":true - } \ No newline at end of file + } + \ No newline at end of file diff --git a/src/tests/ecoc24/descriptors/descriptor_opt.json b/src/tests/ecoc24/descriptors/descriptor_opt.json index 320da86924d814aa79b0f145736c08105a731238..cfb86b9660ac3559d10a9358e0484f27f4ff70c7 100644 --- a/src/tests/ecoc24/descriptors/descriptor_opt.json +++ b/src/tests/ecoc24/descriptors/descriptor_opt.json @@ -799,4 +799,5 @@ ] } ] - } \ No newline at end of file + } + \ No newline at end of file diff --git a/src/tests/ecoc24/tests/test_functional_bootstrap_e2e.py b/src/tests/ecoc24/tests/test_functional_bootstrap_e2e.py new file mode 100644 index 0000000000000000000000000000000000000000..cd72f5e945fbd04928723bbfad4e134647f497f2 --- /dev/null +++ b/src/tests/ecoc24/tests/test_functional_bootstrap_e2e.py @@ -0,0 +1,67 @@ +# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging, os, time +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty +from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario +from common.tools.object_factory.Context import json_context_id +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient +from tests.Fixtures import context_client, device_client # pylint: disable=unused-import + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors', 'descriptor_e2e.json') +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + +def test_scenario_bootstrap( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient, # pylint: disable=redefined-outer-name +) -> None: + validate_empty_scenario(context_client) + + descriptor_loader = DescriptorLoader( + descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) + results = descriptor_loader.process() + check_descriptor_load_results(results, descriptor_loader) + descriptor_loader.validate() + + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + +def test_scenario_devices_enabled( + context_client : ContextClient, # pylint: disable=redefined-outer-name +) -> None: + """ + This test validates that the devices are enabled. + """ + """ DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + + num_devices = -1 + num_devices_enabled, num_retry = 0, 0 + while (num_devices != num_devices_enabled) and (num_retry < 10): + time.sleep(1.0) + response = context_client.ListDevices(Empty()) + num_devices = len(response.devices) + num_devices_enabled = 0 + for device in response.devices: + if device.device_operational_status != DEVICE_OP_STATUS_ENABLED: continue + num_devices_enabled += 1 + LOGGER.info('Num Devices enabled: {:d}/{:d}'.format(num_devices_enabled, num_devices)) + num_retry += 1 """ + assert 1 == 1 diff --git a/src/tests/ecoc24/tests/test_functional_bootstrap.py b/src/tests/ecoc24/tests/test_functional_bootstrap_ip.py similarity index 100% rename from src/tests/ecoc24/tests/test_functional_bootstrap.py rename to src/tests/ecoc24/tests/test_functional_bootstrap_ip.py diff --git a/src/tests/ecoc24/tests/test_functional_bootstrap_opt.py b/src/tests/ecoc24/tests/test_functional_bootstrap_opt.py new file mode 100644 index 0000000000000000000000000000000000000000..2f400c3461d2ffeff2cbd1a874d38b6a1bcaca3b --- /dev/null +++ b/src/tests/ecoc24/tests/test_functional_bootstrap_opt.py @@ -0,0 +1,67 @@ +# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging, os, time +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty +from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario +from common.tools.object_factory.Context import json_context_id +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient +from tests.Fixtures import context_client, device_client # pylint: disable=unused-import + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors', 'descriptor_opt.json') +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + +def test_scenario_bootstrap( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient, # pylint: disable=redefined-outer-name +) -> None: + validate_empty_scenario(context_client) + + descriptor_loader = DescriptorLoader( + descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) + results = descriptor_loader.process() + check_descriptor_load_results(results, descriptor_loader) + descriptor_loader.validate() + + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + +def test_scenario_devices_enabled( + context_client : ContextClient, # pylint: disable=redefined-outer-name +) -> None: + """ + This test validates that the devices are enabled. + """ + """ DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + + num_devices = -1 + num_devices_enabled, num_retry = 0, 0 + while (num_devices != num_devices_enabled) and (num_retry < 10): + time.sleep(1.0) + response = context_client.ListDevices(Empty()) + num_devices = len(response.devices) + num_devices_enabled = 0 + for device in response.devices: + if device.device_operational_status != DEVICE_OP_STATUS_ENABLED: continue + num_devices_enabled += 1 + LOGGER.info('Num Devices enabled: {:d}/{:d}'.format(num_devices_enabled, num_devices)) + num_retry += 1 """ + assert 1 == 1 diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index d684e044efd972bd7705f6c1a448b0a5be23431b..b33705ed5aee61d028e99ec9cbf2a86ea69190f2 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -45,7 +45,7 @@ GET_EVENT_TIMEOUT = 0.5 class VNTMEventDispatcher(threading.Thread): def __init__(self, host, port) -> None: - LOGGER.debug('Creating VTNM connector...') + LOGGER.debug('Creating VNTM connector...') self.host = host self.port = port super().__init__(name='VNTMEventDispatcher', daemon=True) @@ -107,8 +107,8 @@ class VNTMEventDispatcher(threading.Thread): while not self._terminate.is_set(): event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) - LOGGER.info('Event type: {}'.format(event)) if event is None: continue + LOGGER.info('Event type: {}'.format(event)) LOGGER.debug('Received event: {}'.format(event)) topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id))