Commit a89fb9a7 authored by Paris Stentoumis's avatar Paris Stentoumis
Browse files

feature: added piedge support for artefact onboarding

fix: fixed the response.content of some functions causing errors, changed zone details to cover requirements
parent be5d6cee
Loading
Loading
Loading
Loading
+61 −10
Original line number Diff line number Diff line
# Mocked API for testing purposes
import logging
import json
from typing import Dict, List, Optional

from kubernetes.client import V1Deployment
@@ -9,6 +10,7 @@ from sunrise6g_opensdk.edgecloud.core import gsma_schemas
from sunrise6g_opensdk.edgecloud.adapters.kubernetes.lib.core.piedge_encoder import (
    deploy_service_function,
)
from sunrise6g_opensdk.edgecloud.adapters.kubernetes.lib.models.ArtefactOnboarding import ArtefactOnboarding
from sunrise6g_opensdk.edgecloud.adapters.kubernetes.lib.models.app_manifest import (
    AppManifest,
)
@@ -442,11 +444,12 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
            zone = {}
            zone["zoneId"] = node.get("uid")
            zone["geographyDetails"] = node.get("location")
            zone["geolocation"] = node.get("geolocation")
            zone_list.append(zone)
        validated_data = gsma_schemas.ZonesList.model_validate(zone_list)
        return build_custom_http_response(
                status_code=200,
                content=[zone.model_dump_json() for zone in validated_data.root],
                content=[zone.model_dump() for zone in validated_data.root],
                headers={"Content-Type": 'application/json'},
                encoding="utf-8",
                url=None,
@@ -499,7 +502,7 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
        validated_data = gsma_schemas.ZoneRegisteredData.model_validate(gsma_zone_details)
        return build_custom_http_response(
                status_code=200,
                content=validated_data,
                content=validated_data.model_dump(),
                headers={"Content-Type": "application/json"},
                encoding="utf-8",
                url=None,
@@ -517,6 +520,28 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
        :param request_body: Payload with artefact information.
        :return:
        """

        repo_data = request_body["artefactRepoLocation"]
        artefact = ArtefactOnboarding(
            artefact_id=request_body["artefactId"],
            name=request_body["artefactName"],
            repo_name=repo_data.get("repoName", ""),
            repo_type=request_body.get("repoType"),
            repo_url=repo_data["repoURL"],
            repo_user_name=repo_data.get("userName"),
            repo_password=repo_data.get("password"),
            repo_token=repo_data.get("token"),
        )

        self.connector_db.insert_document_artefact(artefact)
        return build_custom_http_response(
                status_code=200,
                content=None,
                headers={"Content-Type": "application/json"},
                encoding="utf-8",
                url=None,
                request=None,
        )    
        pass

    def get_artefact_gsma(self, artefact_id: str) -> Dict:
@@ -606,13 +631,17 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
        repo_url = artefact.get("orig_am_artefact_repo_location_repo_url")
        image_name = artefact.get("orig_am_artefact_name")
        image_tag = artefact.get("orig_am_artefact_version_info") or "latest"
        component_spec = json.loads(artefact.get("orig_am_component_spec"))
        port = []
        exposed_interface = component_spec[0].get("orig_ce_component_spec_exposed_interfaces")[0]
        port.append(exposed_interface.get("orig_ei_comm_port"))
        
        insert_doc = ServiceFunctionRegistrationRequest(
            service_function_id=app_id,
            service_function_image=repo_url + "/" + image_name + ":" + image_tag,
            service_function_name=app_name,
            service_function_type="package_type",
            application_ports= [],
            application_ports= port,
            required_resources= RequiredResources(),
            app_provider=app_provider_id,
            version=version,
@@ -760,7 +789,7 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
                    "appInstIdentifier": deployment_uid,
                }

                validated = gsma_schemas.AppInstanceCreatedResponse.model_validate(response)
                validated = gsma_schemas.AppInstance.model_validate(response)

                return build_custom_http_response(
                    status_code=202,
@@ -899,6 +928,14 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
            }
            return build_custom_http_response(500, error)
        
    def __map_k8s_arch_gsma(self, arch: str):
        mapping_set = {
            "amd64": "ISA_X86_64",
            "arm64": "ISA_ARM_64",
            "386": "ISA_X86"
        }
        return mapping_set[arch]

    def __get_zone_details_gsma(self, node_details):
        gsma_details = {}
        labels = node_details.get("metadata").get("labels")
@@ -906,24 +943,38 @@ class EdgeApplicationManager(EdgeCloudManagementInterface):
        arch_type = labels.get("beta.kubernetes.io/arch")
        computeResourceQuotaLimits = [
            {
                "cpuArchType": arch_type,
                "cpuArchType": self.__map_k8s_arch_gsma(arch_type),
                "numCPU": status.get("capacity").get("cpu"),
                "memory": status.get("capacity").get("memory"),
                "memory": status.get("capacity").get("memory")[:-2],
                # "memory": int(status.get("capacity").get("memory")) / (1024 * 1024),
            }
        ]
        reservedComputeResources = [
            {
                "cpuArchType": arch_type,
                "cpuArchType": self.__map_k8s_arch_gsma(arch_type),
                "numCPU": status.get("allocatable").get("cpu"),
                "memory": status.get("allocatable").get("memory"),
                "memory": status.get("allocatable").get("memory")[:-2],
                # "memory": int(status.get("allocatable").get("memory")) / (1024 * 1024),
            }
        ]
        flavoursSupported = []
        flavoursSupported = [
            {
                "flavourId": "default",
                "cpuArchType": self.__map_k8s_arch_gsma(arch_type),
                "supportedOSTypes": [{
                    "architecture": "x86_64",
                    "distribution": "UBUNTU",
                    "version": "OS_VERSION_UBUNTU_2204_LTS",
                    "license": "NOT_SPECIFIED"
                }],
                "numCPU": status.get("capacity").get("cpu"),
                "memorySize": status.get("capacity").get("memory")[:-2],
                "storageSize": 0,
            }
        ]
        gsma_details["computeResourceQuotaLimits"] = computeResourceQuotaLimits
        gsma_details["reservedComputeResources"] = reservedComputeResources
        gsma_details["flavoursSupported"] = flavoursSupported
        gsma_details["networkResources"] = {"egressBandWidth": 0, "dedicatedNIC": 0, "supportSriov": False,"supportDPDK": False}
        gsma_details["zoneServiceLevelObjsInfo"] = {"latencyRanges": {"minLatency": 0,"maxLatency": 0}, "jitterRanges": {"minJitter": 0,"maxJitter": 0}, "throughputRanges": {"minThroughput": 0, "maxThroughput": 0}}
        gsma_details["zoneServiceLevelObjsInfo"] = {"latencyRanges": {"minLatency": 1,"maxLatency": 1}, "jitterRanges": {"minJitter": 1,"maxJitter": 1}, "throughputRanges": {"minThroughput": 1, "maxThroughput": 1}}
        return gsma_details
+20 −0
Original line number Diff line number Diff line
from enum import Enum
from pydantic import BaseModel, ConfigDict
from typing import Optional

class RepoType(str, Enum):
    UPLOAD = "UPLOAD"
    PUBLICREPO = "PUBLICREPO"
    PRIVATEREPO = "PRIVATEREPO"
    
class ArtefactOnboarding(BaseModel):
    artefact_id: str
    name: str
    # chart: Optional[bytes] = Field(default=None) # XXX AFAIK not supported by CAMARA.
    repo_password: Optional[str] = None
    repo_name: Optional[str] = None
    repo_type: RepoType
    repo_url: Optional[str] = None
    repo_token: Optional[str] = None
    repo_user_name: Optional[str] = None
    model_config = ConfigDict(use_enum_values=True)
 No newline at end of file
+17 −0
Original line number Diff line number Diff line
@@ -251,6 +251,23 @@ class ConnectorDB:
        except Exception as ce_:
            raise Exception("An exception occurred :", ce_)     
    
    
    def insert_document_artefact(self, document=None, _id=None):
        collection = "artefacts"
        myclient = pymongo.MongoClient(self._storage_url)
        mydbmongo = myclient[self.mydb_mongo]
        mycol = mydbmongo[collection]

        myquery = {"artefact_id": document.artefact_id}
        mydoc = mycol.find_one(myquery)
        # keeps the last record (contains registrationStatus)
        if mydoc is not None:
            return ("Already Registered: Artefact id", document.artefact_id)
        try:
            mycol.insert_one(document.model_dump())
        except Exception as ce_:
            raise Exception("An exception occurred :", ce_)

    def get_documents_from_collection(
        self, collection_input, input_type=None, input_value=None
    ) -> List[dict]:
+1 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ class KubernetesConnector:
                pop_["name"] = node.metadata.name
                pop_["uid"] = node.metadata.uid
                pop_["location"] = node.metadata.labels.get("location") or ""
                pop_["geolocation"] = node.metadata.labels.get("geolocation") or ""
                pop_["serial"] = node.status.addresses[0].address
                pop_["node_type"] = node.metadata.labels.get("node_type") or ""
                pop_["status"] = (