Commit 983ab351 authored by Pedro Paulo Tavares's avatar Pedro Paulo Tavares
Browse files

Added some tests and new QKDDriver and Tool with error handling and more logging level

parent ca09f455
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -212,24 +212,24 @@ for COMPONENT in $TFS_COMPONENTS; do
        BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"

        if [ "$COMPONENT" == "ztp" ] || [ "$COMPONENT" == "policy" ]; then
            $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
        elif [ "$COMPONENT" == "pathcomp" ]; then
            BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log"
            $DOCKER_BUILD -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . > "$BUILD_LOG"

            BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log"
            $DOCKER_BUILD -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . > "$BUILD_LOG"
            # next command is redundant, but helpful to keep cache updated between rebuilds
            IMAGE_NAME="$COMPONENT-backend:$TFS_IMAGE_TAG-builder"
            $DOCKER_BUILD -t "$IMAGE_NAME" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$IMAGE_NAME" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
        elif [ "$COMPONENT" == "dlt" ]; then
            BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-connector.log"
            $DOCKER_BUILD -t "$COMPONENT-connector:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/connector/Dockerfile . > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT-connector:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/connector/Dockerfile . > "$BUILD_LOG"

            BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-gateway.log"
            $DOCKER_BUILD -t "$COMPONENT-gateway:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/gateway/Dockerfile . > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT-gateway:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/gateway/Dockerfile . > "$BUILD_LOG"
        else
            $DOCKER_BUILD -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
            $DOCKER_BUILD --network=host -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
        fi

        echo "  Pushing Docker image to '$TFS_REGISTRY_IMAGES'..."
+4 −2
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@
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 slice nbi webui load_generator"
export TFS_COMPONENTS="context device pathcomp service slice nbi webui app"

# export load_generator

# Uncomment to activate Monitoring
#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"
@@ -109,7 +111,7 @@ export CRDB_DEPLOY_MODE="single"
export CRDB_DROP_DATABASE_IF_EXISTS=""

# Disable flag for re-deploying CockroachDB from scratch.
export CRDB_REDEPLOY=""
export CRDB_REDEPLOY="YES"


# ----- NATS -------------------------------------------------------------------
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ class DeviceTypeEnum(Enum):
    PACKET_ROUTER                   = 'packet-router'
    PACKET_SWITCH                   = 'packet-switch'
    XR_CONSTELLATION                = 'xr-constellation'
    QKD_NODE                        = 'qkd-node'

    # ETSI TeraFlowSDN controller
    TERAFLOWSDN_CONTROLLER          = 'teraflowsdn'

src/context/proto

0 → 120000
+1 −0
Original line number Diff line number Diff line
../../proto/src/python
 No newline at end of file
+246 −0
Original line number Diff line number Diff line
import sys
import os
import grpc
import json
from flask import Flask, jsonify, request, abort
from common.proto.context_pb2 import Empty, ContextId, TopologyId, Uuid
from common.proto.context_pb2_grpc import ContextServiceStub
from device.service.driver_api.DriverInstanceCache import DriverInstanceCache, get_driver
from device.service.driver_api.DriverFactory import DriverFactory
from device.service.driver_api.FilterFields import FilterFieldEnum
from device.service.driver_api._Driver import _Driver
from device.service.drivers.qkd.QKDDriver2 import QKDDriver  
app = Flask(__name__)

# Add the directory containing the driver_api module to the system path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')))

# Initialize the DriverFactory and DriverInstanceCache
drivers_list = [
    (QKDDriver, [{'filter_field1': 'value1', 'filter_field2': 'value2'}])
]

driver_factory = DriverFactory(drivers_list)
driver_instance_cache = DriverInstanceCache(driver_factory)


def get_context_topology_info():
    try:
        # Establish a gRPC channel
        channel = grpc.insecure_channel('10.152.183.77:1010')  # Update with the correct IP and port
        stub = ContextServiceStub(channel)

        # Retrieve the context information
        context_list = stub.ListContexts(Empty())
        contexts_info = []
        for context in context_list.contexts:
            context_info = {
                'context_id': context.context_id.context_uuid.uuid,
                'context_name': context.name,
                'topologies': []
            }

            # Retrieve topology information for each context
            topology_list = stub.ListTopologies(context.context_id)
            for topology in topology_list.topologies:
                topology_info = {
                    'topology_id': topology.topology_id.topology_uuid.uuid,
                    'topology_name': topology.name,
                    'devices': []
                }

                # Retrieve detailed topology information
                topology_details = stub.GetTopologyDetails(topology.topology_id)
                for device in topology_details.devices:
                    device_info = {
                        'device_id': device.device_id.device_uuid.uuid,
                        'device_name': device.name,
                        'device_type': device.device_type,
                        'status': device.device_operational_status,
                        'drivers': [driver for driver in device.device_drivers],
                        'endpoints': [{
                            'uuid': endpoint.endpoint_id.endpoint_uuid.uuid,
                            'name': endpoint.name,
                            'type': endpoint.endpoint_type,
                            'location': endpoint.endpoint_location
                        } for endpoint in device.device_endpoints],
                        'configurations': [{
                            'key': config.custom.resource_key,
                            'value': config.custom.resource_value
                        } for config in device.device_config.config_rules],
                        'interfaces': [{
                            'id': interface.qkdi_id,
                            'enabled': interface.enabled,
                            'name': interface.name,
                            'att_point': interface.qkdi_att_point,
                            'capabilities': interface.qkdi_capabilities
                        } for interface in device.qkd_interfaces.qkd_interface],
                        'applications': [{
                            'app_id': app.app_id,
                            'app_qos': app.app_qos,
                            'app_statistics': app.app_statistics,
                            'backing_qkdl_id': app.backing_qkdl_id,
                            'client_app_id': app.client_app_id
                        } for app in device.qkd_applications.qkd_app]
                    }
                    topology_info['devices'].append(device_info)
                context_info['topologies'].append(topology_info)
            contexts_info.append(context_info)
        
        return contexts_info
    except grpc.RpcError as e:
        app.logger.error(f"gRPC error: {e}")
        abort(502, description=f"gRPC error: {e.details()}")
    except Exception as e:
        app.logger.error(f"Error retrieving context topology info: {e}")
        abort(500, description="Internal Server Error")


def get_detailed_device_info():
    try:
        context_info = get_context_topology_info()
        detailed_info = []
        for context in context_info:
            if context['context_name'] == 'admin':
                for topology in context['topologies']:
                    if topology['topology_name'] == 'admin':
                        for device in topology['devices']:
                            driver = get_driver_instance(device)
                            if driver:
                                detailed_info.append({
                                    'device_info': device,
                                    'driver_info': get_device_driver_info(driver)
                                })
        return detailed_info
    except Exception as e:
        app.logger.error(f"Error retrieving detailed device info: {e}")
        abort(500, description="Internal Server Error")


def get_driver_instance(device):
    device_uuid = device['device_id']
    driver_filter_fields = {
        FilterFieldEnum.DEVICE_TYPE: device['device_type'],
        FilterFieldEnum.DRIVER: device['drivers'],
    }
    connect_rules = {config['key']: config['value'] for config in device['configurations']}
    
    address = connect_rules.get('_connect/address', '127.0.0.1')
    port = int(connect_rules.get('_connect/port', '0'))
    settings = json.loads(connect_rules.get('_connect/settings', '{}'))

    try:
        driver = driver_instance_cache.get(
            device_uuid, filter_fields=driver_filter_fields, address=address, port=port, settings=settings)
        if os.getenv('QKD_API_URL'):  # Assume real QKD system if QKD_API_URL is set
            if not driver.Connect():
                raise Exception("Failed to connect to real QKD system")
        else:
            driver.Connect()
        return driver
    except Exception as e:
        app.logger.error(f"Failed to get driver instance for device {device_uuid}: {e}")
        return None



def get_device_driver_info(driver: _Driver):
    try:
        return {
            'initial_config': driver.GetInitialConfig(),
            'running_config': driver.GetConfig(),
            'subscriptions': list(driver.GetState(blocking=False))
        }
    except Exception as e:
        app.logger.error(f"Failed to retrieve driver information: {e}")
        return {'error': str(e)}


@app.route('/qkd/devices', methods=['GET'])
def retrieve_qkd_devices():
    try:
        context_info = get_context_topology_info()
        return jsonify(context_info), 200
    except Exception as e:
        app.logger.error(f"Error retrieving QKD devices: {e}")
        return jsonify({'error': 'Internal Server Error'}), 500


@app.route('/qkd/capabilities', methods=['GET'])
def get_qkd_capabilities():
    try:
        context_info = get_context_topology_info()
        for context in context_info:
            if context['context_name'] == 'admin':
                for topology in context['topologies']:
                    if topology['topology_name'] == 'admin':
                        for device in topology['devices']:
                            driver = get_driver_instance(device)
                            if driver:
                                capabilities = driver.get_qkd_capabilities()
                                return jsonify(capabilities), 200
        abort(404, description="No capabilities found")
    except Exception as e:
        app.logger.error(f"Error retrieving QKD capabilities: {e}")
        return jsonify({'error': 'Internal Server Error'}), 500


@app.route('/qkd/interfaces', methods=['GET'])
def get_qkd_interfaces():
    try:
        context_info = get_context_topology_info()
        for context in context_info:
            if context['context_name'] == 'admin':
                for topology in context['topologies']:
                    if topology['topology_name'] == 'admin':
                        for device in topology['devices']:
                            driver = get_driver_instance(device)
                            if driver:
                                interfaces = driver.get_qkd_interfaces()
                                return jsonify(interfaces), 200
        abort(404, description="No interfaces found")
    except Exception as e:
        app.logger.error(f"Error retrieving QKD interfaces: {e}")
        return jsonify({'error': 'Internal Server Error'}), 500


@app.route('/qkd/links', methods=['GET'])
def get_qkd_links():
    try:
        context_info = get_context_topology_info()
        for context in context_info:
            if context['context_name'] == 'admin':
                for topology in context['topologies']:
                    if topology['topology_name'] == 'admin':
                        for device in topology['devices']:
                            driver = get_driver_instance(device)
                            if driver:
                                links = driver.get_qkd_links()
                                return jsonify(links), 200
        abort(404, description="No links found")
    except Exception as e:
        app.logger.error(f"Error retrieving QKD links: {e}")
        return jsonify({'error': 'Internal Server Error'}), 500


@app.route('/qkd/applications', methods=['GET'])
def get_qkd_applications():
    try:
        context_info = get_context_topology_info()
        for context in context_info:
            if context['context_name'] == 'admin':
                for topology in context['topologies']:
                    if topology['topology_name'] == 'admin':
                        for device in topology['devices']:
                            driver = get_driver_instance(device)
                            if driver:
                                applications = driver.get_qkd_applications()
                                return jsonify(applications), 200
        abort(404, description="No applications found")
    except Exception as e:
        app.logger.error(f"Error retrieving QKD applications: {e}")
        return jsonify({'error': 'Internal Server Error'}), 500


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
Loading