Loading edge_cloud_management_api/controllers/app_controllers.py +68 −11 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ from flask import jsonify, request from pydantic import ValidationError from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory from edge_cloud_management_api.services.storage_service import get_zone from edge_cloud_management_api.services.storage_service import get_fed factory = FederationManagerClientFactory() federation_client = factory.create_federation_client() class NotFound404Exception(Exception): pass Loading Loading @@ -87,28 +90,82 @@ def delete_app(appId, x_correlator=None): def create_app_instance(): logger.info("Received request to create app instance") try: body = request.get_json() logger.debug(f"Request body: {body}") app_id = body.get("appId") app_zones = body.get("appZones") # k8s_ref = body.get("kubernetesClusterRef") pi_edge_client_factory = PiEdgeAPIClientFactory() pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client() if not app_id or not app_zones : return jsonify({"error": "Missing required fields: appId, edgeCloudZoneId, or kubernetesCLusterRef"}), 400 local_zone = get_zone(app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId')) if not local_zone: # TODO: apply federation logic return 'Zone belongs to federated partner OP. Switching to Federation Manager.' zone = get_zone(app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId')) if zone.get('isLocal')=='false': # Step 1: retrieve app metadata appData = pi_edge_client.get_app(appId=app_id).get('appManifest') #Step 2: compose GSMA artefact payload artefact = {} artefact['artefactId'] = app_id artefact['appProviderId'] = appData.get('appProvider') artefact['artefactName'] = appData.get('name') artefact['artefactVersionInfo'] = appData.get('version') artefact['artefactDescription'] = '' repoInfo = appData.get('appRepo') artefact['repoType'] = repoInfo.get('type') artefact['artefactRepoLocation'] = {'repoURL': repoInfo.get('imagePath'), 'userName': repoInfo.get('userName'), 'password': repoInfo.get('credentials'), 'token': ''} exposedInterfaces = [] networkInterfaces = appData.get('componentSpec')[0].get('networkInterfaces') for ni in networkInterfaces: interface = {'interfaceId': '', 'commProtocol': ni.get('protocol'), 'commPort': ni.get('port'), 'visibilityType': ni.get('visibilityType'), 'network': '', 'InterfaceName': ''} exposedInterfaces.append(interface) artefact['componentSpec'] = [ { 'componentName': appData.get('name'), 'numOfInstances': 0, 'restartPolicy': 'RESTART_POLICY_ALWAYS', 'exposedInterfaces': exposedInterfaces, 'compEnvParams': [], 'persistentVolumes': [] } ] # Step 3: Send artefact to local fed manager fed_token = get_fed(zone.get('fedContextId')).get('token') create_artefact_response = federation_client.create_artefact(artefact=artefact, federation_context_id=zone.get('fedContextId'), token=fed_token) # Step 4: Onboard app if create_artefact_response.status_code == 200 or create_artefact_response.status_code ==409: # Step 5: Create GSM onboard app payload onboard_app = {} onboard_app['appId'] = app_id onboard_app['appProviderId'] = appData.get('appProvider') onboard_app['appDeploymentZones'] = [] appMetaData = {} appMetaData['appName'] = appData.get('name') appMetaData['version'] = appData.get('version') onboard_app['appMetaData'] = appMetaData onboard_app['appComponentSpecs'] = [{'serviceNameNB': appData.get('name'), 'serviceNameEW': appData.get('name'), 'componentName': appData.get('name'), 'artefactId': app_id } ] # Step 6: Onboard app at partner onboard_app_response = federation_client.onboard_application(federation_context_id=zone.get('fedContextId'), body=onboard_app, token=fed_token) if onboard_app_response.status_code==200: # Step 7: Construct GSMA deployment payload deploy_app = {} deploy_app['appId'] = app_id deploy_app['appVersion'] = appData.get('version') deploy_app['appProviderId'] = appData.get('appProvider') deploy_app['zoneInfo'] = {'zoneId': zone.get('edgeCloudZoneId')} # Step 8: Deploy app at partner deploy_app_response = federation_client.deploy_app_partner(federation_context_id=zone.get('fedContextId'), body=deploy_app, token = fed_token) return deploy_app_response logger.info(f"Preparing to send deployment request to SRM for appId={app_id}") pi_edge_client_factory = PiEdgeAPIClientFactory() pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client() logger.info(f"Preparing to send deployment request to SRM for appId={app_id}") print("\n === Preparing Deployment Request ===") print(f" Endpoint: {pi_edge_client.base_url}/deployedServiceFunction") Loading edge_cloud_management_api/controllers/edge_cloud_controller.py +5 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.storage_service import insert_zones from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory try: Loading @@ -13,10 +14,14 @@ try: zones = api_client.edge_cloud_zones() for zone in zones: zone['_id'] = zone.get('edgeCloudZoneId') zone['isLocal'] = 'true' insert_zones(zones) except Exception as e: logger.error(e.args) factory = FederationManagerClientFactory() federation_client = factory.create_federation_client() class EdgeCloudZone(BaseModel): edgeCloudZoneId: str = Field(..., description="Unique identifier of the Edge Cloud Zone") edgeCloudZoneName: str = Field(..., description="Name of the Edge Cloud Zone") Loading edge_cloud_management_api/controllers/federation_manager_controller.py +15 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from requests.exceptions import Timeout, ConnectionError from edge_cloud_management_api.managers.log_manager import logger import requests from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.services.storage_service import insert_zones from edge_cloud_management_api.services.storage_service import insert_federation, get_fed, get_all_feds from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory Loading @@ -30,6 +31,20 @@ def create_federation(): response, code = federation_client.post_partner(body, token) fed = {'_id': response.get('federationContextId'), 'token': token} if code==200: provider = response.get('partnerOPFederationId') av_zones = response.get('offeredAvailabilityZones') zones_to_insert = [] for zone in av_zones: inserted_item = {'_id': zone.get('zoneId'), 'edgeCloudProvider': provider, 'edgeCloudZoneId': zone.get('zoneId'), 'edgeCloudZoneName': zone.get('geographyDetails'), 'edgeCloudZoneStatus': 'unknown', 'isLocal': 'false', 'fedContextId': response.get('federationContextId') } zones_to_insert.append(inserted_item) insert_zones(zones_to_insert) insert_federation(fed) return response, code Loading edge_cloud_management_api/services/federation_services.py +21 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ from requests.exceptions import Timeout, ConnectionError from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.storage_service import delete_fed from edge_cloud_management_api.services.storage_service import delete_fed, delete_partner_zones class FederationManagerClient: def __init__(self, base_url=None): Loading Loading @@ -71,6 +71,7 @@ class FederationManagerClient: response = requests.delete(url, headers=self._get_headers(token), timeout=10) if response.content: delete_fed(federation_context_id) delete_partner_zones() return response.json(), 200 return {"status": response.status_code} except Timeout: Loading Loading @@ -110,7 +111,7 @@ class FederationManagerClient: def onboard_application(self, federation_context_id: str, body: dict, token: str): url = f"{self.base_url}/{federation_context_id}/application/onboarding" try: response = requests.post(url, headers=self._get_headers(), json=body, timeout=10) response = requests.post(url, headers=self._get_headers(token), json=body, timeout=10) response.raise_for_status() return response.json() except Timeout: Loading Loading @@ -167,6 +168,14 @@ class FederationManagerClient: '''---PARTNER APP DEPLOYMENT---''' def deploy_app_partner(self, federation_context_id: str, body: dict, token: str): url = f"{self.base_url}/{federation_context_id}/application/lcm" try: response = requests.post(url, headers=self._get_headers(token), json=body, timeout=10) return response except Exception as e: logger.error(f"DELETE onboarding app unexpected error: {e}") return {"error": str(e), "status_code": 500} '''---AVAILABILITY ZONE INFO SYNCHRONIZATION---''' Loading Loading @@ -227,6 +236,16 @@ class FederationManagerClient: logger.error(f"Remove Zone sync unexpected error: {e}") return {"error": str(e), "status_code": 500} '''---ARTEFACT API---''' def create_artefact(self, artefact: dict, federation_context_id, token: str): url = f"{self.base_url}/{federation_context_id}/artefact" try: response = requests.post(url, headers=self._get_headers(token), json=artefact, timeout=10) return response except Exception as e: logger.error(f"Create artefact unexpected error: {e}") return {"error": str(e), "status_code": 500} class FederationManagerClientFactory: def __init__(self): Loading edge_cloud_management_api/services/storage_service.py +7 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,13 @@ def get_zone(zone_id: str): zone = col.find_one({'_id': zone_id}) return zone def delete_partner_zones(): collection = "zones" myclient = pymongo.MongoClient(storage_url) mydbmongo = myclient[mydb_mongo] col = mydbmongo[collection] col.delete_many({'isLocal': 'false'}) def insert_federation(fed: dict): collection = 'federations' myclient = pymongo.MongoClient(storage_url) Loading Loading
edge_cloud_management_api/controllers/app_controllers.py +68 −11 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ from flask import jsonify, request from pydantic import ValidationError from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory from edge_cloud_management_api.services.storage_service import get_zone from edge_cloud_management_api.services.storage_service import get_fed factory = FederationManagerClientFactory() federation_client = factory.create_federation_client() class NotFound404Exception(Exception): pass Loading Loading @@ -87,28 +90,82 @@ def delete_app(appId, x_correlator=None): def create_app_instance(): logger.info("Received request to create app instance") try: body = request.get_json() logger.debug(f"Request body: {body}") app_id = body.get("appId") app_zones = body.get("appZones") # k8s_ref = body.get("kubernetesClusterRef") pi_edge_client_factory = PiEdgeAPIClientFactory() pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client() if not app_id or not app_zones : return jsonify({"error": "Missing required fields: appId, edgeCloudZoneId, or kubernetesCLusterRef"}), 400 local_zone = get_zone(app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId')) if not local_zone: # TODO: apply federation logic return 'Zone belongs to federated partner OP. Switching to Federation Manager.' zone = get_zone(app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId')) if zone.get('isLocal')=='false': # Step 1: retrieve app metadata appData = pi_edge_client.get_app(appId=app_id).get('appManifest') #Step 2: compose GSMA artefact payload artefact = {} artefact['artefactId'] = app_id artefact['appProviderId'] = appData.get('appProvider') artefact['artefactName'] = appData.get('name') artefact['artefactVersionInfo'] = appData.get('version') artefact['artefactDescription'] = '' repoInfo = appData.get('appRepo') artefact['repoType'] = repoInfo.get('type') artefact['artefactRepoLocation'] = {'repoURL': repoInfo.get('imagePath'), 'userName': repoInfo.get('userName'), 'password': repoInfo.get('credentials'), 'token': ''} exposedInterfaces = [] networkInterfaces = appData.get('componentSpec')[0].get('networkInterfaces') for ni in networkInterfaces: interface = {'interfaceId': '', 'commProtocol': ni.get('protocol'), 'commPort': ni.get('port'), 'visibilityType': ni.get('visibilityType'), 'network': '', 'InterfaceName': ''} exposedInterfaces.append(interface) artefact['componentSpec'] = [ { 'componentName': appData.get('name'), 'numOfInstances': 0, 'restartPolicy': 'RESTART_POLICY_ALWAYS', 'exposedInterfaces': exposedInterfaces, 'compEnvParams': [], 'persistentVolumes': [] } ] # Step 3: Send artefact to local fed manager fed_token = get_fed(zone.get('fedContextId')).get('token') create_artefact_response = federation_client.create_artefact(artefact=artefact, federation_context_id=zone.get('fedContextId'), token=fed_token) # Step 4: Onboard app if create_artefact_response.status_code == 200 or create_artefact_response.status_code ==409: # Step 5: Create GSM onboard app payload onboard_app = {} onboard_app['appId'] = app_id onboard_app['appProviderId'] = appData.get('appProvider') onboard_app['appDeploymentZones'] = [] appMetaData = {} appMetaData['appName'] = appData.get('name') appMetaData['version'] = appData.get('version') onboard_app['appMetaData'] = appMetaData onboard_app['appComponentSpecs'] = [{'serviceNameNB': appData.get('name'), 'serviceNameEW': appData.get('name'), 'componentName': appData.get('name'), 'artefactId': app_id } ] # Step 6: Onboard app at partner onboard_app_response = federation_client.onboard_application(federation_context_id=zone.get('fedContextId'), body=onboard_app, token=fed_token) if onboard_app_response.status_code==200: # Step 7: Construct GSMA deployment payload deploy_app = {} deploy_app['appId'] = app_id deploy_app['appVersion'] = appData.get('version') deploy_app['appProviderId'] = appData.get('appProvider') deploy_app['zoneInfo'] = {'zoneId': zone.get('edgeCloudZoneId')} # Step 8: Deploy app at partner deploy_app_response = federation_client.deploy_app_partner(federation_context_id=zone.get('fedContextId'), body=deploy_app, token = fed_token) return deploy_app_response logger.info(f"Preparing to send deployment request to SRM for appId={app_id}") pi_edge_client_factory = PiEdgeAPIClientFactory() pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client() logger.info(f"Preparing to send deployment request to SRM for appId={app_id}") print("\n === Preparing Deployment Request ===") print(f" Endpoint: {pi_edge_client.base_url}/deployedServiceFunction") Loading
edge_cloud_management_api/controllers/edge_cloud_controller.py +5 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.storage_service import insert_zones from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory try: Loading @@ -13,10 +14,14 @@ try: zones = api_client.edge_cloud_zones() for zone in zones: zone['_id'] = zone.get('edgeCloudZoneId') zone['isLocal'] = 'true' insert_zones(zones) except Exception as e: logger.error(e.args) factory = FederationManagerClientFactory() federation_client = factory.create_federation_client() class EdgeCloudZone(BaseModel): edgeCloudZoneId: str = Field(..., description="Unique identifier of the Edge Cloud Zone") edgeCloudZoneName: str = Field(..., description="Name of the Edge Cloud Zone") Loading
edge_cloud_management_api/controllers/federation_manager_controller.py +15 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from requests.exceptions import Timeout, ConnectionError from edge_cloud_management_api.managers.log_manager import logger import requests from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.services.storage_service import insert_zones from edge_cloud_management_api.services.storage_service import insert_federation, get_fed, get_all_feds from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory Loading @@ -30,6 +31,20 @@ def create_federation(): response, code = federation_client.post_partner(body, token) fed = {'_id': response.get('federationContextId'), 'token': token} if code==200: provider = response.get('partnerOPFederationId') av_zones = response.get('offeredAvailabilityZones') zones_to_insert = [] for zone in av_zones: inserted_item = {'_id': zone.get('zoneId'), 'edgeCloudProvider': provider, 'edgeCloudZoneId': zone.get('zoneId'), 'edgeCloudZoneName': zone.get('geographyDetails'), 'edgeCloudZoneStatus': 'unknown', 'isLocal': 'false', 'fedContextId': response.get('federationContextId') } zones_to_insert.append(inserted_item) insert_zones(zones_to_insert) insert_federation(fed) return response, code Loading
edge_cloud_management_api/services/federation_services.py +21 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ from requests.exceptions import Timeout, ConnectionError from edge_cloud_management_api.configs.env_config import config from edge_cloud_management_api.managers.log_manager import logger from edge_cloud_management_api.services.edge_cloud_services import PiEdgeAPIClientFactory from edge_cloud_management_api.services.storage_service import delete_fed from edge_cloud_management_api.services.storage_service import delete_fed, delete_partner_zones class FederationManagerClient: def __init__(self, base_url=None): Loading Loading @@ -71,6 +71,7 @@ class FederationManagerClient: response = requests.delete(url, headers=self._get_headers(token), timeout=10) if response.content: delete_fed(federation_context_id) delete_partner_zones() return response.json(), 200 return {"status": response.status_code} except Timeout: Loading Loading @@ -110,7 +111,7 @@ class FederationManagerClient: def onboard_application(self, federation_context_id: str, body: dict, token: str): url = f"{self.base_url}/{federation_context_id}/application/onboarding" try: response = requests.post(url, headers=self._get_headers(), json=body, timeout=10) response = requests.post(url, headers=self._get_headers(token), json=body, timeout=10) response.raise_for_status() return response.json() except Timeout: Loading Loading @@ -167,6 +168,14 @@ class FederationManagerClient: '''---PARTNER APP DEPLOYMENT---''' def deploy_app_partner(self, federation_context_id: str, body: dict, token: str): url = f"{self.base_url}/{federation_context_id}/application/lcm" try: response = requests.post(url, headers=self._get_headers(token), json=body, timeout=10) return response except Exception as e: logger.error(f"DELETE onboarding app unexpected error: {e}") return {"error": str(e), "status_code": 500} '''---AVAILABILITY ZONE INFO SYNCHRONIZATION---''' Loading Loading @@ -227,6 +236,16 @@ class FederationManagerClient: logger.error(f"Remove Zone sync unexpected error: {e}") return {"error": str(e), "status_code": 500} '''---ARTEFACT API---''' def create_artefact(self, artefact: dict, federation_context_id, token: str): url = f"{self.base_url}/{federation_context_id}/artefact" try: response = requests.post(url, headers=self._get_headers(token), json=artefact, timeout=10) return response except Exception as e: logger.error(f"Create artefact unexpected error: {e}") return {"error": str(e), "status_code": 500} class FederationManagerClientFactory: def __init__(self): Loading
edge_cloud_management_api/services/storage_service.py +7 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,13 @@ def get_zone(zone_id: str): zone = col.find_one({'_id': zone_id}) return zone def delete_partner_zones(): collection = "zones" myclient = pymongo.MongoClient(storage_url) mydbmongo = myclient[mydb_mongo] col = mydbmongo[collection] col.delete_many({'isLocal': 'false'}) def insert_federation(fed: dict): collection = 'federations' myclient = pymongo.MongoClient(storage_url) Loading