Loading service-resource-manager-implementation/src/controllers/fm_internal_controller.py 0 → 100644 +372 −0 Original line number Diff line number Diff line import connexion import logging from requests import Response as RequestsResponse from src.controllers.edge_cloud_management_controller import edgecloud_adapter logger = logging.getLogger(__name__) def _normalize_adapter_response(response): if isinstance(response, RequestsResponse): try: data = response.json() except ValueError: data = response.text return data, response.status_code return response def _call_first_available(target, *method_names): for method_name in method_names: method = getattr(target, method_name, None) if method: return method raise AttributeError(f"None of these methods exist on {type(target).__name__}: {method_names}") def _repo_type_to_package_type(repo_data): descriptor_type = (repo_data.get("artefactDescriptorType") or "").upper() virt_type = (repo_data.get("artefactVirtType") or "").upper() if descriptor_type == "HELM": return "HELM" if virt_type == "VM_TYPE": return "VM" return "CONTAINER" def _repo_credentials(repo_location): if not isinstance(repo_location, dict): return {} return { "repoURL": repo_location.get("repoURL"), "userName": repo_location.get("userName") or "", "password": repo_location.get("password") or "", "token": repo_location.get("token") or "", } def _build_app_repo_from_artefact(artefact_data): repo_location = _repo_credentials(artefact_data.get("artefactRepoLocation")) repo_url = repo_location.get("repoURL") image_path = repo_url if repo_url and artefact_data.get("artefactName") and artefact_data.get("artefactVersionInfo"): version = artefact_data.get("artefactVersionInfo") if repo_url.endswith("/"): image_path = f"{repo_url}{artefact_data.get('artefactName')}:{version}" elif "/" in repo_url and not repo_url.endswith(f":{version}"): image_path = f"{repo_url.rstrip('/')}/{artefact_data.get('artefactName')}:{version}" return { "imagePath": image_path, "repoURL": repo_url, "userName": repo_location.get("userName"), "credentials": repo_location.get("password") or repo_location.get("token"), } def _normalize_component_specs(component_specs): normalized_specs = [] for component in component_specs or []: normalized_component = dict(component) network_interfaces = [] for interface in component.get("exposedInterfaces") or []: port = interface.get("commPort") if port is None: continue network_interfaces.append( { "port": port, "protocol": (interface.get("commProtocol") or "TCP").upper(), "visibilityType": interface.get("visibilityType") or "VISIBILITY_EXTERNAL", } ) if network_interfaces: normalized_component["networkInterfaces"] = network_interfaces normalized_specs.append(normalized_component) return normalized_specs def _build_manifest_from_gsma_onboarding(request_data): component_specs = _normalize_component_specs(request_data.get("appComponentSpecs") or []) artefact_id = None if component_specs: artefact_id = component_specs[0].get("artefactId") artefact_data = None if artefact_id: get_artefact_method = _call_first_available( edgecloud_adapter, "get_artefact", "get_artefact_gsma", ) artefact_response = _normalize_adapter_response(get_artefact_method(artefact_id)) if isinstance(artefact_response, tuple): artefact_data, status = artefact_response if status != 200: return artefact_data, status app_meta_data = request_data.get("appMetaData") or {} manifest = { "appId": request_data.get("appId"), "name": app_meta_data.get("appName") or request_data.get("appId"), "appName": app_meta_data.get("appName") or request_data.get("appId"), "version": app_meta_data.get("version") or "1.0.0", "appDescription": app_meta_data.get("appDescription") or "", "appProvider": request_data.get("appProviderId"), "packageType": _repo_type_to_package_type(artefact_data or {}), "appComponentSpecs": component_specs, "appDeploymentZones": [ {"zoneId": zone_id} for zone_id in request_data.get("appDeploymentZones") or [] ], } if artefact_data: manifest["appRepo"] = _build_app_repo_from_artefact(artefact_data) return manifest, 200 def _normalize_onboarding_response(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status == 201: return data, 200 return data, status return normalized def _normalize_delete_response(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status == 204: return "deleted", 200 return data, status return normalized def _build_deploy_request_from_gsma(request_data): zone_info = request_data.get("zoneInfo") or {} zone_id = zone_info.get("zoneId") app_zones = [] if zone_id: app_zones.append({"zoneId": zone_id}) return request_data.get("appId"), app_zones def _build_zone_summary(zone): zone_id = zone.get("zoneId") or zone.get("edgeCloudZoneId") return { "zoneId": zone_id, "edgeCloudRegion": zone.get("edgeCloudRegion", "unknown"), } def _build_zone_details(zone_id, zone): return { "zoneId": zone_id, "edgeCloudRegion": zone.get("edgeCloudRegion", "unknown"), "reservedComputeResources": [], "computeResourceQuotaLimits": [], "flavoursSupported": [ { "flavourId": zone_id, "numCPU": 0, "memorySize": 0, "storageSize": 0, "supportedOSTypes": ["OTHER"], "cpuArchType": "OTHER", "gpu": [], "fpga": 0, "vpu": 0, "hugepages": [], "cpuExclusivity": False, } ], "networkResources": {}, "zoneServiceLevelObjsInfo": {}, } def _extract_onboarded_app(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, dict) and "appManifest" in data: return data["appManifest"], status return data, status return normalized def _extract_deployed_app(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, dict) and "appInstance" in data: return data["appInstance"], status return data, status return normalized def get_zones_list(): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, list): data = [_build_zone_summary(zone) for zone in data] return data, status return normalized def get_zones(): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, list): data = [ _build_zone_details(zone.get("zoneId") or zone.get("edgeCloudZoneId"), zone) for zone in data ] return data, status return normalized def get_zone(zone_id: str): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status for zone in data: current_zone_id = zone.get("zoneId") or zone.get("edgeCloudZoneId") if current_zone_id == zone_id: return _build_zone_details(zone_id, zone), 200 return {"error": "Zone not found"}, 404 return normalized def create_artefact(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 create_artefact_method = _call_first_available( edgecloud_adapter, "create_artefact", "create_artefact_gsma", ) response = create_artefact_method(connexion.request.get_json()) return _normalize_adapter_response(response) def delete_artefact(artefact_id: str): delete_artefact_method = _call_first_available( edgecloud_adapter, "delete_artefact", "delete_artefact_gsma", ) response = delete_artefact_method(artefact_id) return _normalize_delete_response(response) def create_onboarding(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 manifest, status = _build_manifest_from_gsma_onboarding(connexion.request.get_json()) if status != 200: return manifest, status response = edgecloud_adapter.onboard_app(manifest) return _normalize_onboarding_response(response) def get_onboarding(app_id: str): response = edgecloud_adapter.get_onboarded_app(app_id) return _extract_onboarded_app(response) def update_onboarding(app_id: str): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 request_data = connexion.request.get_json() response = edgecloud_adapter.get_onboarded_app(app_id) normalized = _extract_onboarded_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if isinstance(data, dict): if request_data.get("appUpdQoSProfile"): data["appUpdQoSProfile"] = request_data.get("appUpdQoSProfile") if request_data.get("appComponentSpecs"): data["appComponentSpecs"] = _normalize_component_specs(request_data.get("appComponentSpecs")) patch_method = _call_first_available( edgecloud_adapter, "patch_onboarded_app", "patch_onboarded_app_gsma", ) patch_response = patch_method(app_id, data) normalized_patch = _normalize_adapter_response(patch_response) if isinstance(normalized_patch, tuple): patch_data, patch_status = normalized_patch return patch_data, patch_status return normalized_patch return normalized def delete_onboarding(app_id: str): response = edgecloud_adapter.delete_onboarded_app(app_id) return _normalize_delete_response(response) def deploy_app(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 request_data = connexion.request.get_json() app_id, app_zones = _build_deploy_request_from_gsma(request_data) response = edgecloud_adapter.deploy_app(app_id, app_zones) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status >= 400: return data, status if isinstance(data, dict): return { "appInstIdentifier": data.get("appInstanceId"), "zoneID": data.get("edgeCloudZoneId"), }, status return normalized def get_deployed_app(app_id: str, app_instance_id: str, zone_id: str): response = edgecloud_adapter.get_deployed_app(app_instance_id) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if data.get("appId") != app_id or data.get("edgeCloudZoneId") != zone_id: return {"error": "App instance not found"}, 404 return { "appInstanceState": data.get("appInstanceState"), "accesspointInfo": data.get("accesspointInfo", []), }, status return normalized def undeploy_app(app_id: str, app_instance_id: str, zone_id: str): response = edgecloud_adapter.get_deployed_app(app_instance_id) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if data.get("appId") != app_id or data.get("edgeCloudZoneId") != zone_id: return {"error": "App instance not found"}, 404 response = edgecloud_adapter.undeploy_app(app_instance_id) return _normalize_delete_response(response) service-resource-manager-implementation/src/swagger/swagger.yaml +187 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,193 @@ externalDocs: servers: - url: http://vitrualserver:8080/srm/1.0.0 paths: /internal/fm/zones/list: get: tags: - FM Internal summary: Returns GSMA zone list for FM operationId: get_zones_list responses: "200": description: Zone list retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/zones: get: tags: - FM Internal summary: Returns GSMA zone details for FM operationId: get_zones responses: "200": description: Zone details retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/zones/{zone_id}: get: tags: - FM Internal summary: Returns GSMA zone detail by id for FM operationId: get_zone parameters: - name: zone_id in: path required: true schema: type: string responses: "200": description: Zone detail retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/artefacts: post: tags: - FM Internal summary: Create artefact through GSMA adapter operationId: create_artefact responses: "200": description: Artefact created "201": description: Artefact created x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/artefacts/{artefact_id}: delete: tags: - FM Internal summary: Delete artefact through GSMA adapter operationId: delete_artefact parameters: - name: artefact_id in: path required: true schema: type: string responses: "200": description: Artefact deleted "204": description: Artefact deleted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/onboardings: post: tags: - FM Internal summary: Create onboarding through GSMA adapter operationId: create_onboarding responses: "200": description: Onboarding created x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/onboardings/{app_id}: get: tags: - FM Internal summary: Get onboarding through GSMA adapter operationId: get_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding retrieved x-openapi-router-controller: src.controllers.fm_internal_controller patch: tags: - FM Internal summary: Update onboarding through GSMA adapter operationId: update_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding updated x-openapi-router-controller: src.controllers.fm_internal_controller delete: tags: - FM Internal summary: Delete onboarding through GSMA adapter operationId: delete_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding deleted "204": description: Onboarding deleted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/deployments: post: tags: - FM Internal summary: Deploy app through GSMA adapter operationId: deploy_app responses: "202": description: Deployment accepted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/deployments/{app_id}/instances/{app_instance_id}/zones/{zone_id}: get: tags: - FM Internal summary: Get deployed app through GSMA adapter operationId: get_deployed_app parameters: - name: app_id in: path required: true schema: type: string - name: app_instance_id in: path required: true schema: type: string - name: zone_id in: path required: true schema: type: string responses: "200": description: Deployment retrieved x-openapi-router-controller: src.controllers.fm_internal_controller delete: tags: - FM Internal summary: Delete deployed app through GSMA adapter operationId: undeploy_app parameters: - name: app_id in: path required: true schema: type: string - name: app_instance_id in: path required: true schema: type: string - name: zone_id in: path required: true schema: type: string responses: "200": description: Deployment deleted "204": description: Deployment deleted x-openapi-router-controller: src.controllers.fm_internal_controller /node/{node_id}: get: tags: Loading Loading
service-resource-manager-implementation/src/controllers/fm_internal_controller.py 0 → 100644 +372 −0 Original line number Diff line number Diff line import connexion import logging from requests import Response as RequestsResponse from src.controllers.edge_cloud_management_controller import edgecloud_adapter logger = logging.getLogger(__name__) def _normalize_adapter_response(response): if isinstance(response, RequestsResponse): try: data = response.json() except ValueError: data = response.text return data, response.status_code return response def _call_first_available(target, *method_names): for method_name in method_names: method = getattr(target, method_name, None) if method: return method raise AttributeError(f"None of these methods exist on {type(target).__name__}: {method_names}") def _repo_type_to_package_type(repo_data): descriptor_type = (repo_data.get("artefactDescriptorType") or "").upper() virt_type = (repo_data.get("artefactVirtType") or "").upper() if descriptor_type == "HELM": return "HELM" if virt_type == "VM_TYPE": return "VM" return "CONTAINER" def _repo_credentials(repo_location): if not isinstance(repo_location, dict): return {} return { "repoURL": repo_location.get("repoURL"), "userName": repo_location.get("userName") or "", "password": repo_location.get("password") or "", "token": repo_location.get("token") or "", } def _build_app_repo_from_artefact(artefact_data): repo_location = _repo_credentials(artefact_data.get("artefactRepoLocation")) repo_url = repo_location.get("repoURL") image_path = repo_url if repo_url and artefact_data.get("artefactName") and artefact_data.get("artefactVersionInfo"): version = artefact_data.get("artefactVersionInfo") if repo_url.endswith("/"): image_path = f"{repo_url}{artefact_data.get('artefactName')}:{version}" elif "/" in repo_url and not repo_url.endswith(f":{version}"): image_path = f"{repo_url.rstrip('/')}/{artefact_data.get('artefactName')}:{version}" return { "imagePath": image_path, "repoURL": repo_url, "userName": repo_location.get("userName"), "credentials": repo_location.get("password") or repo_location.get("token"), } def _normalize_component_specs(component_specs): normalized_specs = [] for component in component_specs or []: normalized_component = dict(component) network_interfaces = [] for interface in component.get("exposedInterfaces") or []: port = interface.get("commPort") if port is None: continue network_interfaces.append( { "port": port, "protocol": (interface.get("commProtocol") or "TCP").upper(), "visibilityType": interface.get("visibilityType") or "VISIBILITY_EXTERNAL", } ) if network_interfaces: normalized_component["networkInterfaces"] = network_interfaces normalized_specs.append(normalized_component) return normalized_specs def _build_manifest_from_gsma_onboarding(request_data): component_specs = _normalize_component_specs(request_data.get("appComponentSpecs") or []) artefact_id = None if component_specs: artefact_id = component_specs[0].get("artefactId") artefact_data = None if artefact_id: get_artefact_method = _call_first_available( edgecloud_adapter, "get_artefact", "get_artefact_gsma", ) artefact_response = _normalize_adapter_response(get_artefact_method(artefact_id)) if isinstance(artefact_response, tuple): artefact_data, status = artefact_response if status != 200: return artefact_data, status app_meta_data = request_data.get("appMetaData") or {} manifest = { "appId": request_data.get("appId"), "name": app_meta_data.get("appName") or request_data.get("appId"), "appName": app_meta_data.get("appName") or request_data.get("appId"), "version": app_meta_data.get("version") or "1.0.0", "appDescription": app_meta_data.get("appDescription") or "", "appProvider": request_data.get("appProviderId"), "packageType": _repo_type_to_package_type(artefact_data or {}), "appComponentSpecs": component_specs, "appDeploymentZones": [ {"zoneId": zone_id} for zone_id in request_data.get("appDeploymentZones") or [] ], } if artefact_data: manifest["appRepo"] = _build_app_repo_from_artefact(artefact_data) return manifest, 200 def _normalize_onboarding_response(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status == 201: return data, 200 return data, status return normalized def _normalize_delete_response(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status == 204: return "deleted", 200 return data, status return normalized def _build_deploy_request_from_gsma(request_data): zone_info = request_data.get("zoneInfo") or {} zone_id = zone_info.get("zoneId") app_zones = [] if zone_id: app_zones.append({"zoneId": zone_id}) return request_data.get("appId"), app_zones def _build_zone_summary(zone): zone_id = zone.get("zoneId") or zone.get("edgeCloudZoneId") return { "zoneId": zone_id, "edgeCloudRegion": zone.get("edgeCloudRegion", "unknown"), } def _build_zone_details(zone_id, zone): return { "zoneId": zone_id, "edgeCloudRegion": zone.get("edgeCloudRegion", "unknown"), "reservedComputeResources": [], "computeResourceQuotaLimits": [], "flavoursSupported": [ { "flavourId": zone_id, "numCPU": 0, "memorySize": 0, "storageSize": 0, "supportedOSTypes": ["OTHER"], "cpuArchType": "OTHER", "gpu": [], "fpga": 0, "vpu": 0, "hugepages": [], "cpuExclusivity": False, } ], "networkResources": {}, "zoneServiceLevelObjsInfo": {}, } def _extract_onboarded_app(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, dict) and "appManifest" in data: return data["appManifest"], status return data, status return normalized def _extract_deployed_app(response): normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, dict) and "appInstance" in data: return data["appInstance"], status return data, status return normalized def get_zones_list(): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, list): data = [_build_zone_summary(zone) for zone in data] return data, status return normalized def get_zones(): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if isinstance(data, list): data = [ _build_zone_details(zone.get("zoneId") or zone.get("edgeCloudZoneId"), zone) for zone in data ] return data, status return normalized def get_zone(zone_id: str): response = edgecloud_adapter.get_edge_cloud_zones() normalized = _normalize_adapter_response(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status for zone in data: current_zone_id = zone.get("zoneId") or zone.get("edgeCloudZoneId") if current_zone_id == zone_id: return _build_zone_details(zone_id, zone), 200 return {"error": "Zone not found"}, 404 return normalized def create_artefact(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 create_artefact_method = _call_first_available( edgecloud_adapter, "create_artefact", "create_artefact_gsma", ) response = create_artefact_method(connexion.request.get_json()) return _normalize_adapter_response(response) def delete_artefact(artefact_id: str): delete_artefact_method = _call_first_available( edgecloud_adapter, "delete_artefact", "delete_artefact_gsma", ) response = delete_artefact_method(artefact_id) return _normalize_delete_response(response) def create_onboarding(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 manifest, status = _build_manifest_from_gsma_onboarding(connexion.request.get_json()) if status != 200: return manifest, status response = edgecloud_adapter.onboard_app(manifest) return _normalize_onboarding_response(response) def get_onboarding(app_id: str): response = edgecloud_adapter.get_onboarded_app(app_id) return _extract_onboarded_app(response) def update_onboarding(app_id: str): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 request_data = connexion.request.get_json() response = edgecloud_adapter.get_onboarded_app(app_id) normalized = _extract_onboarded_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if isinstance(data, dict): if request_data.get("appUpdQoSProfile"): data["appUpdQoSProfile"] = request_data.get("appUpdQoSProfile") if request_data.get("appComponentSpecs"): data["appComponentSpecs"] = _normalize_component_specs(request_data.get("appComponentSpecs")) patch_method = _call_first_available( edgecloud_adapter, "patch_onboarded_app", "patch_onboarded_app_gsma", ) patch_response = patch_method(app_id, data) normalized_patch = _normalize_adapter_response(patch_response) if isinstance(normalized_patch, tuple): patch_data, patch_status = normalized_patch return patch_data, patch_status return normalized_patch return normalized def delete_onboarding(app_id: str): response = edgecloud_adapter.delete_onboarded_app(app_id) return _normalize_delete_response(response) def deploy_app(): if not connexion.request.is_json: return {"error": "Wrong request schema"}, 400 request_data = connexion.request.get_json() app_id, app_zones = _build_deploy_request_from_gsma(request_data) response = edgecloud_adapter.deploy_app(app_id, app_zones) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status >= 400: return data, status if isinstance(data, dict): return { "appInstIdentifier": data.get("appInstanceId"), "zoneID": data.get("edgeCloudZoneId"), }, status return normalized def get_deployed_app(app_id: str, app_instance_id: str, zone_id: str): response = edgecloud_adapter.get_deployed_app(app_instance_id) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if data.get("appId") != app_id or data.get("edgeCloudZoneId") != zone_id: return {"error": "App instance not found"}, 404 return { "appInstanceState": data.get("appInstanceState"), "accesspointInfo": data.get("accesspointInfo", []), }, status return normalized def undeploy_app(app_id: str, app_instance_id: str, zone_id: str): response = edgecloud_adapter.get_deployed_app(app_instance_id) normalized = _extract_deployed_app(response) if isinstance(normalized, tuple): data, status = normalized if status != 200: return data, status if data.get("appId") != app_id or data.get("edgeCloudZoneId") != zone_id: return {"error": "App instance not found"}, 404 response = edgecloud_adapter.undeploy_app(app_instance_id) return _normalize_delete_response(response)
service-resource-manager-implementation/src/swagger/swagger.yaml +187 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,193 @@ externalDocs: servers: - url: http://vitrualserver:8080/srm/1.0.0 paths: /internal/fm/zones/list: get: tags: - FM Internal summary: Returns GSMA zone list for FM operationId: get_zones_list responses: "200": description: Zone list retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/zones: get: tags: - FM Internal summary: Returns GSMA zone details for FM operationId: get_zones responses: "200": description: Zone details retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/zones/{zone_id}: get: tags: - FM Internal summary: Returns GSMA zone detail by id for FM operationId: get_zone parameters: - name: zone_id in: path required: true schema: type: string responses: "200": description: Zone detail retrieved x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/artefacts: post: tags: - FM Internal summary: Create artefact through GSMA adapter operationId: create_artefact responses: "200": description: Artefact created "201": description: Artefact created x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/artefacts/{artefact_id}: delete: tags: - FM Internal summary: Delete artefact through GSMA adapter operationId: delete_artefact parameters: - name: artefact_id in: path required: true schema: type: string responses: "200": description: Artefact deleted "204": description: Artefact deleted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/onboardings: post: tags: - FM Internal summary: Create onboarding through GSMA adapter operationId: create_onboarding responses: "200": description: Onboarding created x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/onboardings/{app_id}: get: tags: - FM Internal summary: Get onboarding through GSMA adapter operationId: get_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding retrieved x-openapi-router-controller: src.controllers.fm_internal_controller patch: tags: - FM Internal summary: Update onboarding through GSMA adapter operationId: update_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding updated x-openapi-router-controller: src.controllers.fm_internal_controller delete: tags: - FM Internal summary: Delete onboarding through GSMA adapter operationId: delete_onboarding parameters: - name: app_id in: path required: true schema: type: string responses: "200": description: Onboarding deleted "204": description: Onboarding deleted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/deployments: post: tags: - FM Internal summary: Deploy app through GSMA adapter operationId: deploy_app responses: "202": description: Deployment accepted x-openapi-router-controller: src.controllers.fm_internal_controller /internal/fm/deployments/{app_id}/instances/{app_instance_id}/zones/{zone_id}: get: tags: - FM Internal summary: Get deployed app through GSMA adapter operationId: get_deployed_app parameters: - name: app_id in: path required: true schema: type: string - name: app_instance_id in: path required: true schema: type: string - name: zone_id in: path required: true schema: type: string responses: "200": description: Deployment retrieved x-openapi-router-controller: src.controllers.fm_internal_controller delete: tags: - FM Internal summary: Delete deployed app through GSMA adapter operationId: undeploy_app parameters: - name: app_id in: path required: true schema: type: string - name: app_instance_id in: path required: true schema: type: string - name: zone_id in: path required: true schema: type: string responses: "200": description: Deployment deleted "204": description: Deployment deleted x-openapi-router-controller: src.controllers.fm_internal_controller /node/{node_id}: get: tags: Loading