Commit f154b297 authored by Shayan Hajipour's avatar Shayan Hajipour
Browse files

enhancement: list of slice endpoints retrieved in webui depended on

config rules. If the slice is related to CAMARA OFC25, retrieve the list
of endpoints based on SDPs, otherwise, return the slice object's list of
endpoints.
parent 32ec651f
Loading
Loading
Loading
Loading
+68 −4
Original line number Diff line number Diff line
@@ -14,10 +14,11 @@

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.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum, EndPointId
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.Constants import DEFAULT_CONTEXT_NAME
from context.client.ContextClient import ContextClient
from slice.client.SliceClient import SliceClient

@@ -26,6 +27,67 @@ 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(
    service_config: ServiceConfig, resource_key: str
) -> Optional[ConfigRule]:
    """
    Retrieve the custom config rule with the given resource_key from a ServiceConfig.
    """
    for cr in service_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 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:
        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 = DEFAULT_CONTEXT_NAME
            device_uuid = sdp["node-id"]
            endpoint.device_id.device_uuid.uuid = device_uuid
            attachment_circuits = sdp["attachment-circuits"]["attachment-circuit"]
            endpoint_uuid = attachment_circuits[0]["ac-tp-id"]
            endpoint.endpoint_uuid.uuid = endpoint_uuid
            list_endpoint_ids.append(endpoint)

    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 +112,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 +144,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()