Commit 199fbb2c authored by Ville Hallivuori's avatar Ville Hallivuori
Browse files

Support creating XR service without using multi-layer path computation

parent a5004f44
Loading
Loading
Loading
Loading
+129 −11
Original line number Original line Diff line number Diff line
@@ -19,21 +19,31 @@
#
#
# Run in this directory with PYTHONPATH=../../../../
# Run in this directory with PYTHONPATH=../../../../
# E.g.:
# E.g.:
#   Multi-layer:
#     PYTHONPATH=../../../../  ./service-cli.py create 1 R1-EMU 13/1/2 500 2 R3-EMU 13/1/2 500
#     PYTHONPATH=../../../../  ./service-cli.py create 1 R1-EMU 13/1/2 500 2 R3-EMU 13/1/2 500
#   Single-layer:
#     PYTHONPATH=../../../../  ./service-cli.py create-xr mydirectservice7 X1-XR-CONSTELLATION  "XR HUB 1|XR-T1" "XR LEAF 1|XR-T1"
#
#     PYTHONPATH=../../../../  ./service-cli.py list
#     PYTHONPATH=../../../../  ./service-cli.py list
#     PYTHONPATH=../../../../  ./service-cli.py delete 43a8046a-5dec-463d-82f7-7cc3442dbf4f
#     PYTHONPATH=../../../../  ./service-cli.py delete 43a8046a-5dec-463d-82f7-7cc3442dbf4f



import argparse
import argparse
import logging
import logging
import traceback
#import traceback
from contextlib import contextmanager
from contextlib import contextmanager


from common.Settings import get_setting
from common.Settings import get_setting
from context.client.ContextClient import ContextClient
from context.client.ContextClient import ContextClient
from service.client.ServiceClient import ServiceClient
from tests.tools.mock_osm.MockOSM import MockOSM
from tests.tools.mock_osm.MockOSM import MockOSM
from common.proto.context_pb2 import ContextId, ServiceTypeEnum, ServiceStatusEnum
from common.proto.context_pb2 import ContextId, ServiceTypeEnum, ServiceStatusEnum, Service, Context, Empty
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.Context import json_context, json_context_id
from common.tools.object_factory.Topology import json_topology_id
from common.tools.object_factory.ConfigRule import json_config_rule_set
from copy import deepcopy
from dataclasses import dataclass, field
from typing import Dict


LOGGER = logging.getLogger(__name__)
LOGGER = logging.getLogger(__name__)


@@ -48,11 +58,44 @@ def make_context_client():
    finally:
    finally:
        _client.close()
        _client.close()


@contextmanager
def make_service_client():
    try:
        _client = ServiceClient(get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
        yield _client
    finally:
        _client.close()

def make_osm_wim():
def make_osm_wim():
    wim_url = 'http://{:s}:{:s}'.format(
    wim_url = 'http://{:s}:{:s}'.format(
        get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP')))
        get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP')))
    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)


@dataclass
class DevInfo:
    name: str
    uuid: str
    # endpoints name --> uuid
    endpoints: Dict[str, str] = field(default_factory= dict)

    def get_endpoint_uuid_or_exit(self, ep_name: str) -> str:
        if ep_name not in self.endpoints:
            print(f"Endpoint {ep_name} does not exist in device {self.name}. See \"service-cli.py list-endpoints\"")
            exit(-1)
        return self.endpoints[ep_name]

def get_devices(cc: ContextClient) -> Dict[str, DevInfo]:
    r = cc.ListDevices(Empty())
    # print(grpc_message_to_json_string(r))

    devices = dict()
    for dev in r.devices:
        di = DevInfo(dev.name, dev.device_id.device_uuid.uuid)
        for ep in dev.device_endpoints:
            di.endpoints[ep.name] = ep.endpoint_id.endpoint_uuid.uuid
        devices[dev.name] = di
    return devices

logging.basicConfig(level=logging.ERROR)
logging.basicConfig(level=logging.ERROR)


parser = argparse.ArgumentParser(description='TF Service Management Utility')
parser = argparse.ArgumentParser(description='TF Service Management Utility')
@@ -74,6 +117,13 @@ delete_parser = subparsers.add_parser('delete')
delete_parser.add_argument('service_uuid', type=str, help='UUID of the service to be deleted')
delete_parser.add_argument('service_uuid', type=str, help='UUID of the service to be deleted')


list_parser = subparsers.add_parser('list')
list_parser = subparsers.add_parser('list')
list_parser = subparsers.add_parser('list-endpoints')

create_xr_parser = subparsers.add_parser('create-xr')
create_xr_parser.add_argument('service_name', type=str, help='Service Name')
create_xr_parser.add_argument('constellation', type=str, help='XR Constellation')
create_xr_parser.add_argument('interface1', type=str, help='One endpoint of the service')
create_xr_parser.add_argument('interface2', type=str, help='Second endpoint of the service')


args = parser.parse_args()
args = parser.parse_args()


@@ -103,12 +153,12 @@ else:
    WIM_SERVICE_CONNECTION_POINTS = []
    WIM_SERVICE_CONNECTION_POINTS = []


#print(str(args))
#print(str(args))
print(f"=== WIM_SERVICE_TYPE: {WIM_SERVICE_TYPE}")
#print(f"=== WIM_SERVICE_TYPE: {WIM_SERVICE_TYPE}")
print(f"=== WIM_SERVICE_CONNECTION_POINTS: {WIM_SERVICE_CONNECTION_POINTS}")
#print(f"=== WIM_SERVICE_CONNECTION_POINTS: {WIM_SERVICE_CONNECTION_POINTS}")
print(f"=== WIM_MAPPING: {WIM_MAPPING}")
#print(f"=== WIM_MAPPING: {WIM_MAPPING}")


with make_context_client() as client:
with make_context_client() as client:
    osm_wim = make_osm_wim();
    osm_wim = make_osm_wim()


    if args.command == "create":
    if args.command == "create":
        service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
        service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
@@ -123,6 +173,68 @@ with make_context_client() as client:
            print(f"*** Service {args.service_uuid} is no longer present (delete was successfull or service did not exist)")
            print(f"*** Service {args.service_uuid} is no longer present (delete was successfull or service did not exist)")
        except Exception as e:
        except Exception as e:
            print(f"*** Failed to delete service {args.service_uuid}, {e}")
            print(f"*** Failed to delete service {args.service_uuid}, {e}")

    elif args.command == "create-xr":
        CONTEXT_NAME = 'admin'
        CONTEXT_ID   = json_context_id(CONTEXT_NAME)
        CONTEXT      = json_context(CONTEXT_NAME, name=CONTEXT_NAME)

        json_tapi_settings = {
            'capacity_value'  : 50.0,
            'capacity_unit'   : 'GHz',
            'layer_proto_name': 'PHOTONIC_MEDIA',
            'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC',
            'direction'       : 'UNIDIRECTIONAL',
        }
        config_rule = json_config_rule_set('/settings', json_tapi_settings)

        response = client.ListContextIds(Empty())
        assert len(response.context_ids) == 1
        context_uuid=json_context_id(response.context_ids[0].context_uuid.uuid)

        devices = get_devices(client)
        if args.constellation not in devices:
            print(f"Constellation {args.constellation} does not exist as a device. See \"service-cli.py list-endpoints\"")
            exit(-1)
        else:
            dev_info = devices[args.constellation]
            constellation_uuid = dev_info.uuid

        interface1_uuid = dev_info.get_endpoint_uuid_or_exit(args.interface1)
        interface2_uuid = dev_info.get_endpoint_uuid_or_exit(args.interface2)

        print(f"Constellation {args.constellation:40}: {constellation_uuid:36}")
        print(f"Interface 1   {args.interface1:40}: {interface1_uuid:36}")
        print(f"Interface 2   {args.interface2:40}: {interface2_uuid:36}")

        service_request = {
            "name": args.service_name,
            "service_id": {
                 "context_id": {"context_uuid": {"uuid": response.context_ids[0].context_uuid.uuid}},
                 "service_uuid": {"uuid": args.service_name}
            },
            'service_type'        : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
            "service_endpoint_ids": [
                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': interface1_uuid}, 'topology_id': json_topology_id("admin", context_id=context_uuid)},
                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': interface2_uuid}, 'topology_id': json_topology_id("admin", context_id=context_uuid)}
            ],
            'service_status'      : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED},
            'service_constraints' : [],
        }

        with make_service_client() as service_client:
            sr = deepcopy(service_request)
            endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], []
            create_response = service_client.CreateService(Service(**sr))
            print(f'CreateService: {grpc_message_to_json_string(create_response)}')

            sr['service_endpoint_ids'] = endpoints
            #sr['service_id']['service_uuid'] = create_response
            sr['service_config'] = {'config_rules': [config_rule]}

            update_response = service_client.UpdateService(Service(**sr))
            print(f'UpdateService: {grpc_message_to_json_string(update_response)}')

    elif args.command == "list":
    elif args.command == "list":
        response = client.ListServices(ContextId(**CONTEXT_ID))
        response = client.ListServices(ContextId(**CONTEXT_ID))


@@ -136,9 +248,15 @@ with make_context_client() as client:
            for sc in service.service_constraints:
            for sc in service.service_constraints:
                try:
                try:
                    scs += f"{sc.endpoint_location.endpoint_id.device_id.device_uuid.uuid}:{sc.endpoint_location.endpoint_id.endpoint_uuid.uuid} "
                    scs += f"{sc.endpoint_location.endpoint_id.device_id.device_uuid.uuid}:{sc.endpoint_location.endpoint_id.endpoint_uuid.uuid} "
                except Exception:
                except Exception: # pylint: disable=bare-except
                    pass
                    pass


            print(f"{service.service_id.service_uuid.uuid:36}  {ServiceTypeEnum.Name(service.service_type):40}  {ServiceStatusEnum.Name(service.service_status.service_status)}  {scs}")
            print(f"{service.service_id.service_uuid.uuid:36}  {ServiceTypeEnum.Name(service.service_type):40}  {service.name:40}  {ServiceStatusEnum.Name(service.service_status.service_status)}  {scs}")



    elif args.command == "list-endpoints":
        devices = get_devices(client)
        for name in sorted(devices.keys()):
            dev = devices[name]
            print(f"{name:40}    {dev.uuid:36}")
            for ep_name in sorted(dev.endpoints.keys()):
                print(f"    {ep_name:40}    {dev.endpoints[ep_name]:36}")
+4 −0
Original line number Original line Diff line number Diff line
@@ -17,7 +17,11 @@ export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get service/contextservice --namesp
export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service/contextservice --namespace tfs  -o jsonpath='{.spec.ports[?(@.name=="grpc")].port}')
export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service/contextservice --namespace tfs  -o jsonpath='{.spec.ports[?(@.name=="grpc")].port}')
export COMPUTESERVICE_SERVICE_HOST=$(kubectl get service/computeservice --namespace tfs  --template '{{.spec.clusterIP}}')
export COMPUTESERVICE_SERVICE_HOST=$(kubectl get service/computeservice --namespace tfs  --template '{{.spec.clusterIP}}')
export COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service/computeservice --namespace tfs  -o jsonpath='{.spec.ports[?(@.name=="http")].port}')
export COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service/computeservice --namespace tfs  -o jsonpath='{.spec.ports[?(@.name=="http")].port}')
export SERVICESERVICE_SERVICE_HOST=$(kubectl get service/serviceservice --namespace tfs  --template '{{.spec.clusterIP}}')
export SERVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service/serviceservice --namespace tfs  -o jsonpath='{.spec.ports[?(@.name=="grpc")].port}')
echo "CONTEXTSERVICE_SERVICE_HOST=$CONTEXTSERVICE_SERVICE_HOST"
echo "CONTEXTSERVICE_SERVICE_HOST=$CONTEXTSERVICE_SERVICE_HOST"
echo "CONTEXTSERVICE_SERVICE_PORT_GRPC=$CONTEXTSERVICE_SERVICE_PORT_GRPC"
echo "CONTEXTSERVICE_SERVICE_PORT_GRPC=$CONTEXTSERVICE_SERVICE_PORT_GRPC"
echo "COMPUTESERVICE_SERVICE_HOST=$COMPUTESERVICE_SERVICE_HOST"
echo "COMPUTESERVICE_SERVICE_HOST=$COMPUTESERVICE_SERVICE_HOST"
echo "COMPUTESERVICE_SERVICE_PORT_HTTP=$COMPUTESERVICE_SERVICE_PORT_HTTP"
echo "COMPUTESERVICE_SERVICE_PORT_HTTP=$COMPUTESERVICE_SERVICE_PORT_HTTP"
echo "SERVICESERVICE_SERVICE_HOST=$SERVICESERVICE_SERVICE_HOST"
echo "SERVICESERVICE_SERVICE_PORT_GRPC=$SERVICESERVICE_SERVICE_PORT_GRPC"