diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..cdd823e64e7e91ae85da84f22410ecb7eb370ae2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,72 @@ +.travis.yaml +.swagger-codegen-ignore +README.md +tox.ini +git_push.sh +test-requirements.txt +setup.py + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000000000000000000000000000000000000..287e8f77ca939e9ba21e8cb577deff2da27f7d8c --- /dev/null +++ b/.env.sample @@ -0,0 +1,4 @@ +PI_EDGE_BASE_URL=http://example.com/api +PI_EDGE_USERNAME=username +PI_EDGE_PASSWORD=password +HTTP_PROXY=https://company.proxy:3128 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cd1e1f706806c5d855b074867b08626ca0a5f448 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.python-version + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints + +# virtual environment folders +.venv + +# environment +.env + +# code editors +.vscode/ \ No newline at end of file diff --git a/.swagger-codegen-ignore b/.swagger-codegen-ignore new file mode 100644 index 0000000000000000000000000000000000000000..c5fa491b4c557bf997d5dd21797de782545dc9e5 --- /dev/null +++ b/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/.swagger-codegen/VERSION b/.swagger-codegen/VERSION new file mode 100644 index 0000000000000000000000000000000000000000..eefcac2bd9a659c96e0fef356a30bd8f9cc51bca --- /dev/null +++ b/.swagger-codegen/VERSION @@ -0,0 +1 @@ +3.0.63 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..7b21730d595d4e96c7f6fcc4787d6abb3df53ebf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +# ref: https://docs.travis-ci.com/user/languages/python +language: python +python: + - "3.10" + - "3.11" + - "3.12" +install: "pip install -r requirements.txt" +# command to run tests +script: nosetests diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..3679b6f84bf15ab60cf12f71ca059a7810d2dc52 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.12-alpine + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY requirements.txt /usr/src/app/ + +RUN pip3 install --no-cache-dir --trusted-host pypi.org --trusted-host files.pythonhosted.org -r requirements.txt + +COPY . /usr/src/app + +EXPOSE 8080 + +ENTRYPOINT ["python3"] + +CMD ["-m", "swagger_server"] \ No newline at end of file diff --git a/README.md b/README.md index 23b9cc984c22751411cf5fd8c11bac37f145f339..b8a0e16af6ecbf089505d2cf26c88df2f7e8c4cc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,49 @@ -# capabilities-exposure-api -CAMARA compliant Capabilities Exposure API +# Capabilities Exposure API Server + +A Server Implementation of the **CAMARA Edge Application Management API** as specified [here](https://github.com/camaraproject/EdgeCloud/blob/main/code/API_definitions/Edge-Application-Management.yaml) + + +### Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. +It uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask. +It propagates requests to the [Sunrise 6G OP service resource manager](https://github.com/SMARTECH-ISI-Athena/Sunrise-6G-Operator-Platform), as configured in the `.env`. + +### Usage +Before running the server you need to `mv env.sample .env` and update variables to properly link to a running OP service resource manager instance. + +To run the server, please execute the following from the root directory: + +``` +pip3 install -r requirements.txt +python3 -m swagger_server +``` + +and open your browser to the OpenAPI documentation: + +``` +http://localhost:8080/edge-application-management/ui/ +``` + +Your OpenAPI definition lives here: + +``` +http://localhost:8080/edge-application-management/openapi.json +``` + +To launch the integration tests, use tox: +``` +sudo pip install tox +tox +``` + +### Running with Docker + +To run the server on a Docker container, please execute the following from the root directory: + +```bash +# building the image +docker build -t swagger_server . + +# starting up a container +docker run -p 8080:8080 swagger_server +``` \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..636defbd813fad4884179c0b0051b063dfe5082a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +connexion >= 2.6.0 +connexion[swagger-ui] >= 2.6.0 +python_dateutil == 2.6.0 +setuptools >= 21.0.0 +swagger-ui-bundle >= 0.0.2 +python-dotenv == 1.0.1 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..0373c59fc1540b99fb98b2cf4f4737dc080aec22 --- /dev/null +++ b/setup.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +import sys +from setuptools import setup, find_packages + +NAME = "swagger_server" +VERSION = "1.0.0" +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = [ + "connexion", + "swagger-ui-bundle>=0.0.2" +] + +setup( + name=NAME, + version=VERSION, + description="Capabilities Exposure API Server", + author_email="dkaragkounis@intracom-telecom.com", + url="", + keywords=["Swagger", "Capabilities Exposure API Server"], + install_requires=REQUIRES, + packages=find_packages(), + package_data={'': ['swagger/swagger.yaml']}, + include_package_data=True, + entry_points={ + 'console_scripts': ['swagger_server=swagger_server.__main__:main']}, + long_description="""\ + The Capabilities Exposure API Server allows API consumers (Application Providers) to manage the Life Cycle of an Application and to Discover Edge Cloud Zones. + """ +) diff --git a/swagger_server/__init__.py b/swagger_server/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/swagger_server/__main__.py b/swagger_server/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..bc9777dd382845f07b0bd02198c2ed8cd1386d5f --- /dev/null +++ b/swagger_server/__main__.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import connexion + +from swagger_server import encoder + + +def main(): + # app = connexion.App(__name__, specification_dir='./swagger/') + app = connexion.FlaskApp(__name__) + app.app.json_encoder = encoder.JSONEncoder + app.add_api('./swagger/swagger.yaml', arguments={'title': 'Capabilities Exposure API Server'}, pythonic_params=True) + app.run(port=8080) + + +if __name__ == '__main__': + main() diff --git a/swagger_server/configs/__init__.py b/swagger_server/configs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/swagger_server/configs/env_config.py b/swagger_server/configs/env_config.py new file mode 100644 index 0000000000000000000000000000000000000000..4d27e8881d60a86e3e928da999ad1b6983adae72 --- /dev/null +++ b/swagger_server/configs/env_config.py @@ -0,0 +1,9 @@ +from dotenv import load_dotenv +import os + +load_dotenv() + +PI_EDGE_BASE_URL = os.getenv("PI_EDGE_BASE_URL") +PI_EDGE_USERNAME = os.getenv("PI_EDGE_USERNAME") +PI_EDGE_PASSWORD = os.getenv("PI_EDGE_PASSWORD") +HTTP_PROXY = os.getenv("HTTP_PROXY") diff --git a/swagger_server/configs/logger_config.py b/swagger_server/configs/logger_config.py new file mode 100644 index 0000000000000000000000000000000000000000..f6bd8873cca12433152c8048ec4ff4a6ccfdb580 --- /dev/null +++ b/swagger_server/configs/logger_config.py @@ -0,0 +1,9 @@ +import logging +import sys + +# logging.basicConfig(level=logging.INFO) +logger = logging.getLogger("Capabilities Exposure API Server") +logger.setLevel(logging.INFO) +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(formatter) diff --git a/swagger_server/controllers/__init__.py b/swagger_server/controllers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/swagger_server/controllers/application_controller.py b/swagger_server/controllers/application_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..96ca09dca5fabedc256d978a8c3ae36a661918a0 --- /dev/null +++ b/swagger_server/controllers/application_controller.py @@ -0,0 +1,191 @@ +import connexion +import six + +from swagger_server.configs.logger_config import logger +from swagger_server.filters.service_functions import find_requested_service_function +from swagger_server.models.app_id import AppId # noqa: E501 +from swagger_server.models.app_instance_id import AppInstanceId # noqa: E501 +from swagger_server.models.app_manifest import AppManifest # noqa: E501 +from swagger_server.models.edge_cloud_region import EdgeCloudRegion # noqa: E501 +from swagger_server.models.edge_cloud_zone import EdgeCloudZone # noqa: E501 +from swagger_server.models.error_info import ErrorInfo # noqa: E501 +from swagger_server.models.inline_response200 import InlineResponse200 # noqa: E501 +from swagger_server.models.inline_response2001 import InlineResponse2001 # noqa: E501 +from swagger_server.models.inline_response202 import InlineResponse202 # noqa: E501 +from swagger_server.models.submitted_app import SubmittedApp # noqa: E501 +from swagger_server import util +from swagger_server.schema_mappers.application_instantiation_mapper import ( + map_to_pi_edge_deployed_service_function, +) +from swagger_server.services.pi_edge_services import PiEdgeAPIClientFactory + + +def create_app_instance(body, app_id, x_correlator=None): # noqa: E501 + """Instantiation of an Application + + Ask the Edge Cloud Platform to instantiate an application to one or several Edge Cloud Zones with an Application as an input and an Application Instance as the output. # noqa: E501 + + :param body: Array of Edge Cloud Zone + :type body: list | bytes + :param app_id: A globally unique identifier associated with the application. Edge Cloud Provider generates this identifier when the application is submitted. + :type app_id: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + + :rtype: InlineResponse202 + """ + try: + if connexion.request.is_json: + body = [ + EdgeCloudZone.from_dict(d) for d in connexion.request.get_json() + ] # noqa: E501 + # if connexion.request.is_json: + # app_id = AppId.from_dict(connexion.request.get_json()) # noqa: E501 + + logger.critical(body) + logger.critical(f"Test: {app_id}") + + pi_edge_factory = PiEdgeAPIClientFactory() + pi_edge_api_client = pi_edge_factory.create_pi_edge_api_client() + + service_functions_catalogue = ( + pi_edge_api_client.get_service_functions_catalogue() + ) + requested_application = find_requested_service_function( + service_functions_catalogue, app_id + ) + if requested_application is None: + return { + "status": 400, + "code": "INVALID_ARGUMENT", + "message": "The requested appId could not be retrieved. Please verify application metadata for the provided id do exists.", + }, 400 + + deployed_service_functions = [ + map_to_pi_edge_deployed_service_function( + edge_cloud, requested_application["name"] + ) + for edge_cloud in body + ] + + for service_function in deployed_service_functions: + result = pi_edge_api_client.deploy_service_function(data=service_function) + if result != None: # an error occurred + if "error" in result.keys(): + raise Exception(result["error"]) + else: + raise Exception("Unexpected error in app instantiation") + return {}, 202 # application instantiation accepted + except: + logger.exception("Error instantiating application") + return { + "status": 500, + "code": "INTERNAL", + "message": "Internal server error.", + }, 500 + + +def delete_app(app_id, x_correlator=None): # noqa: E501 + """Delete an Application from an Edge Cloud Provider + + Delete all the information and content related to an Application # noqa: E501 + + :param app_id: Identificator of the application to be deleted provided by the Edge Cloud Provider once the submission was successful + :type app_id: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + + :rtype: None + """ + if connexion.request.is_json: + app_id = AppId.from_dict(connexion.request.get_json()) # noqa: E501 + return "do some magic!" + + +def delete_app_instance(app_id, app_instance_id, x_correlator=None): # noqa: E501 + """Terminate an Application Instance + + Terminate a running instance of an application within an Edge Cloud Zone # noqa: E501 + + :param app_id: A globally unique identifier associated with the application. Edge Cloud Provider generates this identifier when the application is submitted. + :type app_id: dict | bytes + :param app_instance_id: Identificator of the specific application instance that will be terminated + :type app_instance_id: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + + :rtype: None + """ + if connexion.request.is_json: + app_id = AppId.from_dict(connexion.request.get_json()) # noqa: E501 + if connexion.request.is_json: + app_instance_id = AppInstanceId.from_dict( + connexion.request.get_json() + ) # noqa: E501 + return "do some magic!" + + +def get_app(app_id, x_correlator=None): # noqa: E501 + """Retrieve the information of an Application + + Ask the Edge Cloud Provider the information for a given application # noqa: E501 + + :param app_id: A globally unique identifier associated with the application. Edge Cloud Provider generates this identifier when the application is submitted. + :type app_id: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + + :rtype: InlineResponse200 + """ + if connexion.request.is_json: + app_id = AppId.from_dict(connexion.request.get_json()) # noqa: E501 + return "do some magic!" + + +def get_app_instance( + app_id, x_correlator=None, app_instance_id=None, region=None +): # noqa: E501 + """Retrieve the information of Application Instances for a given App + + Ask the Edge Cloud Provider the information of the instances for a given application # noqa: E501 + + :param app_id: A globally unique identifier associated with the application. Edge Cloud Provider generates this identifier when the application is submitted. + :type app_id: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + :param app_instance_id: A globally unique identifier associated with a running instance of an application within an specific Edge Cloud Zone. Edge Cloud Provider generates this identifier. + :type app_instance_id: dict | bytes + :param region: Human readable name of the geographical Edge Cloud Region of the Edge Cloud. Defined by the Edge Cloud Provider. + :type region: dict | bytes + + :rtype: InlineResponse2001 + """ + if connexion.request.is_json: + app_id = AppId.from_dict(connexion.request.get_json()) # noqa: E501 + if connexion.request.is_json: + app_instance_id = AppInstanceId.from_dict( + connexion.request.get_json() + ) # noqa: E501 + if connexion.request.is_json: + region = EdgeCloudRegion.from_dict(connexion.request.get_json()) # noqa: E501 + return "do some magic!" + + +def submit_app(body, x_correlator=None): # noqa: E501 + """Submit application metadata to the Edge Cloud Provider. + + Contains the information about the application to be instantiated in the Edge Cloud # noqa: E501 + + :param body: The Application Provider request contains mandatory + criteria (e.g. required CPU, memory, storage, bandwidth) and + optional parameters. + + :type body: dict | bytes + :param x_correlator: Correlation id for the different services + :type x_correlator: str + + :rtype: SubmittedApp + """ + if connexion.request.is_json: + body = AppManifest.from_dict(connexion.request.get_json()) # noqa: E501 + return "do some magic!" diff --git a/swagger_server/controllers/authorization_controller.py b/swagger_server/controllers/authorization_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..2f7b0bb3e281b3fb9efb588dfc8ba4c8cc3a59ed --- /dev/null +++ b/swagger_server/controllers/authorization_controller.py @@ -0,0 +1,6 @@ +from typing import List +""" +controller generated to handled auth operation described at: +https://connexion.readthedocs.io/en/latest/security.html +""" + diff --git a/swagger_server/controllers/edge_cloud_controller.py b/swagger_server/controllers/edge_cloud_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..5472071fc16035d31e498156257ace451acbffa4 --- /dev/null +++ b/swagger_server/controllers/edge_cloud_controller.py @@ -0,0 +1,58 @@ +import connexion +import six + +from swagger_server.models.edge_cloud_region import EdgeCloudRegion # noqa: E501 +from swagger_server.models.edge_cloud_zone_status import ( + EdgeCloudZoneStatus, +) # noqa: E501 +from swagger_server.models.edge_cloud_zones import EdgeCloudZones # noqa: E501 +from swagger_server.models.error_info import ErrorInfo # noqa: E501 +from swagger_server import util +from swagger_server.schema_mappers.edge_cloud_mapper import map_to_edge_cloud +from swagger_server.services.pi_edge_services import PiEdgeAPIClientFactory + + +def get_edge_cloud_zones(x_correlator=None, region=None, status=None): # noqa: E501 + """Retrieve a list of the operators Edge Cloud Zones and their status + + List of the operators Edge Cloud Zones and their status, ordering the results by location and filtering by status (active/inactive/unknown) # noqa: E501 + + :param x_correlator: Correlation id for the different services + :type x_correlator: str + :param region: Human readable name of the geographical Edge Cloud Region of the Edge Cloud. Defined by the Edge Cloud Provider. + :type region: dict | bytes + :param status: Human readable status of the Edge Cloud Zone + :type status: dict | bytes + + :rtype: EdgeCloudZones + """ + try: + if connexion.request.is_json: + region = EdgeCloudRegion.from_dict( + connexion.request.get_json() + ) # noqa: E501 + if connexion.request.is_json: + status = EdgeCloudZoneStatus.from_dict( + connexion.request.get_json() + ) # noqa: E501 + + pi_edge_factory = PiEdgeAPIClientFactory() + pi_edge_api_client = pi_edge_factory.create_pi_edge_api_client() + nodes: list | None = pi_edge_api_client.edge_cloud_zones() + + if not nodes: + error_info = ErrorInfo( + status=404, code="NOT_FOUND", message="No edge cloud zones found." + ) + return error_info, 404 + + # Map nodes to EdgeCloudZones + edge_cloud_zones = [map_to_edge_cloud(zone) for zone in nodes] + + return edge_cloud_zones, 200 + + except Exception as e: + error_info = ErrorInfo( + status=500, code="INTERNAL_ERROR", message=f"An error occurred: {str(e)}" + ) + return error_info, 500 diff --git a/swagger_server/encoder.py b/swagger_server/encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..61ba4721961a65d38af5d5ce2948b0abe9c7aa58 --- /dev/null +++ b/swagger_server/encoder.py @@ -0,0 +1,20 @@ +from connexion.apps.flask_app import FlaskJSONEncoder +import six + +from swagger_server.models.base_model_ import Model + + +class JSONEncoder(FlaskJSONEncoder): + include_nulls = False + + def default(self, o): + if isinstance(o, Model): + dikt = {} + for attr, _ in six.iteritems(o.swagger_types): + value = getattr(o, attr) + if value is None and not self.include_nulls: + continue + attr = o.attribute_map[attr] + dikt[attr] = value + return dikt + return FlaskJSONEncoder.default(self, o) diff --git a/swagger_server/filters/__init__.py b/swagger_server/filters/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/swagger_server/filters/service_functions.py b/swagger_server/filters/service_functions.py new file mode 100644 index 0000000000000000000000000000000000000000..83e45d9b0a9f3c5b8690da28c66518ba9a6ba36c --- /dev/null +++ b/swagger_server/filters/service_functions.py @@ -0,0 +1,14 @@ +def find_requested_service_function(service_functions: list, app_id: str): + """Given a pi edge service functions catalogue, return the requested item or None + + Args: + service_functions (list): list of service function + app_id (str): a uuid4 id + + Returns: + dict | None: the requested service function dict or None if not found + """ + for item in service_functions: + if isinstance(item, dict) and "_id" in item.keys(): + if item["_id"] == app_id: + return item diff --git a/swagger_server/models/__init__.py b/swagger_server/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..be60669341c869935de61db9eb94f98465f14706 --- /dev/null +++ b/swagger_server/models/__init__.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +# flake8: noqa +from __future__ import absolute_import +# import models into model package +from swagger_server.models.access_endpoint import AccessEndpoint +from swagger_server.models.any_of_access_endpoint import AnyOfAccessEndpoint +from swagger_server.models.app_id import AppId +from swagger_server.models.app_instance_id import AppInstanceId +from swagger_server.models.app_instance_info import AppInstanceInfo +from swagger_server.models.app_instance_info_component_endpoint_info import AppInstanceInfoComponentEndpointInfo +from swagger_server.models.app_manifest import AppManifest +from swagger_server.models.app_manifest_app_repo import AppManifestAppRepo +from swagger_server.models.app_manifest_component_spec import AppManifestComponentSpec +from swagger_server.models.app_manifest_network_interfaces import AppManifestNetworkInterfaces +from swagger_server.models.app_zones import AppZones +from swagger_server.models.edge_cloud_provider import EdgeCloudProvider +from swagger_server.models.edge_cloud_region import EdgeCloudRegion +from swagger_server.models.edge_cloud_zone import EdgeCloudZone +from swagger_server.models.edge_cloud_zone_id import EdgeCloudZoneId +from swagger_server.models.edge_cloud_zone_name import EdgeCloudZoneName +from swagger_server.models.edge_cloud_zone_status import EdgeCloudZoneStatus +from swagger_server.models.edge_cloud_zones import EdgeCloudZones +from swagger_server.models.error_info import ErrorInfo +from swagger_server.models.fqdn import Fqdn +from swagger_server.models.gpu_info import GpuInfo +from swagger_server.models.inline_response200 import InlineResponse200 +from swagger_server.models.inline_response2001 import InlineResponse2001 +from swagger_server.models.inline_response202 import InlineResponse202 +from swagger_server.models.ipv4_addr import Ipv4Addr +from swagger_server.models.ipv6_addr import Ipv6Addr +from swagger_server.models.operating_system import OperatingSystem +from swagger_server.models.port import Port +from swagger_server.models.required_resources import RequiredResources +from swagger_server.models.submitted_app import SubmittedApp +from swagger_server.models.uri import Uri diff --git a/swagger_server/models/access_endpoint.py b/swagger_server/models/access_endpoint.py new file mode 100644 index 0000000000000000000000000000000000000000..48324f0daa38f522a06359ada698112d1c699afb --- /dev/null +++ b/swagger_server/models/access_endpoint.py @@ -0,0 +1,150 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.fqdn import Fqdn # noqa: F401,E501 +from swagger_server.models.ipv4_addr import Ipv4Addr # noqa: F401,E501 +from swagger_server.models.ipv6_addr import Ipv6Addr # noqa: F401,E501 +from swagger_server.models.port import Port # noqa: F401,E501 +from swagger_server import util + + +class AccessEndpoint(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, port: Port=None, fqdn: Fqdn=None, ipv4_addresses: List[Ipv4Addr]=None, ipv6_addresses: List[Ipv6Addr]=None): # noqa: E501 + """AccessEndpoint - a model defined in Swagger + + :param port: The port of this AccessEndpoint. # noqa: E501 + :type port: Port + :param fqdn: The fqdn of this AccessEndpoint. # noqa: E501 + :type fqdn: Fqdn + :param ipv4_addresses: The ipv4_addresses of this AccessEndpoint. # noqa: E501 + :type ipv4_addresses: List[Ipv4Addr] + :param ipv6_addresses: The ipv6_addresses of this AccessEndpoint. # noqa: E501 + :type ipv6_addresses: List[Ipv6Addr] + """ + self.swagger_types = { + 'port': Port, + 'fqdn': Fqdn, + 'ipv4_addresses': List[Ipv4Addr], + 'ipv6_addresses': List[Ipv6Addr] + } + + self.attribute_map = { + 'port': 'port', + 'fqdn': 'fqdn', + 'ipv4_addresses': 'ipv4Addresses', + 'ipv6_addresses': 'ipv6Addresses' + } + self._port = port + self._fqdn = fqdn + self._ipv4_addresses = ipv4_addresses + self._ipv6_addresses = ipv6_addresses + + @classmethod + def from_dict(cls, dikt) -> 'AccessEndpoint': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AccessEndpoint of this AccessEndpoint. # noqa: E501 + :rtype: AccessEndpoint + """ + return util.deserialize_model(dikt, cls) + + @property + def port(self) -> Port: + """Gets the port of this AccessEndpoint. + + + :return: The port of this AccessEndpoint. + :rtype: Port + """ + return self._port + + @port.setter + def port(self, port: Port): + """Sets the port of this AccessEndpoint. + + + :param port: The port of this AccessEndpoint. + :type port: Port + """ + if port is None: + raise ValueError("Invalid value for `port`, must not be `None`") # noqa: E501 + + self._port = port + + @property + def fqdn(self) -> Fqdn: + """Gets the fqdn of this AccessEndpoint. + + + :return: The fqdn of this AccessEndpoint. + :rtype: Fqdn + """ + return self._fqdn + + @fqdn.setter + def fqdn(self, fqdn: Fqdn): + """Sets the fqdn of this AccessEndpoint. + + + :param fqdn: The fqdn of this AccessEndpoint. + :type fqdn: Fqdn + """ + + self._fqdn = fqdn + + @property + def ipv4_addresses(self) -> List[Ipv4Addr]: + """Gets the ipv4_addresses of this AccessEndpoint. + + IP version 4 of an application instance # noqa: E501 + + :return: The ipv4_addresses of this AccessEndpoint. + :rtype: List[Ipv4Addr] + """ + return self._ipv4_addresses + + @ipv4_addresses.setter + def ipv4_addresses(self, ipv4_addresses: List[Ipv4Addr]): + """Sets the ipv4_addresses of this AccessEndpoint. + + IP version 4 of an application instance # noqa: E501 + + :param ipv4_addresses: The ipv4_addresses of this AccessEndpoint. + :type ipv4_addresses: List[Ipv4Addr] + """ + + self._ipv4_addresses = ipv4_addresses + + @property + def ipv6_addresses(self) -> List[Ipv6Addr]: + """Gets the ipv6_addresses of this AccessEndpoint. + + IP version 6 of an application instance. # noqa: E501 + + :return: The ipv6_addresses of this AccessEndpoint. + :rtype: List[Ipv6Addr] + """ + return self._ipv6_addresses + + @ipv6_addresses.setter + def ipv6_addresses(self, ipv6_addresses: List[Ipv6Addr]): + """Sets the ipv6_addresses of this AccessEndpoint. + + IP version 6 of an application instance. # noqa: E501 + + :param ipv6_addresses: The ipv6_addresses of this AccessEndpoint. + :type ipv6_addresses: List[Ipv6Addr] + """ + + self._ipv6_addresses = ipv6_addresses diff --git a/swagger_server/models/any_of_access_endpoint.py b/swagger_server/models/any_of_access_endpoint.py new file mode 100644 index 0000000000000000000000000000000000000000..cb2ab06bfd9e6bd8468350013dea05ed21d492a7 --- /dev/null +++ b/swagger_server/models/any_of_access_endpoint.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class AnyOfAccessEndpoint(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """AnyOfAccessEndpoint - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'AnyOfAccessEndpoint': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AnyOfAccessEndpoint of this AnyOfAccessEndpoint. # noqa: E501 + :rtype: AnyOfAccessEndpoint + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/app_id.py b/swagger_server/models/app_id.py new file mode 100644 index 0000000000000000000000000000000000000000..75832d7b9fa048f25878af61237b1ef58b7ab946 --- /dev/null +++ b/swagger_server/models/app_id.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class AppId(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """AppId - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'AppId': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppId of this AppId. # noqa: E501 + :rtype: AppId + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/app_instance_id.py b/swagger_server/models/app_instance_id.py new file mode 100644 index 0000000000000000000000000000000000000000..d49bdaa3ff840e81654bb289363f76cedcbbf831 --- /dev/null +++ b/swagger_server/models/app_instance_id.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class AppInstanceId(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """AppInstanceId - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'AppInstanceId': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppInstanceId of this AppInstanceId. # noqa: E501 + :rtype: AppInstanceId + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/app_instance_info.py b/swagger_server/models/app_instance_info.py new file mode 100644 index 0000000000000000000000000000000000000000..971c7b1257d765ef99787fc2b1d7c98453977207 --- /dev/null +++ b/swagger_server/models/app_instance_info.py @@ -0,0 +1,153 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_instance_id import AppInstanceId # noqa: F401,E501 +from swagger_server.models.app_instance_info_component_endpoint_info import AppInstanceInfoComponentEndpointInfo # noqa: F401,E501 +from swagger_server.models.edge_cloud_zone import EdgeCloudZone # noqa: F401,E501 +from swagger_server import util + + +class AppInstanceInfo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, app_instance_id: AppInstanceId=None, status: str='unknown', component_endpoint_info: List[AppInstanceInfoComponentEndpointInfo]=None, edge_cloud_zone: EdgeCloudZone=None): # noqa: E501 + """AppInstanceInfo - a model defined in Swagger + + :param app_instance_id: The app_instance_id of this AppInstanceInfo. # noqa: E501 + :type app_instance_id: AppInstanceId + :param status: The status of this AppInstanceInfo. # noqa: E501 + :type status: str + :param component_endpoint_info: The component_endpoint_info of this AppInstanceInfo. # noqa: E501 + :type component_endpoint_info: List[AppInstanceInfoComponentEndpointInfo] + :param edge_cloud_zone: The edge_cloud_zone of this AppInstanceInfo. # noqa: E501 + :type edge_cloud_zone: EdgeCloudZone + """ + self.swagger_types = { + 'app_instance_id': AppInstanceId, + 'status': str, + 'component_endpoint_info': List[AppInstanceInfoComponentEndpointInfo], + 'edge_cloud_zone': EdgeCloudZone + } + + self.attribute_map = { + 'app_instance_id': 'appInstanceId', + 'status': 'status', + 'component_endpoint_info': 'componentEndpointInfo', + 'edge_cloud_zone': 'edgeCloudZone' + } + self._app_instance_id = app_instance_id + self._status = status + self._component_endpoint_info = component_endpoint_info + self._edge_cloud_zone = edge_cloud_zone + + @classmethod + def from_dict(cls, dikt) -> 'AppInstanceInfo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppInstanceInfo of this AppInstanceInfo. # noqa: E501 + :rtype: AppInstanceInfo + """ + return util.deserialize_model(dikt, cls) + + @property + def app_instance_id(self) -> AppInstanceId: + """Gets the app_instance_id of this AppInstanceInfo. + + + :return: The app_instance_id of this AppInstanceInfo. + :rtype: AppInstanceId + """ + return self._app_instance_id + + @app_instance_id.setter + def app_instance_id(self, app_instance_id: AppInstanceId): + """Sets the app_instance_id of this AppInstanceInfo. + + + :param app_instance_id: The app_instance_id of this AppInstanceInfo. + :type app_instance_id: AppInstanceId + """ + + self._app_instance_id = app_instance_id + + @property + def status(self) -> str: + """Gets the status of this AppInstanceInfo. + + Status of the application instance (default is 'unknown') # noqa: E501 + + :return: The status of this AppInstanceInfo. + :rtype: str + """ + return self._status + + @status.setter + def status(self, status: str): + """Sets the status of this AppInstanceInfo. + + Status of the application instance (default is 'unknown') # noqa: E501 + + :param status: The status of this AppInstanceInfo. + :type status: str + """ + allowed_values = ["ready", "instantiating", "failed", "terminating", "unknown"] # noqa: E501 + if status not in allowed_values: + raise ValueError( + "Invalid value for `status` ({0}), must be one of {1}" + .format(status, allowed_values) + ) + + self._status = status + + @property + def component_endpoint_info(self) -> List[AppInstanceInfoComponentEndpointInfo]: + """Gets the component_endpoint_info of this AppInstanceInfo. + + Information about the IP and Port exposed by the Edge Cloud Platform. Application Client shall use these access points to reach this application instance # noqa: E501 + + :return: The component_endpoint_info of this AppInstanceInfo. + :rtype: List[AppInstanceInfoComponentEndpointInfo] + """ + return self._component_endpoint_info + + @component_endpoint_info.setter + def component_endpoint_info(self, component_endpoint_info: List[AppInstanceInfoComponentEndpointInfo]): + """Sets the component_endpoint_info of this AppInstanceInfo. + + Information about the IP and Port exposed by the Edge Cloud Platform. Application Client shall use these access points to reach this application instance # noqa: E501 + + :param component_endpoint_info: The component_endpoint_info of this AppInstanceInfo. + :type component_endpoint_info: List[AppInstanceInfoComponentEndpointInfo] + """ + + self._component_endpoint_info = component_endpoint_info + + @property + def edge_cloud_zone(self) -> EdgeCloudZone: + """Gets the edge_cloud_zone of this AppInstanceInfo. + + + :return: The edge_cloud_zone of this AppInstanceInfo. + :rtype: EdgeCloudZone + """ + return self._edge_cloud_zone + + @edge_cloud_zone.setter + def edge_cloud_zone(self, edge_cloud_zone: EdgeCloudZone): + """Sets the edge_cloud_zone of this AppInstanceInfo. + + + :param edge_cloud_zone: The edge_cloud_zone of this AppInstanceInfo. + :type edge_cloud_zone: EdgeCloudZone + """ + + self._edge_cloud_zone = edge_cloud_zone diff --git a/swagger_server/models/app_instance_info_component_endpoint_info.py b/swagger_server/models/app_instance_info_component_endpoint_info.py new file mode 100644 index 0000000000000000000000000000000000000000..ea08d7ed79e3cff64d3b44ae457e73cb46252969 --- /dev/null +++ b/swagger_server/models/app_instance_info_component_endpoint_info.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.access_endpoint import AccessEndpoint # noqa: F401,E501 +import re # noqa: F401,E501 +from swagger_server import util + + +class AppInstanceInfoComponentEndpointInfo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, interface_id: str=None, access_points: AccessEndpoint=None): # noqa: E501 + """AppInstanceInfoComponentEndpointInfo - a model defined in Swagger + + :param interface_id: The interface_id of this AppInstanceInfoComponentEndpointInfo. # noqa: E501 + :type interface_id: str + :param access_points: The access_points of this AppInstanceInfoComponentEndpointInfo. # noqa: E501 + :type access_points: AccessEndpoint + """ + self.swagger_types = { + 'interface_id': str, + 'access_points': AccessEndpoint + } + + self.attribute_map = { + 'interface_id': 'interfaceId', + 'access_points': 'accessPoints' + } + self._interface_id = interface_id + self._access_points = access_points + + @classmethod + def from_dict(cls, dikt) -> 'AppInstanceInfoComponentEndpointInfo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppInstanceInfo_componentEndpointInfo of this AppInstanceInfoComponentEndpointInfo. # noqa: E501 + :rtype: AppInstanceInfoComponentEndpointInfo + """ + return util.deserialize_model(dikt, cls) + + @property + def interface_id(self) -> str: + """Gets the interface_id of this AppInstanceInfoComponentEndpointInfo. + + This is the interface Identifier that Application Provider defines when application is being submitted. # noqa: E501 + + :return: The interface_id of this AppInstanceInfoComponentEndpointInfo. + :rtype: str + """ + return self._interface_id + + @interface_id.setter + def interface_id(self, interface_id: str): + """Sets the interface_id of this AppInstanceInfoComponentEndpointInfo. + + This is the interface Identifier that Application Provider defines when application is being submitted. # noqa: E501 + + :param interface_id: The interface_id of this AppInstanceInfoComponentEndpointInfo. + :type interface_id: str + """ + if interface_id is None: + raise ValueError("Invalid value for `interface_id`, must not be `None`") # noqa: E501 + + self._interface_id = interface_id + + @property + def access_points(self) -> AccessEndpoint: + """Gets the access_points of this AppInstanceInfoComponentEndpointInfo. + + + :return: The access_points of this AppInstanceInfoComponentEndpointInfo. + :rtype: AccessEndpoint + """ + return self._access_points + + @access_points.setter + def access_points(self, access_points: AccessEndpoint): + """Sets the access_points of this AppInstanceInfoComponentEndpointInfo. + + + :param access_points: The access_points of this AppInstanceInfoComponentEndpointInfo. + :type access_points: AccessEndpoint + """ + if access_points is None: + raise ValueError("Invalid value for `access_points`, must not be `None`") # noqa: E501 + + self._access_points = access_points diff --git a/swagger_server/models/app_manifest.py b/swagger_server/models/app_manifest.py new file mode 100644 index 0000000000000000000000000000000000000000..0e5fa069e32d5066548f67b20b756aba6aa55e5d --- /dev/null +++ b/swagger_server/models/app_manifest.py @@ -0,0 +1,247 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_manifest_app_repo import AppManifestAppRepo # noqa: F401,E501 +from swagger_server.models.app_manifest_component_spec import AppManifestComponentSpec # noqa: F401,E501 +from swagger_server.models.operating_system import OperatingSystem # noqa: F401,E501 +from swagger_server.models.required_resources import RequiredResources # noqa: F401,E501 +import re # noqa: F401,E501 +from swagger_server import util + + +class AppManifest(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, name: str=None, version: int=None, package_type: str=None, operating_system: OperatingSystem=None, app_repo: AppManifestAppRepo=None, required_resources: RequiredResources=None, component_spec: List[AppManifestComponentSpec]=None): # noqa: E501 + """AppManifest - a model defined in Swagger + + :param name: The name of this AppManifest. # noqa: E501 + :type name: str + :param version: The version of this AppManifest. # noqa: E501 + :type version: int + :param package_type: The package_type of this AppManifest. # noqa: E501 + :type package_type: str + :param operating_system: The operating_system of this AppManifest. # noqa: E501 + :type operating_system: OperatingSystem + :param app_repo: The app_repo of this AppManifest. # noqa: E501 + :type app_repo: AppManifestAppRepo + :param required_resources: The required_resources of this AppManifest. # noqa: E501 + :type required_resources: RequiredResources + :param component_spec: The component_spec of this AppManifest. # noqa: E501 + :type component_spec: List[AppManifestComponentSpec] + """ + self.swagger_types = { + 'name': str, + 'version': int, + 'package_type': str, + 'operating_system': OperatingSystem, + 'app_repo': AppManifestAppRepo, + 'required_resources': RequiredResources, + 'component_spec': List[AppManifestComponentSpec] + } + + self.attribute_map = { + 'name': 'name', + 'version': 'version', + 'package_type': 'packageType', + 'operating_system': 'operatingSystem', + 'app_repo': 'appRepo', + 'required_resources': 'requiredResources', + 'component_spec': 'componentSpec' + } + self._name = name + self._version = version + self._package_type = package_type + self._operating_system = operating_system + self._app_repo = app_repo + self._required_resources = required_resources + self._component_spec = component_spec + + @classmethod + def from_dict(cls, dikt) -> 'AppManifest': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppManifest of this AppManifest. # noqa: E501 + :rtype: AppManifest + """ + return util.deserialize_model(dikt, cls) + + @property + def name(self) -> str: + """Gets the name of this AppManifest. + + Name of the application. # noqa: E501 + + :return: The name of this AppManifest. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this AppManifest. + + Name of the application. # noqa: E501 + + :param name: The name of this AppManifest. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501 + + self._name = name + + @property + def version(self) -> int: + """Gets the version of this AppManifest. + + Application version information # noqa: E501 + + :return: The version of this AppManifest. + :rtype: int + """ + return self._version + + @version.setter + def version(self, version: int): + """Sets the version of this AppManifest. + + Application version information # noqa: E501 + + :param version: The version of this AppManifest. + :type version: int + """ + if version is None: + raise ValueError("Invalid value for `version`, must not be `None`") # noqa: E501 + + self._version = version + + @property + def package_type(self) -> str: + """Gets the package_type of this AppManifest. + + Format of the application image package # noqa: E501 + + :return: The package_type of this AppManifest. + :rtype: str + """ + return self._package_type + + @package_type.setter + def package_type(self, package_type: str): + """Sets the package_type of this AppManifest. + + Format of the application image package # noqa: E501 + + :param package_type: The package_type of this AppManifest. + :type package_type: str + """ + allowed_values = ["QCOW2", "OVA", "CONTAINER", "HELM"] # noqa: E501 + if package_type not in allowed_values: + raise ValueError( + "Invalid value for `package_type` ({0}), must be one of {1}" + .format(package_type, allowed_values) + ) + + self._package_type = package_type + + @property + def operating_system(self) -> OperatingSystem: + """Gets the operating_system of this AppManifest. + + + :return: The operating_system of this AppManifest. + :rtype: OperatingSystem + """ + return self._operating_system + + @operating_system.setter + def operating_system(self, operating_system: OperatingSystem): + """Sets the operating_system of this AppManifest. + + + :param operating_system: The operating_system of this AppManifest. + :type operating_system: OperatingSystem + """ + + self._operating_system = operating_system + + @property + def app_repo(self) -> AppManifestAppRepo: + """Gets the app_repo of this AppManifest. + + + :return: The app_repo of this AppManifest. + :rtype: AppManifestAppRepo + """ + return self._app_repo + + @app_repo.setter + def app_repo(self, app_repo: AppManifestAppRepo): + """Sets the app_repo of this AppManifest. + + + :param app_repo: The app_repo of this AppManifest. + :type app_repo: AppManifestAppRepo + """ + if app_repo is None: + raise ValueError("Invalid value for `app_repo`, must not be `None`") # noqa: E501 + + self._app_repo = app_repo + + @property + def required_resources(self) -> RequiredResources: + """Gets the required_resources of this AppManifest. + + + :return: The required_resources of this AppManifest. + :rtype: RequiredResources + """ + return self._required_resources + + @required_resources.setter + def required_resources(self, required_resources: RequiredResources): + """Sets the required_resources of this AppManifest. + + + :param required_resources: The required_resources of this AppManifest. + :type required_resources: RequiredResources + """ + if required_resources is None: + raise ValueError("Invalid value for `required_resources`, must not be `None`") # noqa: E501 + + self._required_resources = required_resources + + @property + def component_spec(self) -> List[AppManifestComponentSpec]: + """Gets the component_spec of this AppManifest. + + Information defined in \"appRepo\" point to the application descriptor e.g. Helm chart, docker-compose yaml file etc. The descriptor may contain one or more containers and their associated meta-data. A component refers to additional details about these containers to expose the instances of the containers to external client applications. App provider can define one or more components (via the associated network port) in componentSpec corresponding to the containers in helm charts or docker-compose yaml file as part of app descriptors. # noqa: E501 + + :return: The component_spec of this AppManifest. + :rtype: List[AppManifestComponentSpec] + """ + return self._component_spec + + @component_spec.setter + def component_spec(self, component_spec: List[AppManifestComponentSpec]): + """Sets the component_spec of this AppManifest. + + Information defined in \"appRepo\" point to the application descriptor e.g. Helm chart, docker-compose yaml file etc. The descriptor may contain one or more containers and their associated meta-data. A component refers to additional details about these containers to expose the instances of the containers to external client applications. App provider can define one or more components (via the associated network port) in componentSpec corresponding to the containers in helm charts or docker-compose yaml file as part of app descriptors. # noqa: E501 + + :param component_spec: The component_spec of this AppManifest. + :type component_spec: List[AppManifestComponentSpec] + """ + if component_spec is None: + raise ValueError("Invalid value for `component_spec`, must not be `None`") # noqa: E501 + + self._component_spec = component_spec diff --git a/swagger_server/models/app_manifest_app_repo.py b/swagger_server/models/app_manifest_app_repo.py new file mode 100644 index 0000000000000000000000000000000000000000..37c3d85a2981954c4b87eb22b21a78a56b03145b --- /dev/null +++ b/swagger_server/models/app_manifest_app_repo.py @@ -0,0 +1,217 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.uri import Uri # noqa: F401,E501 +from swagger_server import util + + +class AppManifestAppRepo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, type: str=None, image_path: Uri=None, user_name: str=None, credentials: str=None, auth_type: str=None, checksum: str=None): # noqa: E501 + """AppManifestAppRepo - a model defined in Swagger + + :param type: The type of this AppManifestAppRepo. # noqa: E501 + :type type: str + :param image_path: The image_path of this AppManifestAppRepo. # noqa: E501 + :type image_path: Uri + :param user_name: The user_name of this AppManifestAppRepo. # noqa: E501 + :type user_name: str + :param credentials: The credentials of this AppManifestAppRepo. # noqa: E501 + :type credentials: str + :param auth_type: The auth_type of this AppManifestAppRepo. # noqa: E501 + :type auth_type: str + :param checksum: The checksum of this AppManifestAppRepo. # noqa: E501 + :type checksum: str + """ + self.swagger_types = { + 'type': str, + 'image_path': Uri, + 'user_name': str, + 'credentials': str, + 'auth_type': str, + 'checksum': str + } + + self.attribute_map = { + 'type': 'type', + 'image_path': 'imagePath', + 'user_name': 'userName', + 'credentials': 'credentials', + 'auth_type': 'authType', + 'checksum': 'checksum' + } + self._type = type + self._image_path = image_path + self._user_name = user_name + self._credentials = credentials + self._auth_type = auth_type + self._checksum = checksum + + @classmethod + def from_dict(cls, dikt) -> 'AppManifestAppRepo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppManifest_appRepo of this AppManifestAppRepo. # noqa: E501 + :rtype: AppManifestAppRepo + """ + return util.deserialize_model(dikt, cls) + + @property + def type(self) -> str: + """Gets the type of this AppManifestAppRepo. + + Application repository and image URI information. PUBLICREPO is used of public urls like github, helm repo etc. PRIVATEREPO is used for private repo managed by the application developer. Private repo can be accessed by using the app developer provided userName and password. Password is recommended to be the personal access token created by developer e.g. in Github repo. # noqa: E501 + + :return: The type of this AppManifestAppRepo. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type: str): + """Sets the type of this AppManifestAppRepo. + + Application repository and image URI information. PUBLICREPO is used of public urls like github, helm repo etc. PRIVATEREPO is used for private repo managed by the application developer. Private repo can be accessed by using the app developer provided userName and password. Password is recommended to be the personal access token created by developer e.g. in Github repo. # noqa: E501 + + :param type: The type of this AppManifestAppRepo. + :type type: str + """ + allowed_values = ["PRIVATEREPO", "PUBLICREPO"] # noqa: E501 + if type not in allowed_values: + raise ValueError( + "Invalid value for `type` ({0}), must be one of {1}" + .format(type, allowed_values) + ) + + self._type = type + + @property + def image_path(self) -> Uri: + """Gets the image_path of this AppManifestAppRepo. + + + :return: The image_path of this AppManifestAppRepo. + :rtype: Uri + """ + return self._image_path + + @image_path.setter + def image_path(self, image_path: Uri): + """Sets the image_path of this AppManifestAppRepo. + + + :param image_path: The image_path of this AppManifestAppRepo. + :type image_path: Uri + """ + if image_path is None: + raise ValueError("Invalid value for `image_path`, must not be `None`") # noqa: E501 + + self._image_path = image_path + + @property + def user_name(self) -> str: + """Gets the user_name of this AppManifestAppRepo. + + Username to acces the Helm chart, docker-compose file or VM image repository # noqa: E501 + + :return: The user_name of this AppManifestAppRepo. + :rtype: str + """ + return self._user_name + + @user_name.setter + def user_name(self, user_name: str): + """Sets the user_name of this AppManifestAppRepo. + + Username to acces the Helm chart, docker-compose file or VM image repository # noqa: E501 + + :param user_name: The user_name of this AppManifestAppRepo. + :type user_name: str + """ + + self._user_name = user_name + + @property + def credentials(self) -> str: + """Gets the credentials of this AppManifestAppRepo. + + Password or personal access token created by developer to acces the app repository. API users can generate a personal access token e.g. docker clients to use them as password. # noqa: E501 + + :return: The credentials of this AppManifestAppRepo. + :rtype: str + """ + return self._credentials + + @credentials.setter + def credentials(self, credentials: str): + """Sets the credentials of this AppManifestAppRepo. + + Password or personal access token created by developer to acces the app repository. API users can generate a personal access token e.g. docker clients to use them as password. # noqa: E501 + + :param credentials: The credentials of this AppManifestAppRepo. + :type credentials: str + """ + + self._credentials = credentials + + @property + def auth_type(self) -> str: + """Gets the auth_type of this AppManifestAppRepo. + + The credentials can also be formatted as a Basic auth or Bearer auth in HTTP \"Authorization\" header. # noqa: E501 + + :return: The auth_type of this AppManifestAppRepo. + :rtype: str + """ + return self._auth_type + + @auth_type.setter + def auth_type(self, auth_type: str): + """Sets the auth_type of this AppManifestAppRepo. + + The credentials can also be formatted as a Basic auth or Bearer auth in HTTP \"Authorization\" header. # noqa: E501 + + :param auth_type: The auth_type of this AppManifestAppRepo. + :type auth_type: str + """ + allowed_values = ["DOCKER", "HTTP_BASIC", "HTTP_BEARER", "NONE"] # noqa: E501 + if auth_type not in allowed_values: + raise ValueError( + "Invalid value for `auth_type` ({0}), must be one of {1}" + .format(auth_type, allowed_values) + ) + + self._auth_type = auth_type + + @property + def checksum(self) -> str: + """Gets the checksum of this AppManifestAppRepo. + + MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 + + :return: The checksum of this AppManifestAppRepo. + :rtype: str + """ + return self._checksum + + @checksum.setter + def checksum(self, checksum: str): + """Sets the checksum of this AppManifestAppRepo. + + MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 + + :param checksum: The checksum of this AppManifestAppRepo. + :type checksum: str + """ + + self._checksum = checksum diff --git a/swagger_server/models/app_manifest_component_spec.py b/swagger_server/models/app_manifest_component_spec.py new file mode 100644 index 0000000000000000000000000000000000000000..69d3e2077f4c0c13c24fe6fd90bd8f1ca8fde8cc --- /dev/null +++ b/swagger_server/models/app_manifest_component_spec.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_manifest_network_interfaces import AppManifestNetworkInterfaces # noqa: F401,E501 +from swagger_server import util + + +class AppManifestComponentSpec(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, component_name: str=None, network_interfaces: List[AppManifestNetworkInterfaces]=None): # noqa: E501 + """AppManifestComponentSpec - a model defined in Swagger + + :param component_name: The component_name of this AppManifestComponentSpec. # noqa: E501 + :type component_name: str + :param network_interfaces: The network_interfaces of this AppManifestComponentSpec. # noqa: E501 + :type network_interfaces: List[AppManifestNetworkInterfaces] + """ + self.swagger_types = { + 'component_name': str, + 'network_interfaces': List[AppManifestNetworkInterfaces] + } + + self.attribute_map = { + 'component_name': 'componentName', + 'network_interfaces': 'networkInterfaces' + } + self._component_name = component_name + self._network_interfaces = network_interfaces + + @classmethod + def from_dict(cls, dikt) -> 'AppManifestComponentSpec': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppManifest_componentSpec of this AppManifestComponentSpec. # noqa: E501 + :rtype: AppManifestComponentSpec + """ + return util.deserialize_model(dikt, cls) + + @property + def component_name(self) -> str: + """Gets the component_name of this AppManifestComponentSpec. + + Component name must be unique with an application # noqa: E501 + + :return: The component_name of this AppManifestComponentSpec. + :rtype: str + """ + return self._component_name + + @component_name.setter + def component_name(self, component_name: str): + """Sets the component_name of this AppManifestComponentSpec. + + Component name must be unique with an application # noqa: E501 + + :param component_name: The component_name of this AppManifestComponentSpec. + :type component_name: str + """ + if component_name is None: + raise ValueError("Invalid value for `component_name`, must not be `None`") # noqa: E501 + + self._component_name = component_name + + @property + def network_interfaces(self) -> List[AppManifestNetworkInterfaces]: + """Gets the network_interfaces of this AppManifestComponentSpec. + + Each application component exposes some ports either for external users or for inter component communication. Application provider is required to specify which ports are to be exposed and the type of traffic that will flow through these ports.The underlying platform may assign a dynamic port against the \"extPort\" that the application clients will use to connect with edge application instance. # noqa: E501 + + :return: The network_interfaces of this AppManifestComponentSpec. + :rtype: List[AppManifestNetworkInterfaces] + """ + return self._network_interfaces + + @network_interfaces.setter + def network_interfaces(self, network_interfaces: List[AppManifestNetworkInterfaces]): + """Sets the network_interfaces of this AppManifestComponentSpec. + + Each application component exposes some ports either for external users or for inter component communication. Application provider is required to specify which ports are to be exposed and the type of traffic that will flow through these ports.The underlying platform may assign a dynamic port against the \"extPort\" that the application clients will use to connect with edge application instance. # noqa: E501 + + :param network_interfaces: The network_interfaces of this AppManifestComponentSpec. + :type network_interfaces: List[AppManifestNetworkInterfaces] + """ + if network_interfaces is None: + raise ValueError("Invalid value for `network_interfaces`, must not be `None`") # noqa: E501 + + self._network_interfaces = network_interfaces diff --git a/swagger_server/models/app_manifest_network_interfaces.py b/swagger_server/models/app_manifest_network_interfaces.py new file mode 100644 index 0000000000000000000000000000000000000000..be8283e18435595363abd21d3065d66e93d0d140 --- /dev/null +++ b/swagger_server/models/app_manifest_network_interfaces.py @@ -0,0 +1,165 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +import re # noqa: F401,E501 +from swagger_server import util + + +class AppManifestNetworkInterfaces(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, interface_id: str=None, protocol: str=None, port: int=None, visibility_type: str=None): # noqa: E501 + """AppManifestNetworkInterfaces - a model defined in Swagger + + :param interface_id: The interface_id of this AppManifestNetworkInterfaces. # noqa: E501 + :type interface_id: str + :param protocol: The protocol of this AppManifestNetworkInterfaces. # noqa: E501 + :type protocol: str + :param port: The port of this AppManifestNetworkInterfaces. # noqa: E501 + :type port: int + :param visibility_type: The visibility_type of this AppManifestNetworkInterfaces. # noqa: E501 + :type visibility_type: str + """ + self.swagger_types = { + 'interface_id': str, + 'protocol': str, + 'port': int, + 'visibility_type': str + } + + self.attribute_map = { + 'interface_id': 'interfaceId', + 'protocol': 'protocol', + 'port': 'port', + 'visibility_type': 'visibilityType' + } + self._interface_id = interface_id + self._protocol = protocol + self._port = port + self._visibility_type = visibility_type + + @classmethod + def from_dict(cls, dikt) -> 'AppManifestNetworkInterfaces': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppManifest_networkInterfaces of this AppManifestNetworkInterfaces. # noqa: E501 + :rtype: AppManifestNetworkInterfaces + """ + return util.deserialize_model(dikt, cls) + + @property + def interface_id(self) -> str: + """Gets the interface_id of this AppManifestNetworkInterfaces. + + Each Port and corresponding traffic protocol exposed by the component is identified by a name. Application client on user device requires this to uniquley idenify the interface. # noqa: E501 + + :return: The interface_id of this AppManifestNetworkInterfaces. + :rtype: str + """ + return self._interface_id + + @interface_id.setter + def interface_id(self, interface_id: str): + """Sets the interface_id of this AppManifestNetworkInterfaces. + + Each Port and corresponding traffic protocol exposed by the component is identified by a name. Application client on user device requires this to uniquley idenify the interface. # noqa: E501 + + :param interface_id: The interface_id of this AppManifestNetworkInterfaces. + :type interface_id: str + """ + if interface_id is None: + raise ValueError("Invalid value for `interface_id`, must not be `None`") # noqa: E501 + + self._interface_id = interface_id + + @property + def protocol(self) -> str: + """Gets the protocol of this AppManifestNetworkInterfaces. + + Defines the IP transport communication protocol i.e., TCP, UDP or ANY # noqa: E501 + + :return: The protocol of this AppManifestNetworkInterfaces. + :rtype: str + """ + return self._protocol + + @protocol.setter + def protocol(self, protocol: str): + """Sets the protocol of this AppManifestNetworkInterfaces. + + Defines the IP transport communication protocol i.e., TCP, UDP or ANY # noqa: E501 + + :param protocol: The protocol of this AppManifestNetworkInterfaces. + :type protocol: str + """ + allowed_values = ["TCP", "UDP", "ANY"] # noqa: E501 + if protocol not in allowed_values: + raise ValueError( + "Invalid value for `protocol` ({0}), must be one of {1}" + .format(protocol, allowed_values) + ) + + self._protocol = protocol + + @property + def port(self) -> int: + """Gets the port of this AppManifestNetworkInterfaces. + + Port number exposed by the component. Edge Cloud Provider may generate a dynamic port towards the component instance which forwards external traffic to the component port. # noqa: E501 + + :return: The port of this AppManifestNetworkInterfaces. + :rtype: int + """ + return self._port + + @port.setter + def port(self, port: int): + """Sets the port of this AppManifestNetworkInterfaces. + + Port number exposed by the component. Edge Cloud Provider may generate a dynamic port towards the component instance which forwards external traffic to the component port. # noqa: E501 + + :param port: The port of this AppManifestNetworkInterfaces. + :type port: int + """ + if port is None: + raise ValueError("Invalid value for `port`, must not be `None`") # noqa: E501 + + self._port = port + + @property + def visibility_type(self) -> str: + """Gets the visibility_type of this AppManifestNetworkInterfaces. + + Defines whether the interface is exposed to outer world or not i.e., external, or internal. If this is set to \"external\", then it is exposed to external applications otherwise it is exposed internally to edge application components within edge cloud. When exposed to external world, an external dynamic port is assigned for UC traffic and mapped to the extPort # noqa: E501 + + :return: The visibility_type of this AppManifestNetworkInterfaces. + :rtype: str + """ + return self._visibility_type + + @visibility_type.setter + def visibility_type(self, visibility_type: str): + """Sets the visibility_type of this AppManifestNetworkInterfaces. + + Defines whether the interface is exposed to outer world or not i.e., external, or internal. If this is set to \"external\", then it is exposed to external applications otherwise it is exposed internally to edge application components within edge cloud. When exposed to external world, an external dynamic port is assigned for UC traffic and mapped to the extPort # noqa: E501 + + :param visibility_type: The visibility_type of this AppManifestNetworkInterfaces. + :type visibility_type: str + """ + allowed_values = ["VISIBILITY_EXTERNAL", "VISIBILITY_INTERNAL"] # noqa: E501 + if visibility_type not in allowed_values: + raise ValueError( + "Invalid value for `visibility_type` ({0}), must be one of {1}" + .format(visibility_type, allowed_values) + ) + + self._visibility_type = visibility_type diff --git a/swagger_server/models/app_zones.py b/swagger_server/models/app_zones.py new file mode 100644 index 0000000000000000000000000000000000000000..79e81e9105b15670112b17475134018e3e6aedb0 --- /dev/null +++ b/swagger_server/models/app_zones.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.edge_cloud_zone import EdgeCloudZone # noqa: F401,E501 +from swagger_server import util + + +class AppZones(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """AppZones - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'AppZones': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The AppZones of this AppZones. # noqa: E501 + :rtype: AppZones + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/base_model_.py b/swagger_server/models/base_model_.py new file mode 100644 index 0000000000000000000000000000000000000000..97999c3d3237c287013b2139acb9858a52b454e8 --- /dev/null +++ b/swagger_server/models/base_model_.py @@ -0,0 +1,69 @@ +import pprint + +import six +import typing + +from swagger_server import util + +T = typing.TypeVar('T') + + +class Model(object): + # swaggerTypes: The key is attribute name and the + # value is attribute type. + swagger_types = {} + + # attributeMap: The key is attribute name and the + # value is json key in definition. + attribute_map = {} + + @classmethod + def from_dict(cls: typing.Type[T], dikt) -> T: + """Returns the dict as a model""" + return util.deserialize_model(dikt, cls) + + def to_dict(self): + """Returns the model properties as a dict + + :rtype: dict + """ + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """Returns the string representation of the model + + :rtype: str + """ + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/swagger_server/models/edge_cloud_provider.py b/swagger_server/models/edge_cloud_provider.py new file mode 100644 index 0000000000000000000000000000000000000000..4e14675d1f5390350b9afd117d77edbf4902b2ea --- /dev/null +++ b/swagger_server/models/edge_cloud_provider.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class EdgeCloudProvider(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """EdgeCloudProvider - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudProvider': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudProvider of this EdgeCloudProvider. # noqa: E501 + :rtype: EdgeCloudProvider + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/edge_cloud_region.py b/swagger_server/models/edge_cloud_region.py new file mode 100644 index 0000000000000000000000000000000000000000..2ae421c29fceff42632cda31d6d84286fad37340 --- /dev/null +++ b/swagger_server/models/edge_cloud_region.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class EdgeCloudRegion(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """EdgeCloudRegion - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudRegion': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudRegion of this EdgeCloudRegion. # noqa: E501 + :rtype: EdgeCloudRegion + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/edge_cloud_zone.py b/swagger_server/models/edge_cloud_zone.py new file mode 100644 index 0000000000000000000000000000000000000000..bbcd8a7770ffe1c5a0788e84075b155d20cc3368 --- /dev/null +++ b/swagger_server/models/edge_cloud_zone.py @@ -0,0 +1,171 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.edge_cloud_provider import EdgeCloudProvider # noqa: F401,E501 +from swagger_server.models.edge_cloud_region import EdgeCloudRegion # noqa: F401,E501 +from swagger_server.models.edge_cloud_zone_id import EdgeCloudZoneId # noqa: F401,E501 +from swagger_server.models.edge_cloud_zone_name import EdgeCloudZoneName # noqa: F401,E501 +from swagger_server.models.edge_cloud_zone_status import EdgeCloudZoneStatus # noqa: F401,E501 +from swagger_server import util + + +class EdgeCloudZone(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, edge_cloud_zone_id: EdgeCloudZoneId=None, edge_cloud_zone_name: EdgeCloudZoneName=None, edge_cloud_zone_status: EdgeCloudZoneStatus=None, edge_cloud_provider: EdgeCloudProvider=None, edge_cloud_region: EdgeCloudRegion=None): # noqa: E501 + """EdgeCloudZone - a model defined in Swagger + + :param edge_cloud_zone_id: The edge_cloud_zone_id of this EdgeCloudZone. # noqa: E501 + :type edge_cloud_zone_id: EdgeCloudZoneId + :param edge_cloud_zone_name: The edge_cloud_zone_name of this EdgeCloudZone. # noqa: E501 + :type edge_cloud_zone_name: EdgeCloudZoneName + :param edge_cloud_zone_status: The edge_cloud_zone_status of this EdgeCloudZone. # noqa: E501 + :type edge_cloud_zone_status: EdgeCloudZoneStatus + :param edge_cloud_provider: The edge_cloud_provider of this EdgeCloudZone. # noqa: E501 + :type edge_cloud_provider: EdgeCloudProvider + :param edge_cloud_region: The edge_cloud_region of this EdgeCloudZone. # noqa: E501 + :type edge_cloud_region: EdgeCloudRegion + """ + self.swagger_types = { + 'edge_cloud_zone_id': EdgeCloudZoneId, + 'edge_cloud_zone_name': EdgeCloudZoneName, + 'edge_cloud_zone_status': EdgeCloudZoneStatus, + 'edge_cloud_provider': EdgeCloudProvider, + 'edge_cloud_region': EdgeCloudRegion + } + + self.attribute_map = { + 'edge_cloud_zone_id': 'edgeCloudZoneId', + 'edge_cloud_zone_name': 'edgeCloudZoneName', + 'edge_cloud_zone_status': 'edgeCloudZoneStatus', + 'edge_cloud_provider': 'edgeCloudProvider', + 'edge_cloud_region': 'edgeCloudRegion' + } + self._edge_cloud_zone_id = edge_cloud_zone_id + self._edge_cloud_zone_name = edge_cloud_zone_name + self._edge_cloud_zone_status = edge_cloud_zone_status + self._edge_cloud_provider = edge_cloud_provider + self._edge_cloud_region = edge_cloud_region + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudZone': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudZone of this EdgeCloudZone. # noqa: E501 + :rtype: EdgeCloudZone + """ + return util.deserialize_model(dikt, cls) + + @property + def edge_cloud_zone_id(self) -> EdgeCloudZoneId: + """Gets the edge_cloud_zone_id of this EdgeCloudZone. + + + :return: The edge_cloud_zone_id of this EdgeCloudZone. + :rtype: EdgeCloudZoneId + """ + return self._edge_cloud_zone_id + + @edge_cloud_zone_id.setter + def edge_cloud_zone_id(self, edge_cloud_zone_id: EdgeCloudZoneId): + """Sets the edge_cloud_zone_id of this EdgeCloudZone. + + + :param edge_cloud_zone_id: The edge_cloud_zone_id of this EdgeCloudZone. + :type edge_cloud_zone_id: EdgeCloudZoneId + """ + + self._edge_cloud_zone_id = edge_cloud_zone_id + + @property + def edge_cloud_zone_name(self) -> EdgeCloudZoneName: + """Gets the edge_cloud_zone_name of this EdgeCloudZone. + + + :return: The edge_cloud_zone_name of this EdgeCloudZone. + :rtype: EdgeCloudZoneName + """ + return self._edge_cloud_zone_name + + @edge_cloud_zone_name.setter + def edge_cloud_zone_name(self, edge_cloud_zone_name: EdgeCloudZoneName): + """Sets the edge_cloud_zone_name of this EdgeCloudZone. + + + :param edge_cloud_zone_name: The edge_cloud_zone_name of this EdgeCloudZone. + :type edge_cloud_zone_name: EdgeCloudZoneName + """ + + self._edge_cloud_zone_name = edge_cloud_zone_name + + @property + def edge_cloud_zone_status(self) -> EdgeCloudZoneStatus: + """Gets the edge_cloud_zone_status of this EdgeCloudZone. + + + :return: The edge_cloud_zone_status of this EdgeCloudZone. + :rtype: EdgeCloudZoneStatus + """ + return self._edge_cloud_zone_status + + @edge_cloud_zone_status.setter + def edge_cloud_zone_status(self, edge_cloud_zone_status: EdgeCloudZoneStatus): + """Sets the edge_cloud_zone_status of this EdgeCloudZone. + + + :param edge_cloud_zone_status: The edge_cloud_zone_status of this EdgeCloudZone. + :type edge_cloud_zone_status: EdgeCloudZoneStatus + """ + + self._edge_cloud_zone_status = edge_cloud_zone_status + + @property + def edge_cloud_provider(self) -> EdgeCloudProvider: + """Gets the edge_cloud_provider of this EdgeCloudZone. + + + :return: The edge_cloud_provider of this EdgeCloudZone. + :rtype: EdgeCloudProvider + """ + return self._edge_cloud_provider + + @edge_cloud_provider.setter + def edge_cloud_provider(self, edge_cloud_provider: EdgeCloudProvider): + """Sets the edge_cloud_provider of this EdgeCloudZone. + + + :param edge_cloud_provider: The edge_cloud_provider of this EdgeCloudZone. + :type edge_cloud_provider: EdgeCloudProvider + """ + + self._edge_cloud_provider = edge_cloud_provider + + @property + def edge_cloud_region(self) -> EdgeCloudRegion: + """Gets the edge_cloud_region of this EdgeCloudZone. + + + :return: The edge_cloud_region of this EdgeCloudZone. + :rtype: EdgeCloudRegion + """ + return self._edge_cloud_region + + @edge_cloud_region.setter + def edge_cloud_region(self, edge_cloud_region: EdgeCloudRegion): + """Sets the edge_cloud_region of this EdgeCloudZone. + + + :param edge_cloud_region: The edge_cloud_region of this EdgeCloudZone. + :type edge_cloud_region: EdgeCloudRegion + """ + + self._edge_cloud_region = edge_cloud_region diff --git a/swagger_server/models/edge_cloud_zone_id.py b/swagger_server/models/edge_cloud_zone_id.py new file mode 100644 index 0000000000000000000000000000000000000000..0528c908f2c3741efcaab9b350ef9be9fc1dc301 --- /dev/null +++ b/swagger_server/models/edge_cloud_zone_id.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class EdgeCloudZoneId(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """EdgeCloudZoneId - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudZoneId': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudZoneId of this EdgeCloudZoneId. # noqa: E501 + :rtype: EdgeCloudZoneId + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/edge_cloud_zone_name.py b/swagger_server/models/edge_cloud_zone_name.py new file mode 100644 index 0000000000000000000000000000000000000000..c1ab9283a3f76678bae5b7a2719cab1c2583562a --- /dev/null +++ b/swagger_server/models/edge_cloud_zone_name.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class EdgeCloudZoneName(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """EdgeCloudZoneName - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudZoneName': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudZoneName of this EdgeCloudZoneName. # noqa: E501 + :rtype: EdgeCloudZoneName + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/edge_cloud_zone_status.py b/swagger_server/models/edge_cloud_zone_status.py new file mode 100644 index 0000000000000000000000000000000000000000..f60d1bea8acbeb5fded23adc522402e48d8b0b3a --- /dev/null +++ b/swagger_server/models/edge_cloud_zone_status.py @@ -0,0 +1,43 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class EdgeCloudZoneStatus(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + """ + allowed enum values + """ + ACTIVE = "active" + INACTIVE = "inactive" + UNKNOWN = "unknown" + def __init__(self): # noqa: E501 + """EdgeCloudZoneStatus - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudZoneStatus': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudZoneStatus of this EdgeCloudZoneStatus. # noqa: E501 + :rtype: EdgeCloudZoneStatus + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/edge_cloud_zones.py b/swagger_server/models/edge_cloud_zones.py new file mode 100644 index 0000000000000000000000000000000000000000..0e087f8afa3daa8e386d5db4b9c5dd8f0958c5df --- /dev/null +++ b/swagger_server/models/edge_cloud_zones.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.edge_cloud_zone import EdgeCloudZone # noqa: F401,E501 +from swagger_server import util + + +class EdgeCloudZones(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """EdgeCloudZones - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'EdgeCloudZones': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The EdgeCloudZones of this EdgeCloudZones. # noqa: E501 + :rtype: EdgeCloudZones + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/error_info.py b/swagger_server/models/error_info.py new file mode 100644 index 0000000000000000000000000000000000000000..253b046ff9db3201e5db1fab6434b7405b88cafe --- /dev/null +++ b/swagger_server/models/error_info.py @@ -0,0 +1,126 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class ErrorInfo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, status: int=None, code: str=None, message: str=None): # noqa: E501 + """ErrorInfo - a model defined in Swagger + + :param status: The status of this ErrorInfo. # noqa: E501 + :type status: int + :param code: The code of this ErrorInfo. # noqa: E501 + :type code: str + :param message: The message of this ErrorInfo. # noqa: E501 + :type message: str + """ + self.swagger_types = { + 'status': int, + 'code': str, + 'message': str + } + + self.attribute_map = { + 'status': 'status', + 'code': 'code', + 'message': 'message' + } + self._status = status + self._code = code + self._message = message + + @classmethod + def from_dict(cls, dikt) -> 'ErrorInfo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The ErrorInfo of this ErrorInfo. # noqa: E501 + :rtype: ErrorInfo + """ + return util.deserialize_model(dikt, cls) + + @property + def status(self) -> int: + """Gets the status of this ErrorInfo. + + HTTP status code returned along with this error response # noqa: E501 + + :return: The status of this ErrorInfo. + :rtype: int + """ + return self._status + + @status.setter + def status(self, status: int): + """Sets the status of this ErrorInfo. + + HTTP status code returned along with this error response # noqa: E501 + + :param status: The status of this ErrorInfo. + :type status: int + """ + if status is None: + raise ValueError("Invalid value for `status`, must not be `None`") # noqa: E501 + + self._status = status + + @property + def code(self) -> str: + """Gets the code of this ErrorInfo. + + Code given to this error # noqa: E501 + + :return: The code of this ErrorInfo. + :rtype: str + """ + return self._code + + @code.setter + def code(self, code: str): + """Sets the code of this ErrorInfo. + + Code given to this error # noqa: E501 + + :param code: The code of this ErrorInfo. + :type code: str + """ + if code is None: + raise ValueError("Invalid value for `code`, must not be `None`") # noqa: E501 + + self._code = code + + @property + def message(self) -> str: + """Gets the message of this ErrorInfo. + + Detailed error description # noqa: E501 + + :return: The message of this ErrorInfo. + :rtype: str + """ + return self._message + + @message.setter + def message(self, message: str): + """Sets the message of this ErrorInfo. + + Detailed error description # noqa: E501 + + :param message: The message of this ErrorInfo. + :type message: str + """ + if message is None: + raise ValueError("Invalid value for `message`, must not be `None`") # noqa: E501 + + self._message = message diff --git a/swagger_server/models/fqdn.py b/swagger_server/models/fqdn.py new file mode 100644 index 0000000000000000000000000000000000000000..5d00b3a06f521a6843179b58a101b3ba3a6283b1 --- /dev/null +++ b/swagger_server/models/fqdn.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class Fqdn(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """Fqdn - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'Fqdn': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Fqdn of this Fqdn. # noqa: E501 + :rtype: Fqdn + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/gpu_info.py b/swagger_server/models/gpu_info.py new file mode 100644 index 0000000000000000000000000000000000000000..b480f2b50b34c379bf786f368b54681cf5374bff --- /dev/null +++ b/swagger_server/models/gpu_info.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class GpuInfo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, gpu_memory: int=None, num_gpu: int=None): # noqa: E501 + """GpuInfo - a model defined in Swagger + + :param gpu_memory: The gpu_memory of this GpuInfo. # noqa: E501 + :type gpu_memory: int + :param num_gpu: The num_gpu of this GpuInfo. # noqa: E501 + :type num_gpu: int + """ + self.swagger_types = { + 'gpu_memory': int, + 'num_gpu': int + } + + self.attribute_map = { + 'gpu_memory': 'gpuMemory', + 'num_gpu': 'numGPU' + } + self._gpu_memory = gpu_memory + self._num_gpu = num_gpu + + @classmethod + def from_dict(cls, dikt) -> 'GpuInfo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The GpuInfo of this GpuInfo. # noqa: E501 + :rtype: GpuInfo + """ + return util.deserialize_model(dikt, cls) + + @property + def gpu_memory(self) -> int: + """Gets the gpu_memory of this GpuInfo. + + GPU memory in mega bytes # noqa: E501 + + :return: The gpu_memory of this GpuInfo. + :rtype: int + """ + return self._gpu_memory + + @gpu_memory.setter + def gpu_memory(self, gpu_memory: int): + """Sets the gpu_memory of this GpuInfo. + + GPU memory in mega bytes # noqa: E501 + + :param gpu_memory: The gpu_memory of this GpuInfo. + :type gpu_memory: int + """ + if gpu_memory is None: + raise ValueError("Invalid value for `gpu_memory`, must not be `None`") # noqa: E501 + + self._gpu_memory = gpu_memory + + @property + def num_gpu(self) -> int: + """Gets the num_gpu of this GpuInfo. + + Number of GPUs # noqa: E501 + + :return: The num_gpu of this GpuInfo. + :rtype: int + """ + return self._num_gpu + + @num_gpu.setter + def num_gpu(self, num_gpu: int): + """Sets the num_gpu of this GpuInfo. + + Number of GPUs # noqa: E501 + + :param num_gpu: The num_gpu of this GpuInfo. + :type num_gpu: int + """ + if num_gpu is None: + raise ValueError("Invalid value for `num_gpu`, must not be `None`") # noqa: E501 + + self._num_gpu = num_gpu diff --git a/swagger_server/models/inline_response200.py b/swagger_server/models/inline_response200.py new file mode 100644 index 0000000000000000000000000000000000000000..a2621cd8b69267902c1f1cbd6b18ada59b7ee998 --- /dev/null +++ b/swagger_server/models/inline_response200.py @@ -0,0 +1,63 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_manifest import AppManifest # noqa: F401,E501 +from swagger_server import util + + +class InlineResponse200(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, app_manifest: AppManifest=None): # noqa: E501 + """InlineResponse200 - a model defined in Swagger + + :param app_manifest: The app_manifest of this InlineResponse200. # noqa: E501 + :type app_manifest: AppManifest + """ + self.swagger_types = { + 'app_manifest': AppManifest + } + + self.attribute_map = { + 'app_manifest': 'appManifest' + } + self._app_manifest = app_manifest + + @classmethod + def from_dict(cls, dikt) -> 'InlineResponse200': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The inline_response_200 of this InlineResponse200. # noqa: E501 + :rtype: InlineResponse200 + """ + return util.deserialize_model(dikt, cls) + + @property + def app_manifest(self) -> AppManifest: + """Gets the app_manifest of this InlineResponse200. + + + :return: The app_manifest of this InlineResponse200. + :rtype: AppManifest + """ + return self._app_manifest + + @app_manifest.setter + def app_manifest(self, app_manifest: AppManifest): + """Sets the app_manifest of this InlineResponse200. + + + :param app_manifest: The app_manifest of this InlineResponse200. + :type app_manifest: AppManifest + """ + + self._app_manifest = app_manifest diff --git a/swagger_server/models/inline_response2001.py b/swagger_server/models/inline_response2001.py new file mode 100644 index 0000000000000000000000000000000000000000..fed1a2969cd2e55a5d53b3e98ab8018ca54fd9ad --- /dev/null +++ b/swagger_server/models/inline_response2001.py @@ -0,0 +1,63 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_instance_info import AppInstanceInfo # noqa: F401,E501 +from swagger_server import util + + +class InlineResponse2001(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, app_instace_info: List[AppInstanceInfo]=None): # noqa: E501 + """InlineResponse2001 - a model defined in Swagger + + :param app_instace_info: The app_instace_info of this InlineResponse2001. # noqa: E501 + :type app_instace_info: List[AppInstanceInfo] + """ + self.swagger_types = { + 'app_instace_info': List[AppInstanceInfo] + } + + self.attribute_map = { + 'app_instace_info': 'appInstaceInfo' + } + self._app_instace_info = app_instace_info + + @classmethod + def from_dict(cls, dikt) -> 'InlineResponse2001': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The inline_response_200_1 of this InlineResponse2001. # noqa: E501 + :rtype: InlineResponse2001 + """ + return util.deserialize_model(dikt, cls) + + @property + def app_instace_info(self) -> List[AppInstanceInfo]: + """Gets the app_instace_info of this InlineResponse2001. + + + :return: The app_instace_info of this InlineResponse2001. + :rtype: List[AppInstanceInfo] + """ + return self._app_instace_info + + @app_instace_info.setter + def app_instace_info(self, app_instace_info: List[AppInstanceInfo]): + """Sets the app_instace_info of this InlineResponse2001. + + + :param app_instace_info: The app_instace_info of this InlineResponse2001. + :type app_instace_info: List[AppInstanceInfo] + """ + + self._app_instace_info = app_instace_info diff --git a/swagger_server/models/inline_response202.py b/swagger_server/models/inline_response202.py new file mode 100644 index 0000000000000000000000000000000000000000..5dabcabb16be962c4b2ef2754a1f5feff3f063e2 --- /dev/null +++ b/swagger_server/models/inline_response202.py @@ -0,0 +1,63 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_instance_info import AppInstanceInfo # noqa: F401,E501 +from swagger_server import util + + +class InlineResponse202(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, app_instaces: List[AppInstanceInfo]=None): # noqa: E501 + """InlineResponse202 - a model defined in Swagger + + :param app_instaces: The app_instaces of this InlineResponse202. # noqa: E501 + :type app_instaces: List[AppInstanceInfo] + """ + self.swagger_types = { + 'app_instaces': List[AppInstanceInfo] + } + + self.attribute_map = { + 'app_instaces': 'appInstaces' + } + self._app_instaces = app_instaces + + @classmethod + def from_dict(cls, dikt) -> 'InlineResponse202': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The inline_response_202 of this InlineResponse202. # noqa: E501 + :rtype: InlineResponse202 + """ + return util.deserialize_model(dikt, cls) + + @property + def app_instaces(self) -> List[AppInstanceInfo]: + """Gets the app_instaces of this InlineResponse202. + + + :return: The app_instaces of this InlineResponse202. + :rtype: List[AppInstanceInfo] + """ + return self._app_instaces + + @app_instaces.setter + def app_instaces(self, app_instaces: List[AppInstanceInfo]): + """Sets the app_instaces of this InlineResponse202. + + + :param app_instaces: The app_instaces of this InlineResponse202. + :type app_instaces: List[AppInstanceInfo] + """ + + self._app_instaces = app_instaces diff --git a/swagger_server/models/ipv4_addr.py b/swagger_server/models/ipv4_addr.py new file mode 100644 index 0000000000000000000000000000000000000000..d47d1dbdbb952f80e1b75cf691686deaf3d110dd --- /dev/null +++ b/swagger_server/models/ipv4_addr.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class Ipv4Addr(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """Ipv4Addr - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'Ipv4Addr': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Ipv4Addr of this Ipv4Addr. # noqa: E501 + :rtype: Ipv4Addr + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/ipv6_addr.py b/swagger_server/models/ipv6_addr.py new file mode 100644 index 0000000000000000000000000000000000000000..83a5259fa5a4ce04704eab1ac9e6144decfaf9b8 --- /dev/null +++ b/swagger_server/models/ipv6_addr.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class Ipv6Addr(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """Ipv6Addr - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'Ipv6Addr': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Ipv6Addr of this Ipv6Addr. # noqa: E501 + :rtype: Ipv6Addr + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/operating_system.py b/swagger_server/models/operating_system.py new file mode 100644 index 0000000000000000000000000000000000000000..b732e86eaa52efc3f9008664d89c77564e11b889 --- /dev/null +++ b/swagger_server/models/operating_system.py @@ -0,0 +1,172 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class OperatingSystem(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, architecture: str=None, family: str=None, version: str=None, license: str=None): # noqa: E501 + """OperatingSystem - a model defined in Swagger + + :param architecture: The architecture of this OperatingSystem. # noqa: E501 + :type architecture: str + :param family: The family of this OperatingSystem. # noqa: E501 + :type family: str + :param version: The version of this OperatingSystem. # noqa: E501 + :type version: str + :param license: The license of this OperatingSystem. # noqa: E501 + :type license: str + """ + self.swagger_types = { + 'architecture': str, + 'family': str, + 'version': str, + 'license': str + } + + self.attribute_map = { + 'architecture': 'architecture', + 'family': 'family', + 'version': 'version', + 'license': 'license' + } + self._architecture = architecture + self._family = family + self._version = version + self._license = license + + @classmethod + def from_dict(cls, dikt) -> 'OperatingSystem': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The OperatingSystem of this OperatingSystem. # noqa: E501 + :rtype: OperatingSystem + """ + return util.deserialize_model(dikt, cls) + + @property + def architecture(self) -> str: + """Gets the architecture of this OperatingSystem. + + Type of the OS Architecture # noqa: E501 + + :return: The architecture of this OperatingSystem. + :rtype: str + """ + return self._architecture + + @architecture.setter + def architecture(self, architecture: str): + """Sets the architecture of this OperatingSystem. + + Type of the OS Architecture # noqa: E501 + + :param architecture: The architecture of this OperatingSystem. + :type architecture: str + """ + allowed_values = ["x86_64", "x86"] # noqa: E501 + if architecture not in allowed_values: + raise ValueError( + "Invalid value for `architecture` ({0}), must be one of {1}" + .format(architecture, allowed_values) + ) + + self._architecture = architecture + + @property + def family(self) -> str: + """Gets the family of this OperatingSystem. + + Family to which OS belongs # noqa: E501 + + :return: The family of this OperatingSystem. + :rtype: str + """ + return self._family + + @family.setter + def family(self, family: str): + """Sets the family of this OperatingSystem. + + Family to which OS belongs # noqa: E501 + + :param family: The family of this OperatingSystem. + :type family: str + """ + allowed_values = ["RHEL", "UBUNTU", "COREOS", "WINDOWS", "OTHER"] # noqa: E501 + if family not in allowed_values: + raise ValueError( + "Invalid value for `family` ({0}), must be one of {1}" + .format(family, allowed_values) + ) + + self._family = family + + @property + def version(self) -> str: + """Gets the version of this OperatingSystem. + + Version of the OS # noqa: E501 + + :return: The version of this OperatingSystem. + :rtype: str + """ + return self._version + + @version.setter + def version(self, version: str): + """Sets the version of this OperatingSystem. + + Version of the OS # noqa: E501 + + :param version: The version of this OperatingSystem. + :type version: str + """ + allowed_values = ["OS_VERSION_UBUNTU_2204_LTS", "OS_VERSION_RHEL_8", "OS_MS_WINDOWS_2022", "OTHER"] # noqa: E501 + if version not in allowed_values: + raise ValueError( + "Invalid value for `version` ({0}), must be one of {1}" + .format(version, allowed_values) + ) + + self._version = version + + @property + def license(self) -> str: + """Gets the license of this OperatingSystem. + + License needed to activate the OS # noqa: E501 + + :return: The license of this OperatingSystem. + :rtype: str + """ + return self._license + + @license.setter + def license(self, license: str): + """Sets the license of this OperatingSystem. + + License needed to activate the OS # noqa: E501 + + :param license: The license of this OperatingSystem. + :type license: str + """ + allowed_values = ["OS_LICENSE_TYPE_FREE", "OS_LICENSE_TYPE_ON_DEMAND", "OTHER"] # noqa: E501 + if license not in allowed_values: + raise ValueError( + "Invalid value for `license` ({0}), must be one of {1}" + .format(license, allowed_values) + ) + + self._license = license diff --git a/swagger_server/models/port.py b/swagger_server/models/port.py new file mode 100644 index 0000000000000000000000000000000000000000..458b7f3efa89fd2e5e782d4c9cb0a4127d5822d3 --- /dev/null +++ b/swagger_server/models/port.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class Port(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """Port - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'Port': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Port of this Port. # noqa: E501 + :rtype: Port + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/models/required_resources.py b/swagger_server/models/required_resources.py new file mode 100644 index 0000000000000000000000000000000000000000..42bf7a498b04d38bbd2af6ce701effd19fdf4a03 --- /dev/null +++ b/swagger_server/models/required_resources.py @@ -0,0 +1,155 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.gpu_info import GpuInfo # noqa: F401,E501 +from swagger_server import util + + +class RequiredResources(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, num_cpu: int=None, memory: int=None, storage: int=None, gpu: List[GpuInfo]=None): # noqa: E501 + """RequiredResources - a model defined in Swagger + + :param num_cpu: The num_cpu of this RequiredResources. # noqa: E501 + :type num_cpu: int + :param memory: The memory of this RequiredResources. # noqa: E501 + :type memory: int + :param storage: The storage of this RequiredResources. # noqa: E501 + :type storage: int + :param gpu: The gpu of this RequiredResources. # noqa: E501 + :type gpu: List[GpuInfo] + """ + self.swagger_types = { + 'num_cpu': int, + 'memory': int, + 'storage': int, + 'gpu': List[GpuInfo] + } + + self.attribute_map = { + 'num_cpu': 'numCPU', + 'memory': 'memory', + 'storage': 'storage', + 'gpu': 'gpu' + } + self._num_cpu = num_cpu + self._memory = memory + self._storage = storage + self._gpu = gpu + + @classmethod + def from_dict(cls, dikt) -> 'RequiredResources': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The RequiredResources of this RequiredResources. # noqa: E501 + :rtype: RequiredResources + """ + return util.deserialize_model(dikt, cls) + + @property + def num_cpu(self) -> int: + """Gets the num_cpu of this RequiredResources. + + Number of virtual CPUs # noqa: E501 + + :return: The num_cpu of this RequiredResources. + :rtype: int + """ + return self._num_cpu + + @num_cpu.setter + def num_cpu(self, num_cpu: int): + """Sets the num_cpu of this RequiredResources. + + Number of virtual CPUs # noqa: E501 + + :param num_cpu: The num_cpu of this RequiredResources. + :type num_cpu: int + """ + if num_cpu is None: + raise ValueError("Invalid value for `num_cpu`, must not be `None`") # noqa: E501 + + self._num_cpu = num_cpu + + @property + def memory(self) -> int: + """Gets the memory of this RequiredResources. + + Memory in giga bytes # noqa: E501 + + :return: The memory of this RequiredResources. + :rtype: int + """ + return self._memory + + @memory.setter + def memory(self, memory: int): + """Sets the memory of this RequiredResources. + + Memory in giga bytes # noqa: E501 + + :param memory: The memory of this RequiredResources. + :type memory: int + """ + if memory is None: + raise ValueError("Invalid value for `memory`, must not be `None`") # noqa: E501 + + self._memory = memory + + @property + def storage(self) -> int: + """Gets the storage of this RequiredResources. + + Storage in giga bytes # noqa: E501 + + :return: The storage of this RequiredResources. + :rtype: int + """ + return self._storage + + @storage.setter + def storage(self, storage: int): + """Sets the storage of this RequiredResources. + + Storage in giga bytes # noqa: E501 + + :param storage: The storage of this RequiredResources. + :type storage: int + """ + if storage is None: + raise ValueError("Invalid value for `storage`, must not be `None`") # noqa: E501 + + self._storage = storage + + @property + def gpu(self) -> List[GpuInfo]: + """Gets the gpu of this RequiredResources. + + Number of GPUs # noqa: E501 + + :return: The gpu of this RequiredResources. + :rtype: List[GpuInfo] + """ + return self._gpu + + @gpu.setter + def gpu(self, gpu: List[GpuInfo]): + """Sets the gpu of this RequiredResources. + + Number of GPUs # noqa: E501 + + :param gpu: The gpu of this RequiredResources. + :type gpu: List[GpuInfo] + """ + + self._gpu = gpu diff --git a/swagger_server/models/submitted_app.py b/swagger_server/models/submitted_app.py new file mode 100644 index 0000000000000000000000000000000000000000..b099ca4e82182fd18cd6225c9e6c047538653683 --- /dev/null +++ b/swagger_server/models/submitted_app.py @@ -0,0 +1,63 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server.models.app_id import AppId # noqa: F401,E501 +from swagger_server import util + + +class SubmittedApp(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self, app_id: AppId=None): # noqa: E501 + """SubmittedApp - a model defined in Swagger + + :param app_id: The app_id of this SubmittedApp. # noqa: E501 + :type app_id: AppId + """ + self.swagger_types = { + 'app_id': AppId + } + + self.attribute_map = { + 'app_id': 'appId' + } + self._app_id = app_id + + @classmethod + def from_dict(cls, dikt) -> 'SubmittedApp': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The SubmittedApp of this SubmittedApp. # noqa: E501 + :rtype: SubmittedApp + """ + return util.deserialize_model(dikt, cls) + + @property + def app_id(self) -> AppId: + """Gets the app_id of this SubmittedApp. + + + :return: The app_id of this SubmittedApp. + :rtype: AppId + """ + return self._app_id + + @app_id.setter + def app_id(self, app_id: AppId): + """Sets the app_id of this SubmittedApp. + + + :param app_id: The app_id of this SubmittedApp. + :type app_id: AppId + """ + + self._app_id = app_id diff --git a/swagger_server/models/uri.py b/swagger_server/models/uri.py new file mode 100644 index 0000000000000000000000000000000000000000..aabb7905716dff555e1105506cdedbf0c5110b87 --- /dev/null +++ b/swagger_server/models/uri.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from swagger_server.models.base_model_ import Model +from swagger_server import util + + +class Uri(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + def __init__(self): # noqa: E501 + """Uri - a model defined in Swagger + + """ + self.swagger_types = { + } + + self.attribute_map = { + } + + @classmethod + def from_dict(cls, dikt) -> 'Uri': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Uri of this Uri. # noqa: E501 + :rtype: Uri + """ + return util.deserialize_model(dikt, cls) diff --git a/swagger_server/schema_mappers/__init__.py b/swagger_server/schema_mappers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/swagger_server/schema_mappers/application_instantiation_mapper.py b/swagger_server/schema_mappers/application_instantiation_mapper.py new file mode 100644 index 0000000000000000000000000000000000000000..a93effa946c296817c51ee59ee46c5628a1affe2 --- /dev/null +++ b/swagger_server/schema_mappers/application_instantiation_mapper.py @@ -0,0 +1,54 @@ +import re +from types import SimpleNamespace + + +def remove_special_characters(input_string: str): + """ + Removes all special characters from the input string. + + Parameters: + input_string (str): The string from which to remove special characters. + + Returns: + str: A string with special characters removed. + """ + # Use regex to replace any character that is not alphanumeric or a space + cleaned_string = re.sub(r"[^a-zA-Z0-9\s]", "", input_string) + return cleaned_string + + +def map_to_pi_edge_deployed_service_function( + input: SimpleNamespace, input_service_function_name: str +): + """ + Converts the CAMARA application instantiation input JSON schema to the desired output format for Pi Edge deployed Service Function. + + Args: + input (SimpleNamespace): A dictionary CAMARA application instantiation information. + + Returns: + dict: The mapped dictionary in the desired format. + + Example Input: + { + "edge_cloud_zone_id": "2243ab4-9886-4e5f-a4a8-f792e0d633ae", + "edge_cloud_zone_name": "test-location", + "edge_cloud_zone_status": "active", + "edge_cloud_provider": "Intracom SA Telecom Solution", + "edge_cloud_region": "GR-ATH" + } + + Example Output: + { + "service_function_name": "nginx-demo", + "service_function_instance_name": "nginxdemo", + "location": "test-location" + } + """ + return { + "service_function_name": input_service_function_name, + "service_function_instance_name": remove_special_characters( + f'{input_service_function_name}{input.edge_cloud_zone_name}' + ), + "location": input.edge_cloud_zone_name, + } diff --git a/swagger_server/schema_mappers/edge_cloud_mapper.py b/swagger_server/schema_mappers/edge_cloud_mapper.py new file mode 100644 index 0000000000000000000000000000000000000000..18008ef43848d1e6773c47509cce77fea3432cc4 --- /dev/null +++ b/swagger_server/schema_mappers/edge_cloud_mapper.py @@ -0,0 +1,35 @@ +def map_to_edge_cloud(input: dict): + """ + Converts the input JSON schema to the desired output format for Edge Cloud Zone. + + Args: + input (dict): A dictionary containing edge cloud zone information. + + Returns: + dict: The mapped dictionary in the desired format. + + Example Input: + { + "_id": "2243ab4-9886-4e5f-a4a8-f792e0d633ae", + "location": "test-location", + "name": "eerpcext-k8s", + "node_type": "server", + "serial": "128.3.43.5" + } + + Example Output: + { + "edgeCloudZoneId": "2243ab4-9886-4e5f-a4a8-f792e0d633ae", + "edgeCloudZoneName": "test-location", + "edgeCloudZoneStatus": "active", + "edgeCloudProvider": "Intracom SA Telecom Solution", + "edgeCloudRegion": "GR-ATH" + } + """ + return { + "edgeCloudZoneId": input.get("_id"), + "edgeCloudZoneName": input.get("location"), + "edgeCloudZoneStatus": "active", + "edgeCloudProvider": "", + "edgeCloudRegion": "", + } diff --git a/swagger_server/services/pi_edge_services.py b/swagger_server/services/pi_edge_services.py new file mode 100644 index 0000000000000000000000000000000000000000..6ac94eb178ed00ce2470cd92ae60047db870603f --- /dev/null +++ b/swagger_server/services/pi_edge_services.py @@ -0,0 +1,209 @@ +import requests +from swagger_server.configs.logger_config import logger +from requests.exceptions import Timeout, ConnectionError +from swagger_server.configs.env_config import ( + PI_EDGE_BASE_URL, + PI_EDGE_PASSWORD, + PI_EDGE_USERNAME, + HTTP_PROXY, +) + + +proxies = { + "http": HTTP_PROXY, + "https": HTTP_PROXY, +} + + +class PiEdgeAPIClient: + def __init__(self, base_url, username, password): + self.base_url = base_url + self.username = username + self.password = password + self.token = None + self.requests_session = self._get_proxy_session(proxies) + + def _get_proxy_session(self, session_proxies): + session = requests.Session() + session.proxies.update(session_proxies) + return session + + def _authenticate(self): + """ + Private method to login and obtain an authentication token. + This is automatically called when headers are required and token is missing. + """ + login_url = f"{self.base_url}/authentication" + credentials = {"username": self.username, "password": self.password} + + try: + response = self.requests_session.post( + login_url, + json=credentials, + # proxies=proxies, + ) + response.raise_for_status() + + # Assuming the token is in the response JSON with key 'access_token' + self.token = response.json().get("token") + if not self.token: + raise ValueError("Login failed: No token found") + except requests.exceptions.HTTPError as http_err: + logger.error(f"HTTP error occurred: {http_err}") + except Exception as err: + logger.error(f"Error occurred: {err}") + + def _get_headers(self): + """ + Helper function to return the authorization headers with token. + If token is not available, automatically login. + """ + if not self.token: + self._authenticate() + + return { + "Authorization": f"Bearer {self.token}", + "Content-Type": "application/json", + } + + def get_service_functions_catalogue(self): + """ + Get service function catalogue from the /serviceFunction endpoint. + """ + url = f"{self.base_url}/serviceFunction" + try: + request_headers = self._get_headers() + response = self.requests_session.get(url, headers=request_headers) + response.raise_for_status() + service_functions = response.json() + if isinstance(service_functions, list): + return service_functions + raise ValueError("Unexpected response from Pi Edge Server") + + except Timeout: + return { + "error": "The request to the external API timed out. Please try again later." + } + + except ConnectionError: + return { + "error": "Failed to connect to the external API service. Service might be unavailable." + } + + except requests.exceptions.HTTPError as http_err: + return { + "error": f"HTTP error occurred: {http_err}.", + "status_code": response.status_code, + } + + except ValueError as val_err: + return {"error": str(val_err)} + + except Exception as err: + return {"error": f"An unexpected error occurred: {err}"} + + def deploy_service_function(self, data: list): + """ + Post data to the /deployedServiceFunction endpoint. + """ + url = f"{self.base_url}/deployedServiceFunction" + try: + response = self.requests_session.post( + url, json=data, headers=self._get_headers() + ) + response.raise_for_status() + except Timeout: + return { + "error": "The request to the external API timed out. Please try again later." + } + + except ConnectionError: + return { + "error": "Failed to connect to the external API service. Service might be unavailable." + } + + except requests.exceptions.HTTPError as http_err: + return { + "error": f"HTTP error occurred: {http_err}.", + "status_code": response.status_code, + } + + except Exception as err: + return {"error": f"An unexpected error occurred: {err}"} + + def edge_cloud_zones(self): + """ + Get list of edge zones from /node endpoint. + """ + url = f"{self.base_url}/node" + try: + request_headers = self._get_headers() + response = self.requests_session.get(url, headers=request_headers) + response.raise_for_status() + nodes = response.json().get("nodes") + if not nodes: + raise ValueError("No edge nodes found") + return nodes + + except Timeout: + return { + "error": "The request to the external API timed out. Please try again later." + } + + except ConnectionError: + return { + "error": "Failed to connect to the external API service. Service might be unavailable." + } + + except requests.exceptions.HTTPError as http_err: + return { + "error": f"HTTP error occurred: {http_err}.", + "status_code": response.status_code, + } + + except ValueError as val_err: + return {"error": str(val_err)} + + except Exception as err: + return {"error": f"An unexpected error occurred: {err}"} + + +class PiEdgeAPIClientFactory: + """ + Factory class to create instances of PiEdgeAPIClient. + """ + + def __init__(self): + self.default_base_url = PI_EDGE_BASE_URL + self.default_username = PI_EDGE_USERNAME + self.default_password = PI_EDGE_PASSWORD + + def create_pi_edge_api_client(self, base_url=None, username=None, password=None): + """ + Factory method to create a new PiEdgeAPIClient instance. + + Args: + base_url (str): The base URL for the PiEdge API. If None, the default is used. + username (str): The username for authentication. If None, the default is used. + password (str): The password for authentication. If None, the default is used. + + Returns: + PiEdgeAPIClient: A new instance of the PiEdgeAPIClient. + """ + if base_url is None: + base_url = self.default_base_url + if username is None: + username = self.default_username + if password is None: + password = self.default_password + + return PiEdgeAPIClient(base_url=base_url, username=username, password=password) + + +if __name__ == "__main__": + + pi_edge_factory = PiEdgeAPIClientFactory() + api_client = pi_edge_factory.create_pi_edge_api_client() + + edge_zones = api_client.edge_cloud_zones() + logger.error("Edge zones:", edge_zones) diff --git a/swagger_server/swagger/swagger.yaml b/swagger_server/swagger/swagger.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f0bcae0e114778a2c17dc26baf367a04ce3c4c25 --- /dev/null +++ b/swagger_server/swagger/swagger.yaml @@ -0,0 +1,1974 @@ +openapi: 3.0.3 +info: + title: Edge Application Management API + description: | + Edge Application Management API allows API consumers to manage the + Life Cycle of an Application and to Discover Edge Cloud Zones. + # Overview + The reference scenario foresees a distributed Telco Edge Cloud where any + Application Delevoper, known as an Application Provider, can host and + deploy their application according to their specifications and operational + criteria (e.g. within an specific geographical zone for data protection + purposes, ensure a minimum QoS for the application clients, etc). + Through Telco Edge Cloud services Developers around the globe can be + benefit from the traditional Cloud strengths but expertise and advantages + of the Mobile Network Operators offering to their users an evolved + experience for XR, V2X, Holographic and other new services. + + # Introduction + The Edge Application Management API provides capabilities for lifecycle + management of application, instances and edge cloud zone discovery. + Lifecycle Management allows Application Provider to onboard + their application to the Edge Cloud Platform which do bookkeeping, + resource validation and other pre-deployment operations. + Application details can contain components network specification, + package type (QCOW2, OVA, CONTAINER, HELM), operating system details and + respository to download the image of the desired application. + Once the application is available on the Edge Cloud + Platform, the Application Provider can instantiate the application. + Edge Cloud Provider helps Application Provider to decide where to + instantiate the applications allowing them to retrieve a list of + Edge Cloud Zones that meets the provided criteria. + + This discovery can be filtered by an specific geographical region + (e.g when data residency is need) and by status (active, inactive, unknown) + Application Provider can ask the Edge Cloud Platform to instantiate the + application to one or several Edge Cloud Zones that meet the criteria. + Typically when more than one Edge Cloud Zone is required in the same + geographic boundary, Application Provider can define instead + the entire Edge Cloud Region. + + Application Provider can retrieve the information of the instances + for a given application, the information could be the Edge Cloud Zone + where the instance is, status (ready, instantiating, failed, + terminating, unknown) and endpoint (ip, port, fqdn). + Application Provider can terminate an instance of an application + (appInstanceId) or all the instances for a given appId. + + # Quick Start + The usage of this API is based on several resources including GSMA + Edge Platform, Public Cloud and SDOs, to define a first approach on the + lifecycle management of application instances and edge cloud zones discovery + + Before starting to use the API, the developer needs to know about + the below specified details. + + __Application Management__ + * __submitApp__ - Submits application details to an Edge Cloud Provider. + Based on the details provided, Edge Cloud Provider shall do bookkeeping, + resource validation and other pre-deployment operations. + * __deleteApp__ - Removes an application from an Edge Cloud Provider, + if there is a running instance of the given application, + the request cannot be done. + * __getApp__ - Retrieves the information of a given application. + + __Application Instance Management__ + * __createAppInstance__ Request the Edge Cloud Provider to instatiate + an instance of an application in a given Edge Cloud Zone, + if this parameter is not set, the Edge Cloud Provider will instantiate + the applications in all the Edge Cloud Zones. + * __getAppInstance__ Retrieves the list with information of the instances + related to a given application. + * __deleteAppInstance__ - Removes a given application instance from an Edge + Cloud Zone. + + __Edge Cloud information__ + * __getEdgeCloudZones__ List of the operators Edge Cloud Zones and their + status, ordering the results by location and filtering by status + (active/inactive/unknown) + + # Authentication and Authorization + CAMARA guidelines defines a set of authorization flows which can grant API + clients access to the API functionality, as outlined in the document + [CAMARA-API-access-and-user-consent.md](https://github.com/camaraproject\ + /IdentityAndConsentManagement/blob/main/documentation/CAMARA-API-access\ + -and-user-consent.md). + Which specific authorization flows are to be used will be determined during + onboarding process, happening between the API Client and the Telco Edge + exposing the API, taking into account the declared purpose for accessing the + API, while also being subject to the prevailing legal framework dictated by + local legislation. + + It is important to remark that in cases where personal user data is + processed by the API, and users can exercise their rights through mechanisms + such as opt-in and/or opt-out, the use of 3-legged access tokens becomes + mandatory. This measure ensures that the API remains in strict compliance + with user privacy preferences and regulatory obligations, upholding the + principles of transparency and user-centric data control. + # API documentation + Two operations have been defined in Edge Application Management API. + + *__Application__* - The Application Provider submit application metadata to + the Edge Cloud Platform. The Edge Cloud Platform generates an appId for that + metadata that will be used to instantiate the application within + the Edge Cloud Zone. + + *__Edge Cloud__* - Retrieves all the Edge Cloud Zones available according to + some defined parameters where an application can be instantiated. + + Definitions of terminologies commonly referred + to throughout the API descriptions. + * __Application Provider__ - The provider of the application that accesses + an Edge Cloud Provider to deploy its application on the Edge Cloud. + An Application Provider may be part of a larger organisation, + like an enterprise, enterprise customer of an Edge Cloud Provider, + or be an independent entity. + * __Application__ - Contains the information about the application to be + instantiated. Descriptor, binary image, charts or any other package + assosiated with the application. The Application Provider request contains + mandatory criteria (e.g. required CPU, memory, storage, bandwidth) defined + in an Application. The Edge Cloud Platform generates a unique ID + for an Application that is ready to be instantiated. + * __Application Instance__ - Is an instance (VM or Container based) running + in an Edge Cloud Zone. The Edge Cloud Platform generates a unique ID + for each instance. + * __Edge Cloud__ - Cloud-like capabilities located at the network edge + including, from the Application Provider's perspective, access to + elastically allocated compute, data storage and network resources, + this access is provided through the Edge Cloud Platform. + * __Edge Cloud Provider__ - Company name of the provider offering the + Edge Services through the Edge Cloud Platform. + Could be an Operator or a Cloud Provider. + * __Edge Cloud Region__ - An Edge Cloud Region is equivalent + to a Region on a Public Cloud. + The higher construct in the hierarchy exposed to an Application + Provider who wishes to deploy an Application on the Edge Cloud and broadly + represents a geography. An Edge CloudRegion typically contains one or + multiple Edge Cloud Zones. + An Edge Cloud Region exists within an Edge Cloud. + * __Edge Cloud Zone__ - An Edge Cloud Zone is the lowest level of + abstraction exposed to an Application Provider who wants to deploy + an Application on Edge Cloud. + Edge Cloud Zones exists within a Edge Cloud Region. + --- + contact: + email: sp-edc@lists.camaraproject.org + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: 0.9.3-wip +externalDocs: + description: Product documentation at Camara + url: https://github.com/camaraproject/EdgeCloud +servers: +- url: "{apiRoot}/{basePath}" + variables: + apiRoot: + description: API root + default: http://localhost:8080 + basePath: + description: Base path for the Edge Application Management API + default: edge-application-management +tags: +- name: Application + description: Application and Application Instance Lice Cycle Management +- name: Edge Cloud + description: Edge Cloud Zones Availability +paths: + /apps: + post: + tags: + - Application + summary: Submit application metadata to the Edge Cloud Provider. + description: | + Contains the information about the application to be + instantiated in the Edge Cloud + operationId: submit_app + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + requestBody: + description: | + The Application Provider request contains mandatory + criteria (e.g. required CPU, memory, storage, bandwidth) and + optional parameters. + content: + application/json: + schema: + $ref: '#/components/schemas/AppManifest' + required: true + responses: + "201": + description: Application created successfully + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/SubmittedApp' + "400": + description: Bad request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 400 + code: INVALID_ARGUMENT + message: Schema validation failed at ... + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "409": + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 409 + code: CONFLICT + message: App already exists + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "501": + description: Not Implemented + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 501 + code: NOT_IMPLEMENTED + message: Service not implemented + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:apps:write + x-openapi-router-controller: swagger_server.controllers.application_controller + /apps/{appId}: + get: + tags: + - Application + summary: Retrieve the information of an Application + description: | + Ask the Edge Cloud Provider the information for a given application + operationId: get_app + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: appId + in: path + description: | + A globally unique identifier associated with the + application. + Edge Cloud Provider generates this identifier when the application + is submitted. + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppId' + responses: + "200": + description: Information of Application + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/inline_response_200' + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:apps:read + x-openapi-router-controller: swagger_server.controllers.application_controller + delete: + tags: + - Application + summary: | + Delete an Application from an Edge Cloud Provider + description: Delete all the information and content related to an Application + operationId: delete_app + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: appId + in: path + description: | + Identificator of the application to be + deleted provided by the Edge Cloud Provider + once the submission was successful + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppId' + responses: + "202": + description: Request accepted + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + "204": + description: App deleted + "400": + description: Bad request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 400 + code: INVALID_ARGUMENT + message: Schema validation failed at ... + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "409": + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 409 + code: CONFLICT + message: App with a running application instance cannot be deleted + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:apps:delete + x-openapi-router-controller: swagger_server.controllers.application_controller + /apps/{appId}/instances: + get: + tags: + - Application + summary: Retrieve the information of Application Instances for a given App + description: | + Ask the Edge Cloud Provider the information of the instances for a + given application + operationId: get_app_instance + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: appId + in: path + description: | + A globally unique identifier associated with + the application. + Edge Cloud Provider generates this identifier when the + application is submitted. + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppId' + - name: appInstanceId + in: query + description: | + A globally unique identifier associated with a running + instance of an application within an specific Edge Cloud Zone. + Edge Cloud Provider generates this identifier. + required: false + style: form + explode: true + schema: + $ref: '#/components/schemas/AppInstanceId' + - name: region + in: query + description: | + Human readable name of the geographical Edge Cloud Region of + the Edge Cloud. Defined by the Edge Cloud Provider. + required: false + style: form + explode: true + schema: + $ref: '#/components/schemas/EdgeCloudRegion' + responses: + "200": + description: Information of Application Instances + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/inline_response_200_1' + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:instances:read + x-openapi-router-controller: swagger_server.controllers.application_controller + post: + tags: + - Application + summary: Instantiation of an Application + description: | + Ask the Edge Cloud Platform to instantiate an application to one + or several Edge Cloud Zones with an Application as an input and an + Application Instance as the output. + operationId: create_app_instance + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: appId + in: path + description: | + A globally unique identifier associated with the + application. Edge Cloud Provider generates this identifier when + the application is submitted. + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppId' + requestBody: + description: Array of Edge Cloud Zone + content: + application/json: + schema: + $ref: '#/components/schemas/AppZones' + required: true + responses: + "202": + description: Application instantiation accepted + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + Location: + description: Contains the URI of the newly created application. + required: true + style: simple + explode: false + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/inline_response_202' + "400": + description: Bad request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 400 + code: INVALID_ARGUMENT + message: Schema validation failed at ... + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "409": + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 409 + code: CONFLICT + message: Application already instantiated in the given Edge Cloud + Zone or Edge Cloud Region + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "501": + description: Not Implemented + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 501 + code: NOT_IMPLEMENTED + message: Service not implemented + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:instances:write + x-openapi-router-controller: swagger_server.controllers.application_controller + /apps/{appId}/instances/{appInstanceId}: + delete: + tags: + - Application + summary: Terminate an Application Instance + description: | + Terminate a running instance of an application within + an Edge Cloud Zone + operationId: delete_app_instance + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: appId + in: path + description: | + A globally unique identifier associated with the + application. Edge Cloud Provider generates this identifier + when the application is submitted. + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppId' + - name: appInstanceId + in: path + description: | + Identificator of the specific application instance + that will be terminated + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/AppInstanceId' + responses: + "202": + description: | + Request accepted to be processed. It applies for async + deletion process + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + "204": + description: Application Instance Deleted + "400": + description: Bad request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 400 + code: INVALID_ARGUMENT + message: Schema validation failed at ... + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:instances:delete + x-openapi-router-controller: swagger_server.controllers.application_controller + /edge-cloud-zones: + get: + tags: + - Edge Cloud + summary: Retrieve a list of the operators Edge Cloud Zones and their status + description: | + List of the operators Edge Cloud Zones and their + status, ordering the results by location and filtering by + status (active/inactive/unknown) + operationId: get_edge_cloud_zones + parameters: + - name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + - name: region + in: query + description: | + Human readable name of the geographical Edge Cloud Region of + the Edge Cloud. Defined by the Edge Cloud Provider. + required: false + style: form + explode: true + schema: + $ref: '#/components/schemas/EdgeCloudRegion' + - name: status + in: query + description: Human readable status of the Edge Cloud Zone + required: false + style: form + explode: true + schema: + $ref: '#/components/schemas/EdgeCloudZoneStatus' + responses: + "200": + description: | + Successful response, returning the + Available Edge Cloud Zones. + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/EdgeCloudZones' + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + # security: + # - openId: + # - edge-application-management:edge-cloud-zones:read + x-openapi-router-controller: swagger_server.controllers.edge_cloud_controller +components: + schemas: + AccessEndpoint: + required: + - port + type: object + properties: + port: + $ref: '#/components/schemas/Port' + fqdn: + $ref: '#/components/schemas/Fqdn' + ipv4Addresses: + minItems: 1 + type: array + description: IP version 4 of an application instance + items: + $ref: '#/components/schemas/Ipv4Addr' + ipv6Addresses: + minItems: 1 + type: array + description: IP version 6 of an application instance. + items: + $ref: '#/components/schemas/Ipv6Addr' + description: | + Application Endpoint for an especific instance that is + running in an specific Edge Cloud Zone. + example: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + anyOf: + - required: + - fqdn + - required: + - ipv4Addresses + - required: + - ipv6Addresses + AppId: + type: string + description: | + A globally unique identifier associated with the application. + Edge Cloud Platform generates this identifier when the + Application is submitted. + format: uuid + AppInstanceId: + type: string + description: | + A globally unique identifier associated with a running + instance of an application. + Edge Cloud Platform generates this identifier when the + instantiation in the Edge Cloud Zone is successful. + format: uuid + AppInstanceInfo: + type: object + properties: + appInstanceId: + $ref: '#/components/schemas/AppInstanceId' + status: + type: string + description: Status of the application instance (default is 'unknown') + default: unknown + enum: + - ready + - instantiating + - failed + - terminating + - unknown + componentEndpointInfo: + minItems: 1 + type: array + description: | + Information about the IP and Port exposed by the + Edge Cloud Platform. + Application Client shall use these access points to reach this + application instance + items: + $ref: '#/components/schemas/AppInstanceInfo_componentEndpointInfo' + edgeCloudZone: + $ref: '#/components/schemas/EdgeCloudZone' + description: Information about the application instance. + example: + appInstanceId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + componentEndpointInfo: + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + edgeCloudZone: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + status: unknown + AppZones: + minItems: 1 + type: array + additionalProperties: false + description: | + Collection of Edge Cloud Zones where the Application Provider wants to + instantiate the application. + items: + $ref: '#/components/schemas/EdgeCloudZone' + AppManifest: + required: + - appRepo + - componentSpec + - name + - packageType + - requiredResources + - version + properties: + name: + pattern: "^[A-Za-z][A-Za-z0-9_]{1,63}$" + type: string + description: Name of the application. + version: + type: integer + description: Application version information + packageType: + type: string + description: Format of the application image package + enum: + - QCOW2 + - OVA + - CONTAINER + - HELM + operatingSystem: + $ref: '#/components/schemas/OperatingSystem' + appRepo: + $ref: '#/components/schemas/AppManifest_appRepo' + requiredResources: + $ref: '#/components/schemas/RequiredResources' + componentSpec: + type: array + description: | + Information defined in "appRepo" point to the application + descriptor e.g. Helm chart, docker-compose yaml file etc. + The descriptor may contain one or more containers and their + associated meta-data. A component refers to additional details + about these containers to expose the instances of the containers + to external client applications. App provider can define one or + more components (via the associated network port) in componentSpec + corresponding to the containers in helm charts or docker-compose + yaml file as part of app descriptors. + items: + $ref: '#/components/schemas/AppManifest_componentSpec' + description: | + Application information and requirements provided by the + Application Provider + example: + name: name + version: 0 + packageType: QCOW2 + operatingSystem: + license: OS_LICENSE_TYPE_FREE + family: RHEL + version: OS_VERSION_UBUNTU_2204_LTS + architecture: x86_64 + requiredResources: + memory: 10 + numCPU: 1 + storage: 60 + gpu: + - gpuMemory: 6 + numGPU: 1 + - gpuMemory: 6 + numGPU: 1 + componentSpec: + - networkInterfaces: + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + componentName: componentName + - networkInterfaces: + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + componentName: componentName + appRepo: + credentials: credentials + imagePath: https://charts.bitnami.com/bitnami/helm/example-chart:0.1.0 + checksum: checksum + type: PRIVATEREPO + userName: userName + authType: DOCKER + EdgeCloudProvider: + type: string + description: Human readable name of the Edge Cloud Provider. + EdgeCloudRegion: + type: string + description: | + Human readable name of the geographical Edge Cloud Region of + the Edge Cloud. Defined by the Edge Cloud Provider. + EdgeCloudZones: + minItems: 1 + type: array + additionalProperties: false + description: | + A collection of Edge Cloud Zones where the Application Provider can + instantiate an Application Instance. + items: + $ref: '#/components/schemas/EdgeCloudZone' + EdgeCloudZoneId: + type: string + description: | + Unique identifier created by the Edge Cloud Platform to identify an + Edge Cloud Zone within an Edge Cloud. + format: uuid + EdgeCloudZone: + minItems: 1 + type: object + properties: + edgeCloudZoneId: + $ref: '#/components/schemas/EdgeCloudZoneId' + edgeCloudZoneName: + $ref: '#/components/schemas/EdgeCloudZoneName' + edgeCloudZoneStatus: + $ref: '#/components/schemas/EdgeCloudZoneStatus' + edgeCloudProvider: + $ref: '#/components/schemas/EdgeCloudProvider' + edgeCloudRegion: + $ref: '#/components/schemas/EdgeCloudRegion' + description: | + An Edge Cloud Zone, uniquely identified by a + combination of the value of the Edge Cloud Zone Id object + and the value of the Edge Cloud Provider + object. This value is used to identify an Edge Cloud zone + between Edge Clouds from different Edge Cloud Providers. + example: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + EdgeCloudZoneName: + type: string + description: | + Human readable name of the geographical zone of + the Edge Cloud. Defined by the Edge Cloud Provider. + EdgeCloudZoneStatus: + type: string + description: Status of the Edge Cloud Zone (default is 'unknown') + default: unknown + enum: + - active + - inactive + - unknown + ErrorInfo: + required: + - code + - message + - status + type: object + properties: + status: + type: integer + description: HTTP status code returned along with this error response + code: + type: string + description: Code given to this error + message: + type: string + description: Detailed error description + description: Information about the error + Fqdn: + type: string + description: | + Full qualified domain name of an application instance + GpuInfo: + required: + - gpuMemory + - numGPU + type: object + properties: + gpuMemory: + type: integer + description: GPU memory in mega bytes + numGPU: + type: integer + description: Number of GPUs + description: Information about the supported GPUs + example: + gpuMemory: 6 + numGPU: 1 + Ipv4Addr: + type: string + description: | + IP of the device. A single IPv4 address may be specified in + dotted-quad form 1.2.3.4. Only this exact IP number will match the flow + control rule. + format: ipv4 + example: 192.168.0.1 + Ipv6Addr: + type: string + description: | + IP of the device. A single IPv6 address, following IETF 5952 + format, may be specified like 2001:db8:85a3:8d3:1319:8a2e:370:7344 + format: ipv6 + example: 2001:db8:85a3:8d3:1319:8a2e:370:7344 + OperatingSystem: + required: + - architecture + - family + - license + - version + type: object + properties: + architecture: + type: string + description: Type of the OS Architecture + example: x86_64 + enum: + - x86_64 + - x86 + family: + type: string + description: Family to which OS belongs + enum: + - RHEL + - UBUNTU + - COREOS + - WINDOWS + - OTHER + version: + type: string + description: Version of the OS + enum: + - OS_VERSION_UBUNTU_2204_LTS + - OS_VERSION_RHEL_8 + - OS_MS_WINDOWS_2022 + - OTHER + license: + type: string + description: License needed to activate the OS + enum: + - OS_LICENSE_TYPE_FREE + - OS_LICENSE_TYPE_ON_DEMAND + - OTHER + description: | + Information about the Operating System of the application image + example: + license: OS_LICENSE_TYPE_FREE + family: RHEL + version: OS_VERSION_UBUNTU_2204_LTS + architecture: x86_64 + Port: + minimum: 0 + type: integer + description: Port to stablish the connection + RequiredResources: + required: + - memory + - numCPU + - storage + type: object + properties: + numCPU: + type: integer + description: Number of virtual CPUs + example: 1 + memory: + type: integer + description: Memory in giga bytes + example: 10 + storage: + type: integer + description: Storage in giga bytes + example: 60 + gpu: + type: array + description: Number of GPUs + items: + $ref: '#/components/schemas/GpuInfo' + description: | + Fundamental hardware requirements to be provisioned by the + Application Provider. + example: + memory: 10 + numCPU: 1 + storage: 60 + gpu: + - gpuMemory: 6 + numGPU: 1 + - gpuMemory: 6 + numGPU: 1 + SubmittedApp: + type: object + properties: + appId: + $ref: '#/components/schemas/AppId' + description: Information about the submitted app + example: + appId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + Uri: + type: string + description: | + A Uniform Resource Identifier (URI) as per RFC 3986, + identifies the endpoint within an Edge Cloud Zone where the user + equipment may connect to the selected application instance + example: https://charts.bitnami.com/bitnami/helm/example-chart:0.1.0 + inline_response_200: + type: object + properties: + appManifest: + $ref: '#/components/schemas/AppManifest' + example: + appManifest: + name: name + version: 0 + packageType: QCOW2 + operatingSystem: + license: OS_LICENSE_TYPE_FREE + family: RHEL + version: OS_VERSION_UBUNTU_2204_LTS + architecture: x86_64 + requiredResources: + memory: 10 + numCPU: 1 + storage: 60 + gpu: + - gpuMemory: 6 + numGPU: 1 + - gpuMemory: 6 + numGPU: 1 + componentSpec: + - networkInterfaces: + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + componentName: componentName + - networkInterfaces: + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + componentName: componentName + appRepo: + credentials: credentials + imagePath: https://charts.bitnami.com/bitnami/helm/example-chart:0.1.0 + checksum: checksum + type: PRIVATEREPO + userName: userName + authType: DOCKER + inline_response_200_1: + minItems: 1 + type: object + properties: + appInstaceInfo: + type: array + items: + $ref: '#/components/schemas/AppInstanceInfo' + example: + appInstaceInfo: + - appInstanceId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + componentEndpointInfo: + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + edgeCloudZone: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + status: unknown + - appInstanceId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + componentEndpointInfo: + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + edgeCloudZone: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + status: unknown + inline_response_202: + minItems: 1 + type: object + properties: + appInstaces: + type: array + items: + $ref: '#/components/schemas/AppInstanceInfo' + example: + appInstaces: + - appInstanceId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + componentEndpointInfo: + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + edgeCloudZone: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + status: unknown + - appInstanceId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + componentEndpointInfo: + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + edgeCloudZone: + edgeCloudProvider: edgeCloudProvider + edgeCloudZoneStatus: unknown + edgeCloudRegion: edgeCloudRegion + edgeCloudZoneId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + edgeCloudZoneName: edgeCloudZoneName + status: unknown + AppInstanceInfo_componentEndpointInfo: + required: + - accessPoints + - interfaceId + type: object + properties: + interfaceId: + pattern: "^[A-Za-z0-9][A-Za-z0-9_]{6,30}[A-Za-z0-9]$" + type: string + description: | + This is the interface Identifier that Application Provider + defines when application is being submitted. + accessPoints: + $ref: '#/components/schemas/AccessEndpoint' + example: + interfaceId: interfaceId + accessPoints: + ipv4Addresses: + - 192.168.0.1 + - 192.168.0.1 + port: 0 + fqdn: fqdn + ipv6Addresses: + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + - 2001:db8:85a3:8d3:1319:8a2e:370:7344 + AppManifest_appRepo: + required: + - imagePath + - type + type: object + properties: + type: + type: string + description: | + Application repository and image URI information. + PUBLICREPO is used of public urls like github, helm repo etc. + PRIVATEREPO is used for private repo managed by the application + developer. Private repo can be accessed by using the app + developer provided userName and password. Password is + recommended to be the personal access token created by developer + e.g. in Github repo. + enum: + - PRIVATEREPO + - PUBLICREPO + imagePath: + $ref: '#/components/schemas/Uri' + userName: + type: string + description: | + Username to acces the Helm chart, docker-compose + file or VM image repository + credentials: + maxLength: 128 + type: string + description: | + Password or personal access token created by + developer to acces the app repository. API users can generate + a personal access token e.g. docker clients to use them as + password. + authType: + type: string + description: | + The credentials can also be formatted as a Basic + auth or Bearer auth in HTTP "Authorization" header. + enum: + - DOCKER + - HTTP_BASIC + - HTTP_BEARER + - NONE + checksum: + type: string + description: | + MD5 checksum for VM and file-based images, sha256 + digest for containers + description: | + Repository where Application Provider stores the application image + example: + credentials: credentials + imagePath: https://charts.bitnami.com/bitnami/helm/example-chart:0.1.0 + checksum: checksum + type: PRIVATEREPO + userName: userName + authType: DOCKER + AppManifest_networkInterfaces: + required: + - interfaceId + - port + - protocol + - visibilityType + type: object + properties: + interfaceId: + pattern: "^[A-Za-z][A-Za-z0-9_]{3,31}$" + type: string + description: | + Each Port and corresponding traffic protocol + exposed by the component is identified by a name. + Application client on user device requires this to + uniquley idenify the interface. + protocol: + type: string + description: | + Defines the IP transport communication + protocol i.e., TCP, UDP or ANY + enum: + - TCP + - UDP + - ANY + port: + maximum: 65535 + minimum: 1 + type: integer + description: | + Port number exposed by the component. + Edge Cloud Provider may generate a dynamic port + towards the component instance which forwards + external traffic to the component port. + format: int32 + visibilityType: + type: string + description: | + Defines whether the interface is exposed + to outer world or not i.e., external, or internal. + If this is set to "external", then it is exposed + to external applications otherwise it is exposed + internally to edge application components within + edge cloud. When exposed to external world, + an external dynamic port is assigned for UC traffic + and mapped to the extPort + enum: + - VISIBILITY_EXTERNAL + - VISIBILITY_INTERNAL + example: + protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + AppManifest_componentSpec: + required: + - componentName + - networkInterfaces + type: object + properties: + componentName: + type: string + description: Component name must be unique with an application + networkInterfaces: + minItems: 1 + type: array + description: | + Each application component exposes some ports + either for external users or for inter component + communication. + Application provider is required to specify which ports are + to be exposed and the type of traffic that will flow through + these ports.The underlying platform may assign a dynamic port + against the "extPort" that the application clients will use + to connect with edge application instance. + items: + $ref: '#/components/schemas/AppManifest_networkInterfaces' + example: + networkInterfaces: + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + - protocol: TCP + port: 39073 + interfaceId: interfaceId + visibilityType: VISIBILITY_EXTERNAL + componentName: componentName + responses: + "400": + description: Bad request + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 400 + code: INVALID_ARGUMENT + message: Schema validation failed at ... + "401": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 401 + code: UNAUTHENTICATED + message: "Authorization failed: ..." + "403": + description: Unauthorized + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 403 + code: PERMISSION_DENIED + message: "Operation not allowed: ..." + "404": + description: Not Found + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 404 + code: NOT_FOUND + message: Resource does not exist + "500": + description: Internal Server Error + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 500 + code: INTERNAL + message: "Internal server error: ..." + "501": + description: Not Implemented + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 501 + code: NOT_IMPLEMENTED + message: Service not implemented + "503": + description: Service Unavailable + headers: + x-correlator: + $ref: '#/components/headers/x-correlator' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInfo' + example: + status: 503 + code: UNAVAILABLE + message: Service unavailable + parameters: + x-correlator: + name: x_correlator + in: header + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + headers: + x-correlator: + description: | + Correlation id for the different services + required: false + style: simple + explode: false + schema: + type: string + format: uuid + # securitySchemes: + # openId: + # type: openIdConnect + # description: OpenID Provider Configuration Information. + # openIdConnectUrl: https://example.com/.well-known/openid-configuration + diff --git a/swagger_server/test/__init__.py b/swagger_server/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..644506301ce077f2e881fcda3454b6cba362ab5e --- /dev/null +++ b/swagger_server/test/__init__.py @@ -0,0 +1,16 @@ +import logging + +import connexion +from flask_testing import TestCase + +from swagger_server.encoder import JSONEncoder + + +class BaseTestCase(TestCase): + + def create_app(self): + logging.getLogger('connexion.operation').setLevel('ERROR') + app = connexion.App(__name__, specification_dir='../swagger/') + app.app.json_encoder = JSONEncoder + app.add_api('swagger.yaml') + return app.app diff --git a/swagger_server/test/test_application_controller.py b/swagger_server/test/test_application_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..63f4b8fc32de581b8e203e49f05589efe2cf6764 --- /dev/null +++ b/swagger_server/test/test_application_controller.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from swagger_server.models.app_id import AppId # noqa: E501 +from swagger_server.models.app_instance_id import AppInstanceId # noqa: E501 +from swagger_server.models.app_manifest import AppManifest # noqa: E501 +from swagger_server.models.edge_cloud_region import EdgeCloudRegion # noqa: E501 +from swagger_server.models.edge_cloud_zone import EdgeCloudZone # noqa: E501 +from swagger_server.models.error_info import ErrorInfo # noqa: E501 +from swagger_server.models.inline_response200 import InlineResponse200 # noqa: E501 +from swagger_server.models.inline_response2001 import InlineResponse2001 # noqa: E501 +from swagger_server.models.inline_response202 import InlineResponse202 # noqa: E501 +from swagger_server.models.submitted_app import SubmittedApp # noqa: E501 +from swagger_server.test import BaseTestCase + + +class TestApplicationController(BaseTestCase): + """ApplicationController integration test stubs""" + + def test_create_app_instance(self): + """Test case for create_app_instance + + Instantiation of an Application + """ + body = [EdgeCloudZone()] + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps/{appId}/instances'.format(app_id=AppId()), + method='POST', + data=json.dumps(body), + headers=headers, + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_delete_app(self): + """Test case for delete_app + + Delete an Application from an Edge Cloud Provider + """ + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps/{appId}'.format(app_id=AppId()), + method='DELETE', + headers=headers) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_delete_app_instance(self): + """Test case for delete_app_instance + + Terminate an Application Instance + """ + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps/{appId}/instances/{appInstanceId}'.format(app_id=AppId(), app_instance_id=AppInstanceId()), + method='DELETE', + headers=headers) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_app(self): + """Test case for get_app + + Retrieve the information of an Application + """ + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps/{appId}'.format(app_id=AppId()), + method='GET', + headers=headers) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_get_app_instance(self): + """Test case for get_app_instance + + Retrieve the information of Application Instances for a given App + """ + query_string = [('app_instance_id', AppInstanceId()), + ('region', EdgeCloudRegion())] + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps/{appId}/instances'.format(app_id=AppId()), + method='GET', + headers=headers, + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_submit_app(self): + """Test case for submit_app + + Submit application metadata to the Edge Cloud Provider. + """ + body = AppManifest() + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/apps', + method='POST', + data=json.dumps(body), + headers=headers, + content_type='application/json') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/swagger_server/test/test_edge_cloud_controller.py b/swagger_server/test/test_edge_cloud_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..d9dd4a819548adadb3174f83e0f23e2ed4c97a4f --- /dev/null +++ b/swagger_server/test/test_edge_cloud_controller.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from swagger_server.models.edge_cloud_region import EdgeCloudRegion # noqa: E501 +from swagger_server.models.edge_cloud_zone_status import EdgeCloudZoneStatus # noqa: E501 +from swagger_server.models.edge_cloud_zones import EdgeCloudZones # noqa: E501 +from swagger_server.models.error_info import ErrorInfo # noqa: E501 +from swagger_server.test import BaseTestCase + + +class TestEdgeCloudController(BaseTestCase): + """EdgeCloudController integration test stubs""" + + def test_get_edge_cloud_zones(self): + """Test case for get_edge_cloud_zones + + Retrieve a list of the operators Edge Cloud Zones and their status + """ + query_string = [('region', EdgeCloudRegion()), + ('status', EdgeCloudZoneStatus())] + headers = [('x_correlator', 'x_correlator_example')] + response = self.client.open( + '/edge-cloud-zones', + method='GET', + headers=headers, + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/swagger_server/type_util.py b/swagger_server/type_util.py new file mode 100644 index 0000000000000000000000000000000000000000..0563f81fd5345282a33705038dfa77fdcaa15872 --- /dev/null +++ b/swagger_server/type_util.py @@ -0,0 +1,32 @@ +# coding: utf-8 + +import sys + +if sys.version_info < (3, 7): + import typing + + def is_generic(klass): + """ Determine whether klass is a generic class """ + return type(klass) == typing.GenericMeta + + def is_dict(klass): + """ Determine whether klass is a Dict """ + return klass.__extra__ == dict + + def is_list(klass): + """ Determine whether klass is a List """ + return klass.__extra__ == list + +else: + + def is_generic(klass): + """ Determine whether klass is a generic class """ + return hasattr(klass, '__origin__') + + def is_dict(klass): + """ Determine whether klass is a Dict """ + return klass.__origin__ == dict + + def is_list(klass): + """ Determine whether klass is a List """ + return klass.__origin__ == list diff --git a/swagger_server/util.py b/swagger_server/util.py new file mode 100644 index 0000000000000000000000000000000000000000..812b2ad42f97ee1790ea2019c90710bc4dada114 --- /dev/null +++ b/swagger_server/util.py @@ -0,0 +1,142 @@ +import datetime + +import six +import typing +from swagger_server import type_util + + +def _deserialize(data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if klass in six.integer_types or klass in (float, str, bool, bytearray): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == datetime.date: + return deserialize_date(data) + elif klass == datetime.datetime: + return deserialize_datetime(data) + elif type_util.is_generic(klass): + if type_util.is_list(klass): + return _deserialize_list(data, klass.__args__[0]) + if type_util.is_dict(klass): + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """Deserializes to primitive type. + + :param data: data to deserialize. + :param klass: class literal. + + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = six.u(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """Return an original value. + + :return: object. + """ + return value + + +def deserialize_date(string): + """Deserializes string to date. + + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +def deserialize_model(data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + instance = klass() + + if not instance.swagger_types: + return data + + for attr, attr_type in six.iteritems(instance.swagger_types): + if data is not None \ + and instance.attribute_map[attr] in data \ + and isinstance(data, (list, dict)): + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + return instance + + +def _deserialize_list(data, boxed_type): + """Deserializes a list and its elements. + + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + +def _deserialize_dict(data, boxed_type): + """Deserializes a dict and its elements. + + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + + :return: deserialized dict. + :rtype: dict + """ + return {k: _deserialize(v, boxed_type) + for k, v in six.iteritems(data)} diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..2640639a25a3bffe0f449788303300a364c55cb7 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,7 @@ +flask_testing==0.8.0 +coverage>=4.0.3 +nose>=1.3.7 +pluggy>=0.3.1 +py>=1.4.31 +randomize>=0.13 +tox==3.20.1 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000000000000000000000000000000000..2751b218c1d2385c081c114c9094fc5e388126dc --- /dev/null +++ b/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py38 + +[testenv] +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands= + nosetests \ + [] \ No newline at end of file