#!/usr/bin/env python3 #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. # Manage L2 services (with underlying XR connectivity) without need to use unit test # files or excessive JSON definitions # # Run in this directory with PYTHONPATH=../../../../ # E.g.: # PYTHONPATH=../../../../ ./service-cli.py create 1 R1-EMU 13/1/2 500 2 R3-EMU 13/1/2 500 # PYTHONPATH=../../../../ ./service-cli.py list # PYTHONPATH=../../../../ ./service-cli.py delete 43a8046a-5dec-463d-82f7-7cc3442dbf4f import argparse import logging import traceback from contextlib import contextmanager from common.Settings import get_setting from context.client.ContextClient import ContextClient from tests.tools.mock_osm.MockOSM import MockOSM from common.proto.context_pb2 import ContextId, ServiceTypeEnum, ServiceStatusEnum from common.tools.grpc.Tools import grpc_message_to_json_string LOGGER = logging.getLogger(__name__) WIM_USERNAME = 'admin' WIM_PASSWORD = 'admin' @contextmanager def make_context_client(): try: _client = ContextClient(get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC')) yield _client finally: _client.close() def make_osm_wim(): wim_url = 'http://{:s}:{:s}'.format( get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP'))) return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD) logging.basicConfig(level=logging.ERROR) parser = argparse.ArgumentParser(description='TF Service Management Utility') subparsers = parser.add_subparsers(dest="command") subparsers.required = True create_parser = subparsers.add_parser('create') create_parser.add_argument('site1', type=int, help='One endpoint of the service, e.g. 1') create_parser.add_argument('device1', type=str, help='One endpoint of the service, e.g. R1-EMU') create_parser.add_argument('interface1', type=str, help='One endpoint of the service, e.g. 13/1/2') create_parser.add_argument('vlan1', type=int, help='VLAN in first endpoint, e.g. 500') create_parser.add_argument('site2', type=int, help='One endpoint of the service, e.g. 2') create_parser.add_argument('device2', type=str, help='One endpoint of the service, e.g. R3-EMU') create_parser.add_argument('interface2', type=str, help='One endpoint of the service, e.g. 13/1/2') create_parser.add_argument('vlan2', type=int, help='VLAN in first endpoint, e.g. 500') delete_parser = subparsers.add_parser('delete') delete_parser.add_argument('service_uuid', type=str, help='UUID of the service to be deleted') list_parser = subparsers.add_parser('list') args = parser.parse_args() WIM_SERVICE_TYPE = 'ELINE' CONTEXT_ID = {'context_uuid': {'uuid': 'admin'}} if args.command == "create": endpoint1 = f"{args.device1}:{args.interface1}" endpoint2 = f"{args.device2}:{args.interface2}" WIM_MAPPING = [ {'device-id': args.device1, 'service_endpoint_id': endpoint1, 'service_mapping_info': {'bearer': {'bearer-reference': endpoint1}, 'site-id': args.site1}}, {'device-id': args.device2, 'service_endpoint_id': endpoint2, 'service_mapping_info': {'bearer': {'bearer-reference': endpoint2}, 'site-id': args.site2}}, ] WIM_SERVICE_CONNECTION_POINTS = [ {'service_endpoint_id': endpoint1, 'service_endpoint_encapsulation_type': 'dot1q', 'service_endpoint_encapsulation_info': {'vlan': args.vlan1}}, {'service_endpoint_id': endpoint2, 'service_endpoint_encapsulation_type': 'dot1q', 'service_endpoint_encapsulation_info': {'vlan': args.vlan2}}, ] else: WIM_MAPPING = [] WIM_SERVICE_CONNECTION_POINTS = [] #print(str(args)) print(f"=== WIM_SERVICE_TYPE: {WIM_SERVICE_TYPE}") print(f"=== WIM_SERVICE_CONNECTION_POINTS: {WIM_SERVICE_CONNECTION_POINTS}") print(f"=== WIM_MAPPING: {WIM_MAPPING}") with make_context_client() as client: osm_wim = make_osm_wim(); if args.command == "create": service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS) print(f"*** Create connectivity service --> {service_uuid}") status = osm_wim.get_connectivity_service_status(service_uuid) print(f"*** Get created service status --> {str(status)}") elif args.command == "delete": osm_wim.wim.check_credentials() try: osm_wim.wim.delete_connectivity_service(args.service_uuid) print(f"*** Service {args.service_uuid} is no longer present (delete was successfull or service did not exist)") except Exception as e: print(f"*** Failed to delete service {args.service_uuid}, {e}") elif args.command == "list": response = client.ListServices(ContextId(**CONTEXT_ID)) #print('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) for service in response.services: scs = "" # See if there are endpoint constraints that might be regognizable by the user. # Keys do not necessarily exist, so catch exceptions and ignore those constraints # that we cannot easily represent. for sc in service.service_constraints: try: scs += f"{sc.endpoint_location.endpoint_id.device_id.device_uuid.uuid}:{sc.endpoint_location.endpoint_id.endpoint_uuid.uuid} " except Exception: pass print(f"{service.service_id.service_uuid.uuid:36} {ServiceTypeEnum.Name(service.service_type):40} {ServiceStatusEnum.Name(service.service_status.service_status)} {scs}")