diff --git a/.dockerignore b/.dockerignore index 68be2e63a8552b7a998ad4544ae0ff7d91e20adb..0619fdc10a56509b5ac78f274e8425f7c495dd25 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,91 +1,41 @@ -# Git files .git .gitignore .gitlab-ci.yml -# Documentation -README.md CONTRIBUTING.md LICENSE +docs/ -# Docker files Dockerfile docker-compose.yaml +docker-compose.dev.yaml .dockerignore -# Python cache and virtual environments __pycache__/ *.py[cod] -*$py.class *.so -.Python -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ .venv/ -src/__pycache__/ -src/models/__pycache__/ -src/controllers/__pycache__/ -src/clients/__pycache__/ -src/test/__pycache__/ -src/adapters/__pycache__/ -src/api/__pycache__/ -src/adapters/tf_adapter/__pycache__/ -src/adapters/fm_adapter/__pycache__/ +venv/ +*.egg-info/ -# Testing and coverage -.coverage +tests/ .pytest_cache/ +.mypy_cache/ +.ruff_cache/ +.coverage htmlcov/ -.tox/ -.nox/ coverage.xml -*.cover -.hypothesis/ -# IDE and editor files .vscode/ .idea/ *.swp -*.swo *~ - -# OS generated files .DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db -# Logs *.log -logs/ - -# Temporary files -tmp/ -temp/ -*.tmp - -# Node modules (if any) -node_modules/ -npm-debug.log* - -# Configuration files that shouldn't be in the image -src/conf/config.cfg +.log/ *.env -.env.local -.env.development -.env.test -.env.production - -# Log files and directories -*.tgz -src/.log/ - -# Build artifacts +.env.* +tmp/ dist/ -build/ \ No newline at end of file +build/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 676771278dc3dbcb227709f7ffed4c10b140d4d9..fbc07aa1aa3d7202c567de056fd587cd50170a75 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,8 +2,37 @@ # This pipeline builds and pushes Docker images for the federation-manager service stages: + - check - build +# Lint, type-check and test on every push and merge request (issue #10). +check: + stage: check + image: python:3.12 + tags: + - docker + services: + - name: postgres:16-alpine + alias: postgres + - name: nats:2.10-alpine + alias: nats + command: ["-js"] + variables: + POSTGRES_USER: fm + POSTGRES_PASSWORD: fm + POSTGRES_DB: fm_db + FM_POSTGRES_URL: "postgresql+asyncpg://fm:fm@postgres:5432/fm_db" + FM_NATS_URL: "nats://nats:4222" + before_script: + - python -m pip install --upgrade pip + - pip install -e ".[dev]" + script: + - ruff format --check src/federation_manager tests + - ruff check src/federation_manager tests + - mypy + # Keycloak is not available here, so the tests needing it are deselected. + - pytest -q -k "not two_stack" + variables: IMAGE_NAME: federation-manager REGISTRY_IMAGE: $CI_REGISTRY_IMAGE/$IMAGE_NAME diff --git a/Dockerfile b/Dockerfile index 3b5324b6fe71658c62fe208597b71d4ee8768307..41e39da3938a4b88dda01b61dd4fa6c1e94504e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,38 +14,23 @@ # limitations under the License. # # -------------------------------------------------------------------------- # -######################################################### -# # -# Dockerfile for creating a container image for the # -# federation-manager # -# # -######################################################### - -FROM python:3.12 -WORKDIR /usr/app -RUN apt-get update && apt-get install -y \ - bash \ - build-essential \ - git \ - wget \ - iptables \ - libcurl4-openssl-dev \ - libssl-dev \ - && rm -rf /var/lib/apt/lists/* -# Copy application code -COPY . . +FROM python:3.12-slim AS build +WORKDIR /build ARG PIP_INDEX_URL ARG PIP_EXTRA_INDEX_URL ARG PIP_TRUSTED_HOST -# Create pip.conf for indexes RUN mkdir -p /root/.config/pip && \ echo "[global]" > /root/.config/pip/pip.conf && \ if [ -n "$PIP_INDEX_URL" ]; then echo "index-url = ${PIP_INDEX_URL}" >> /root/.config/pip/pip.conf; fi && \ if [ -n "$PIP_EXTRA_INDEX_URL" ]; then echo "extra-index-url = ${PIP_EXTRA_INDEX_URL}" >> /root/.config/pip/pip.conf; fi && \ if [ -n "$PIP_TRUSTED_HOST" ]; then echo "trusted-host = ${PIP_TRUSTED_HOST}" >> /root/.config/pip/pip.conf; fi -# Install Python dependencies -RUN python -m pip install --no-cache-dir -r requirements.txt -WORKDIR /usr/app/src/ -EXPOSE 8989 -# Set Gunicorn as the entrypoint -ENTRYPOINT ["gunicorn", "wsgi:app", "--bind", "0.0.0.0:8989", "--workers", "4", "--log-level", "debug", "--timeout", "1000"] +COPY pyproject.toml README.md ./ +COPY src/ ./src/ +RUN python -m pip install --no-cache-dir --prefix=/install . + +FROM python:3.12-slim +COPY --from=build /install /usr/local +RUN useradd --create-home --uid 10001 fm +USER fm +EXPOSE 8082 +ENTRYPOINT ["uvicorn", "federation_manager.main:app", "--host", "0.0.0.0", "--port", "8082"] diff --git a/Dockerfile.dev b/Dockerfile.dev deleted file mode 100644 index b750f20217e68887d4b8d83306ce45051bc5a8ee..0000000000000000000000000000000000000000 --- a/Dockerfile.dev +++ /dev/null @@ -1,57 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -######################################################### -# # -# Dev Dockerfile for creating a container image # -# for the federation-manager with local TF-SDK # -# # -######################################################### - -FROM python:3.12 -WORKDIR /usr/app -RUN apt-get update && apt-get install -y \ - bash \ - build-essential \ - git \ - wget \ - iptables \ - libcurl4-openssl-dev \ - libssl-dev \ - && rm -rf /var/lib/apt/lists/* - -# Copy local TF-SDK first -COPY ../tf-sdk /tmp/tf-sdk - -# Copy application code -COPY . . - - -# Install local TF-SDK instead of the published version -RUN pip install --no-cache-dir /tmp/tf-sdk - -# Install remaining Python dependencies (TF-SDK will be skipped since already installed) -RUN python -m pip install --no-cache-dir -r requirements.txt \ - --extra-index-url https://labs.etsi.org/rep/api/v4/projects/396/packages/pypi/simple \ - --trusted-host labs.etsi.org - -# Clean up -RUN rm -rf /tmp/tf-sdk - -WORKDIR /usr/app/src/ -EXPOSE 8989 -# Set Gunicorn as the entrypoint -ENTRYPOINT ["gunicorn", "wsgi:app", "--bind", "0.0.0.0:8989", "--workers", "4", "--log-level", "debug", "--timeout", "1000"] diff --git a/README.md b/README.md index 911fd5ce9810a50337b929cbe647729069df07e2..5903913474c21d74d7ff6b5b8db732eaf0ed58dc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Federation Manager** is an open-source Python component implementing the *Federation Management* functionality of the **Operator Platform (OP)**, as defined by the [GSMA Operator Platform Group (OPG)](https://www.gsma.com/solutions-and-impact/technologies/networks/gsma_resources/gsma-operator-platform-group-september-2024-publications/). -This project aligns with the EWBI specifications outlined in the GSMA OPG document *"East-Westbound Interface APIs, (Version 4.0)"*. +This project implements the EWBI specification published by the GSMA OPG as *"East-Westbound Interface APIs"* (**OPG.04 v6.0**), against the OpenAPI contract distributed with that PRD (`OPG.04_EWBI_Federation_API_v1.4.0.yaml`, vendored under `docs/`). ## Description @@ -39,8 +39,8 @@ experiences across markets. ## Compatibility -- Based on GSMA OPG Specifications: **OPG.02-v6.0** — *Operator Platform: Requirements and Architecture* and -**OPG.04-v4.0** — *East-Westbound Interface APIs*. +- Based on GSMA OPG specifications: **OPG.02 v10.0** — *Operator Platform: Requirements and Architecture* — and +**OPG.04 v6.0** — *East-Westbound Interface APIs*. - Designed to work with the Operator Platform core components and peer Federation Managers. ## Getting Started @@ -49,205 +49,73 @@ experiences across markets. - **Python 3.12** or higher - **Docker** and **Docker Compose** -- **Git** - -### Installation - -1. **Clone the repository:** - ```bash - git clone - cd federation-manager - ``` - -2. **Set up configuration:** - ```bash - cp src/conf/config.cfg.sample src/conf/config.cfg - # Edit config.cfg with your specific settings - ``` - -3. **Choose your deployment method:** - -#### Option A: Docker Compose (Recommended) - ```bash - docker compose up -d - ``` - This starts: - - Federation Manager (port 8990) - - MongoDB (port 27017) - - Keycloak (port 8080) - -#### Option B: Local Development - ```bash - # Create virtual environment - python -m venv venv - source venv/bin/activate # On Windows: venv\Scripts\activate - - # Install dependencies - pip install -r requirements.txt - - # Start services - cd src/ - python main.py - ``` - -### Quick Start - -1. **Access the API documentation:** - - Swagger UI: `http://localhost:8990/ui/` - - OpenAPI spec: `http://localhost:8990/openapi.yaml` - -2. **Authentication:** - - Keycloak Admin Console: `http://localhost:8080/admin/` - - Default credentials: `admin/admin` - -3. **Test the API:** - ```bash - curl -X GET http://localhost:8990/operatorplatform/federation/v1/health - ``` - -## Testing - -The Federation Manager includes a comprehensive test suite that validates the **dual role architecture**: - -### Dual Role Testing -The Federation Manager operates in two modes: -- **Partner OP Mode**: Handles external requests (without `X-Internal` header) -- **Originating OP Mode**: Handles internal requests (with `X-Internal` and `X-Partner-API-Root` headers) - -### Running Tests - -1. **Run all tests:** - ```bash - cd src/ - python test/run_all_tests.py --verbose --coverage - ``` - -2. **Test execution order:** - - `federation_management` - - `availability_zone_info_synchronization` - - `artefact_management` - - `application_onboarding_management` - - `application_deployment_management` - -3. **Coverage reports:** - - Terminal output with coverage percentage - - HTML report in `src/htmlcov/` directory - -### Test Architecture - -The test suite validates the complete stack: -``` -API → Adapter → Client → External System -``` - -Each test runs for both operational modes, ensuring: -- ✅ Partner OP functionality (external federation partners) -- ✅ Originating OP functionality (internal service requests) -- ✅ End-to-end integration across all components - -## Development - -### CI/CD Pipeline - -The project includes GitLab CI/CD configuration (`.gitlab-ci.yml`) with: - -- **Build Stage**: Creates and pushes Docker images to GitLab Container Registry - -For detailed CI/CD setup instructions, see [CI_CD_SETUP.md](CI_CD_SETUP.md). - -### Docker Development - -1. **Build the image:** - ```bash - docker build -t federation-manager . - ``` - -2. **Run with custom configuration:** - ```bash - docker run -p 8989:8989 \ - -v ./src/conf/config.cfg:/usr/app/src/conf/config.cfg \ - federation-manager - ``` -3. **Development with docker-compose:** - ```bash - docker-compose -f docker-compose.yaml up --build - ``` +### Run the stack -### Environment Variables - -Key configuration options (set in `src/conf/config.cfg`): +```bash +docker compose up --build +``` -- **Server**: Host, port, and API settings -- **Database**: MongoDB connection parameters -- **Keycloak**: Authentication service configuration -- **Logging**: Log levels and output configuration +That starts Federation Manager on **:8082**, plus PostgreSQL, NATS JetStream and Keycloak. -## Deployment +```bash +curl http://localhost:8082/healthz +``` -### Production Deployment +### Local development -1. **Using Docker Compose:** - ```bash - # Pull latest images - docker-compose pull - - # Start services - docker-compose up -d - - # Monitor logs - docker-compose logs -f federation-manager - ``` +```bash +python -m venv .venv && . .venv/bin/activate +pip install -e ".[dev]" +docker compose -f docker-compose.dev.yaml up -d postgres nats keycloak +uvicorn federation_manager.main:app --reload --port 8082 +``` -2. **Using Kubernetes:** - ```bash - kubectl apply -f src/deploy/ - ``` +### Tests -## API Documentation +```bash +pytest # everything +pytest -m "not integration" # unit tests only, no infrastructure needed +ruff check src tests && mypy +``` -### Swagger UI -Interactive API documentation is available at: -- **Local**: `http://localhost:8990/ui/` -- **API Spec**: `http://localhost:8990/openapi.yaml` +Integration tests need the dev stack above. The FM ↔ SRM loop test additionally needs a running +SRM and skips without one; see `docs/running-srm.md`. -### Key Endpoints +## Configuration -1. **Federation Management**: - - `POST /partner` - Create federation context - - `GET /{federationContextId}` - Get federation details - - `DELETE /{federationContextId}` - Terminate federation +Settings are environment variables with the `FM_` prefix, read by `federation_manager.core.config`. -2. **Zone Management**: - - `POST /{federationContextId}/zones` - Register availability zones - - `GET /{federationContextId}/zones` - List zones +| Variable | Default | Purpose | +|---|---|---| +| `FM_POSTGRES_URL` | `postgresql+asyncpg://fm:fm@localhost:5433/fm_db` | `fm_db` connection | +| `FM_NATS_URL` | `nats://localhost:4222` | DataBus | +| `FM_KEYCLOAK_ISSUER` | `http://localhost:8090/realms/federation` | Inbound token issuer | +| `FM_FEDERATION_ID`, `FM_COUNTRY_CODE`, `FM_MCC`, `FM_MNCS` | — | Our OPG.04 identity, sent on outbound `CreateFederation` | +| `FM_PARTNER_STATUS_LINK` | — | Callback URL advertised to partners | +| `FM_PLATFORM_CAPS` | `["serviceAPIs"]` | Capabilities advertised on federation setup | +| `FM_BOOTSTRAP_FEDERATION` | `false` | Federate with every active partner at startup (ADR-0043) | +| `FM_EVENT_CONSUMER_DURABLE` | `fm-event-worker` | JetStream durable name; must differ per deployment | +| `FM_ALLOW_INSECURE_PARTNER_ENDPOINTS` | `false` | Permit plain-HTTP partner endpoints. **Development only** | -3. **Application Management**: - - `POST /{federationContextId}/artefact` - Upload application artefacts - - `POST /{federationContextId}/applicationonboarding` - Onboard applications - - `POST /{federationContextId}/applicationlcm` - Manage application lifecycle +## API -### Authentication +The partner-facing surface is GSMA OPG.04 v6.0, served under `/operatorplatform/federation/v1`. +Generated OpenAPI is at `/openapi.json`, with Swagger UI at `/docs`. -All API endpoints require OAuth 2.0 Bearer tokens from Keycloak: +`docs/` holds the vendored GSMA artifact, an OpenAPI Overlay recording its known defects, and the +generated profile used for contract checks. Regenerate with: ```bash -# Get access token -curl -X POST http://localhost:8080/realms/federation/protocol/openid-connect/token \ - -H "Content-Type: application/x-www-form-urlencoded" \ - -d "grant_type=client_credentials" \ - -d "client_id=" \ - -d "client_secret=" - -# Use token in API calls -curl -X GET http://localhost:8990/operatorplatform/federation/v1/health \ - -H "Authorization: Bearer " +python scripts/apply_overlay.py ``` +Internal, non-partner endpoints live under `/internal/`; they are not exposed on the EWBI path. + ## Contributing -Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. +See [CONTRIBUTING.md](CONTRIBUTING.md). ## License -This project is licensed under the [Apache 2.0 License](LICENSE). +Apache License 2.0. See [LICENSE](LICENSE). diff --git a/docker-compose.yaml b/docker-compose.yaml index 0a2d64661997ef2d11314a2d6c16d23109f7e6c8..1b5027ecdffd7977abcc7a7ceea6fea4e143350e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,3 @@ -version: '3.8' - services: federation-manager: build: @@ -8,37 +6,55 @@ services: container_name: federation-manager restart: unless-stopped ports: - - "8990:8989" - volumes: - - ./src/conf/config.cfg:/usr/app/src/conf/config.cfg + - "8082:8082" + environment: + FM_POSTGRES_URL: postgresql+asyncpg://fm:fm@postgres:5432/fm_db + FM_NATS_URL: nats://nats:4222 + FM_KEYCLOAK_ISSUER: http://keycloak:8080/realms/federation depends_on: - - mongodb - - keycloak - mongodb: - image: mongo - container_name: mongodb + postgres: + condition: service_healthy + nats: + condition: service_started + keycloak: + condition: service_healthy + + postgres: + image: postgres:16-alpine restart: unless-stopped - ports: - - "27017:27017" environment: - MONGO_INITDB_DATABASE: federation-manager - MONGODB_DATA_DIR: /data/db - MONDODB_LOG_DIR: /dev/null + POSTGRES_USER: fm + POSTGRES_PASSWORD: fm + POSTGRES_DB: fm_db + healthcheck: + test: ["CMD-SHELL", "pg_isready -U fm -d fm_db"] + interval: 3s + timeout: 3s + retries: 20 volumes: - - smdbdata:/data/db + - fm-pgdata:/var/lib/postgresql/data + + nats: + image: nats:2.10-alpine + restart: unless-stopped + command: ["-js"] + keycloak: image: quay.io/keycloak/keycloak:26.1.4 - container_name: keycloak + restart: unless-stopped + command: ["start-dev", "--import-realm"] environment: - - KC_BOOTSTRAP_ADMIN_USERNAME=admin - - KC_BOOTSTRAP_ADMIN_PASSWORD=admin - - KC_IMPORT=/opt/keycloak/data/import/realm-import.json + KC_BOOTSTRAP_ADMIN_USERNAME: admin + KC_BOOTSTRAP_ADMIN_PASSWORD: admin ports: - - "8080:8080" - command: - [ "start-dev", "--import-realm" ] + - "8090:8080" volumes: - - ./keycloak/realm-import.json:/opt/keycloak/data/import/realm-import.json + - ./keycloak:/opt/keycloak/data/import + healthcheck: + test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/8080"] + interval: 3s + timeout: 3s + retries: 30 + volumes: - smdbdata: - driver: local + fm-pgdata: diff --git a/pyproject.toml b/pyproject.toml index 90a00091c3030180c9bec694185d861ee31787cf..5f4a0cf404f0015f271d1156662f95b22738abc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,14 +34,6 @@ include = ["federation_manager*"] [tool.ruff] line-length = 100 target-version = "py312" -# Legacy Connexion code under src/ is being replaced; only lint the new package. -# TODO: drop extend-exclude once the old src/ tree is removed at parity. -extend-exclude = [ - "src/adapters", "src/api", "src/clients", "src/conf", "src/deploy", - "src/models", "src/static", "src/swagger", "src/templates", "src/test", - "src/encoder.py", "src/init.py", "src/main.py", "src/type_util.py", - "src/util.py", "src/validator.py", "src/wsgi.py", -] [tool.ruff.lint] select = ["E", "W", "F", "I"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 091e507397f091fa5eb0019d17ede6c6729e5892..0000000000000000000000000000000000000000 --- a/requirements.txt +++ /dev/null @@ -1,44 +0,0 @@ -attrs==23.1.0 -Authlib==1.2.1 -certifi==2023.11.17 -cffi==2.0.0 -charset-normalizer==3.3.2 -click==8.1.7 -clickclick==20.10.2 -connexion==2.14.2 -coverage==7.5.1 -cryptography==41.0.7 -dnspython==2.4.2 -email-validator==2.1.0.post1 -Flask==2.2.5 -flask-mongoengine==1.0.0 -Flask-Testing==0.8.1 -flask-wtf==1.2.1 -gunicorn==20.1.0 -idna==3.6 -importlib-metadata==7.0.0 -importlib-resources==5.13.0 -inflection==0.5.1 -itsdangerous==2.1.2 -Jinja2==3.1.2 -jsonschema==4.20.0 -jsonschema-specifications==2023.11.2 -MarkupSafe==2.1.3 -mongoengine==0.29.1 -packaging==23.2 -pkgutil-resolve-name==1.3.10 -pycparser==2.23 -PyJWT==2.8.0 -pymongo==4.13.2 -python-dateutil==2.9.0 -PyYAML==6.0.1 -referencing==0.32.0 -requests==2.32.4 -rpds-py==0.13.2 -six==1.16.0 -setuptools==80.9.0 -swagger-ui-bundle==0.0.9 -urllib3==2.1.0 -Werkzeug==2.2.3 -wtforms==3.1.1 -zipp==3.17.0 diff --git a/src/adapters/__init__.py b/src/adapters/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/adapters/error.py b/src/adapters/error.py deleted file mode 100644 index 3bf6cc2ebd7ef7381322c877c8d8c29912e73dcd..0000000000000000000000000000000000000000 --- a/src/adapters/error.py +++ /dev/null @@ -1,20 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -class APIError(Exception): - def __init__(self, status_code, detail_error): - super().__init__(detail_error) - self.detail_error = detail_error - self.status_code = status_code diff --git a/src/adapters/fm_adapter/__init__.py b/src/adapters/fm_adapter/__init__.py deleted file mode 100644 index 3566adf51d36c03ef9a3c6101dcaa34e1c519b9e..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import importlib -import pkgutil - - -package_name = __name__ - -for _, module_name, is_pkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("_"): - importlib.import_module(f"{package_name}.{module_name}") diff --git a/src/adapters/fm_adapter/application_deployment_management.py b/src/adapters/fm_adapter/application_deployment_management.py deleted file mode 100644 index f8bc611dddfaa23b0d0d82c3a4c141a5f174663a..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/application_deployment_management.py +++ /dev/null @@ -1,301 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from mongoengine.errors import ValidationError - -from models.mongo_document import OriginatingOperatorPlatformOriginatingOP -from models.mongo_document import OriginatingApplicationDeploymentManagementOriginatingOP -from adapters.error import APIError -from clients import fed_manager as fm_client - - -def verify_required_header(partner_api_root): - if not partner_api_root: - raise APIError(400, "X-Partner-API-Root header is missing") - - -def get_all_app_instances(federation_context_id, app_id, app_provider_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves all application instance of partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_provider_id: - :type app_provider_id: dict | bytes - - :rtype: List[InlineResponse2009] - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find application deployment at partner - deployment_response_data = fm_client.get_all_instances_deployment( - originating_op_instance.partner_federation_id, app_id, app_provider_id, bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in deployment_response_data and "status_code" in deployment_response_data: - status_code = deployment_response_data["status_code"] - error_message = deployment_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - - info = "" - if len(deployment_response_data) > 0: - try: - info = deployment_response_data[0] - except: - info = "" - if "appInstanceInfo" in info: - # Find all instances in originating operator - if find_all_instances_originating_op(federation_context_id, app_id, app_provider_id): - return deployment_response_data, 200 - else: - raise APIError(409, "Application deployment exists at partner operator but not in originating operator") - else: - if find_all_instances_originating_op(federation_context_id, app_id, app_provider_id): - raise APIError(409, "Application deployment exists in originating operator but not at partner operator") - else: - raise APIError(404, "Application deployment not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while getting all app instances. Reason: {error}") - - -def get_app_instance_details(federation_context_id, app_id, app_instance_id, zone_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves an application instance details from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: InlineResponse2008 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find application deployment details at partner - deployment_response_data = fm_client.get_instance_details_deployment( - originating_op_instance.partner_federation_id, app_id, app_instance_id, zone_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in deployment_response_data and "status_code" in deployment_response_data: - status_code = deployment_response_data["status_code"] - error_message = deployment_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appInstanceState" in deployment_response_data: - # Find instance details in originating operator - if find_instance_details(federation_context_id, app_id, app_instance_id, zone_id): - return deployment_response_data, 200 - else: - raise APIError(409, "Application Deployment exist at partner operator but not in originating operator") - else: - if find_instance_details(federation_context_id, app_id, app_instance_id, zone_id): - raise APIError(409, "Application Deployment exist in originating operator but not at partner operator") - else: - raise APIError(404, "Application Deployment not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while getting app instance details. Reason: {error}") - - -def install_app(federation_context_id, body, bearer_token, partner_api_root): # noqa: E501 - """Instantiates an application on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param body: Details about application and zones where application instance should be created. It also definea call back URI which the partner OP shall use update home OP about a change in instance status. - :type body: dict | bytes - - :rtype: InlineResponse202 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Create deployment at partner - deployment_response_data = fm_client.install_app_deployment(originating_op_instance.partner_federation_id, - body, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in deployment_response_data and "status_code" in deployment_response_data: - status_code = deployment_response_data["status_code"] - error_message = deployment_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appInstIdentifier" in deployment_response_data: - install_app_originating_op(federation_context_id, originating_op_instance.partner_federation_id, body, - deployment_response_data) - return deployment_response_data, 202 - else: - raise APIError(422, f"Unexpected response from partner API: {deployment_response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error installing application. Reason: {error}") - - -def remove_app(federation_context_id, app_id, app_instance_id, zone_id, bearer_token, partner_api_root): # noqa: E501 - """Terminate an application instance on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find application deployment details at partner - deployment_response_data = fm_client.get_instance_details_deployment( - originating_op_instance.partner_federation_id, app_id, app_instance_id, zone_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in deployment_response_data and "status_code" in deployment_response_data: - status_code = deployment_response_data["status_code"] - error_message = deployment_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appInstanceState" in deployment_response_data: - originating_ad_objects = find_instance_details(federation_context_id, app_id, app_instance_id, zone_id) - if originating_ad_objects: - # Delete application deployment at partner - response_data = fm_client.remove_app_deployment(originating_op_instance.partner_federation_id, app_id, - app_instance_id, zone_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "termination" in response_data: - # If application deployment has been removed well, remove application deployment from originating - originating_ad_objects.delete() - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - else: - raise APIError(409, "Application Deployment exist at partner operator but not in originating operator") - else: - if find_instance_details(federation_context_id, app_id, app_instance_id, zone_id): - raise APIError(409, "Application Deployment exist in originating operator but not at partner operator") - else: - raise APIError(404, "Application Deployment not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error removing application. Reason: {error}") - - -def install_app_originating_op(federation_id, partner_federation_id, body, response_partner): - zone_id = response_partner.get("zoneId") or response_partner.get("zoneID") - - # Convert the original model instance to the MongoEngine document - deployment_data = { - "orig_ad_federation_context_id": federation_id, - "orig_ad_instance_id": response_partner.get("appInstIdentifier"), - "orig_ad_app_id": body.app_id, - "orig_ad_app_version": body.app_version, - "orig_ad_app_provider_id": body.app_provider_id, - "orig_ad_zone_info_zone_id": zone_id, - "orig_ad_zone_info_flavour_id": body.zone_info.flavour_id, - "orig_ad_zone_info_resource_consumption": body.zone_info.resource_consumption, - "orig_ad_zone_info_res_pool": body.zone_info.res_pool, - "orig_ad_app_inst_callback_link": body.app_inst_callback_link, - "partner_federation_id": partner_federation_id - } - # Create a new MongoEngine document and save it to MongoDB - new_deployment = OriginatingApplicationDeploymentManagementOriginatingOP(**deployment_data) - new_deployment.save() - - -def find_all_instances_originating_op(federation_id, app_id, app_provider_id): - originating_ad_objects = OriginatingApplicationDeploymentManagementOriginatingOP.objects( - orig_ad_federation_context_id=federation_id, - orig_ad_app_id=app_id, - orig_ad_app_provider_id=app_provider_id - ) - return originating_ad_objects - - -def find_instance_details(federation_id, app_id, instance_id, zone_id): - originating_ad_objects = OriginatingApplicationDeploymentManagementOriginatingOP.objects( - orig_ad_federation_context_id=federation_id, - orig_ad_app_id=app_id, - orig_ad_instance_id=instance_id, - orig_ad_zone_info_zone_id=zone_id - ) - return originating_ad_objects diff --git a/src/adapters/fm_adapter/application_onboarding_management.py b/src/adapters/fm_adapter/application_onboarding_management.py deleted file mode 100644 index 6472c8ada2c11db0022a2b39a4f39659f680dba0..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/application_onboarding_management.py +++ /dev/null @@ -1,403 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -import logging -from mongoengine.errors import ValidationError - -from models.mongo_document import OriginatingOperatorPlatformOriginatingOP -from models.mongo_document import OriginatingApplicationOnboardingManagementOriginatingOP -from models.mongo_document import OriginatingApplicationOnboardingManagementUpdateOriginatingOP -from adapters.error import APIError -from clients import fed_manager as fm_client - - -logger = logging.getLogger(__name__) - - -def verify_required_header(partner_api_root): - if not partner_api_root: - raise APIError(400, "X-Partner-API-Root header is missing") - - -def delete_app(federation_context_id, app_id, bearer_token, partner_api_root): # noqa: E501 - """Deboards the application from any zones, if any, and deletes the App. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - logger.info( - "Onboarding partner application using federation_id=%s partner_api_root=%s", - originating_op_instance.partner_federation_id, - partner_api_root, - ) - # Find application onboarding at partner - response_get = fm_client.get_profile(originating_op_instance.partner_federation_id, app_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appId" in response_get: - originating_ao_objects = find_application_onboarding_at_originating_op(federation_context_id, app_id) - if originating_ao_objects: - # Delete application onboarding from partner - response_data = fm_client.delete_profile(originating_op_instance.partner_federation_id, app_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "deletion" in response_data: - # If application onboarding has been removed well, remove application onboarding from originating - delete_application_onboarding_originating_op(originating_ao_objects) - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - else: - raise APIError(409, "Application Onboarding exist at partner operator but not in originating operator") - else: - if find_application_onboarding_at_originating_op(federation_context_id, app_id): - raise APIError(409, "Application Onboarding exist in originating operator but not at partner operator") - else: - raise APIError(404, "Application Onboarding not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or app ID format: {federation_context_id}, {app_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while deleting application onboarding. Reason: {error}") - - -def onboard_application(body, federation_context_id, bearer_token, partner_api_root): # noqa: E501 - """Submits an application details to a partner OP. Based on the details provided, partner OP shall do bookkeeping, resource validation and other pre-deployment operations. - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefacts, QoS profile and regions where application shall be made available etc. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find application onboarding at partner - response_get = fm_client.get_profile(originating_op_instance.partner_federation_id, body.app_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - # If it's a 404, that means application doesn't exist at partner, which is what we want for onboarding - if response_get["status_code"] != 404: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - # 404 means application doesn't exist at partner, continue with onboarding logic - originating_ao_objects = find_application_onboarding_at_originating_op(federation_context_id, body.app_id) - - # Recreate partner onboarding if partner runtime/bookkeeping was lost after a rebuild. - response_data = fm_client.create_profile(originating_op_instance.partner_federation_id, body, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "accepted" in response_data: - if not originating_ao_objects: - create_application_onboarding_originating_op(federation_context_id, - originating_op_instance.partner_federation_id, body) - return response_data, 202 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - elif "appId" in response_get: - if find_application_onboarding_at_originating_op(federation_context_id, body.app_id): - raise APIError(409, "Application onboarding already exists") - else: - raise APIError(409, "Application onboarding exist at partner operator but not exist in originating operator") - else: - if find_application_onboarding_at_originating_op(federation_context_id, body.app_id): - raise APIError(409, "Application onboarding exist in originating operator but not exist at partner operator") - else: - # Create application profile at partner - response_data = fm_client.create_profile(originating_op_instance.partner_federation_id, body, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "accepted" in response_data: - # Create application onboarding in originating - create_application_onboarding_originating_op(federation_context_id, - originating_op_instance.partner_federation_id, body) - return response_data, 202 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while onboarding application. Reason: {error}") - - -def update_application(body, federation_context_id, app_id, bearer_token, partner_api_root): # noqa: E501 - """Updates partner OP about changes in application compute resource requirements, QOS Profile, associated descriptor or change in associated components - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefact and QOS profile that needs to be updated. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find application onboarding at partner - response_get = fm_client.get_profile(originating_op_instance.partner_federation_id, app_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appId" in response_get: - originating_ao_objects = find_application_onboarding_at_originating_op(federation_context_id, app_id) - if originating_ao_objects: - # Update application onboarding at partner - response_data = fm_client.update_profile(originating_op_instance.partner_federation_id, app_id, body, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "accepted" in response_data: - originating_ao_instance = originating_ao_objects[0] - update_application_onboarding_originating_op(body, federation_context_id, - originating_op_instance.partner_federation_id, app_id, - originating_ao_instance) - return response_data, 202 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - else: - raise APIError(409, "Application onboarding exist at partner operator but not exist in originating operator") - else: - if find_application_onboarding_at_originating_op(federation_context_id, app_id): - raise APIError(409, "Application onboarding exist in originating operator but not exist at partner operator") - else: - raise APIError(404, "Application onboarding not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or app ID format: {federation_context_id}, {app_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while updating application. Reason: {error}") - - -def view_application(federation_context_id, app_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves application details from partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: InlineResponse2007 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - application_response_data = fm_client.get_profile(originating_op_instance.partner_federation_id, app_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in application_response_data and "status_code" in application_response_data: - status_code = application_response_data["status_code"] - error_message = application_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "appId" in application_response_data: - if find_application_onboarding_at_originating_op(federation_context_id, app_id): - return application_response_data, 200 - else: - raise APIError(409, "Application Onboarding exist at partner operator but not in originating operator") - else: - if find_application_onboarding_at_originating_op(federation_context_id, app_id): - raise APIError(409, "Application Onboarding exist in originating operator but not at partner operator") - else: - raise APIError(404, "Application Onboarding not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or app ID format: {federation_context_id}, {app_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while viewing application. Reason: {error}") - - -def find_application_onboarding_at_originating_op(federation_id, app_id): - originating_ao_objects = OriginatingApplicationOnboardingManagementOriginatingOP.objects( - orig_ao_federation_context_id=federation_id, - orig_ao_app_id=app_id) - - return originating_ao_objects - - -def delete_application_onboarding_originating_op(originating_ao_objects): - # Delete all the onboarding updates related to onboarding application - obj_onboarding = originating_ao_objects.get() - id_onboarding = obj_onboarding.id - originating_ao_update_objects = OriginatingApplicationOnboardingManagementUpdateOriginatingOP.objects() - for o in originating_ao_update_objects: - try: - if o.federation_context_app_id.pk == id_onboarding: - o.delete() - except Exception as error: - print(f"Unable to delete onboarding updates. Error: {error}") - - # Delete Application Onboarding - originating_ao_objects.delete() - - -def create_application_onboarding_originating_op(federation_id, partner_federation_id, body): - onboarding_data = { - "orig_ao_federation_context_id": federation_id, - "orig_ao_app_id": body.app_id, - "orig_ao_app_provider_id": body.app_provider_id, - "orig_ao_app_deployment_zones": body.app_deployment_zones, - "orig_ao_app_meta_data_app_name": body.app_meta_data.app_name, - "orig_ao_app_meta_data_version": body.app_meta_data.version, - "orig_ao_app_meta_data_app_description": body.app_meta_data.app_description, - "orig_ao_app_meta_data_mobility_support": body.app_meta_data.mobility_support, - "orig_ao_app_meta_data_access_token": body.app_meta_data.access_token, - "orig_ao_app_meta_data_category": body.app_meta_data.category, - "orig_ao_app_qos_profile_latency_constraints": body.app_qo_s_profile.latency_constraints, - "orig_ao_app_qos_profile_bandwidth_required": body.app_qo_s_profile.bandwidth_required, - "orig_ao_app_qos_profile_multi_user_clients": body.app_qo_s_profile.multi_user_clients, - "orig_ao_app_qos_profile_no_of_users_per_app_inst": body.app_qo_s_profile.no_of_users_per_app_inst, - "orig_ao_app_qos_profile_app_provisioning": body.app_qo_s_profile.app_provisioning, - "orig_ao_app_component_specs": json.dumps(body.app_component_specs), - "orig_ao_app_status_callback_link": body.app_status_callback_link, - "partner_federation_id": partner_federation_id - } - - # Create a new MongoEngine document and save it to MongoDB - new_onboarding = OriginatingApplicationOnboardingManagementOriginatingOP(**onboarding_data) - new_onboarding.save() - - -def update_application_onboarding_originating_op(body, federation_context_id, partner_federation_id, app_id, originating_ao_instance): - app_update_component_specs_list = [] - for acs in body.app_component_specs: - data_acs = { - "artefactId": acs.get("artefactId") - } - if acs.get("serviceNameNB"): - data_acs["serviceNameNB"] = acs.get("serviceNameNB") - if acs.get("serviceNameEW"): - data_acs["serviceNameEW"] = acs.get("serviceNameEW") - if acs.get("componentName"): - data_acs["componentName"] = acs.get("componentName") - app_update_component_specs_list.append(data_acs) - - onboarding_update_data = { - "app_component_specs": json.dumps(app_update_component_specs_list), - "federation_context_app_id": originating_ao_instance, - "partner_federation_id": partner_federation_id - } - - if body.app_upd_qo_s_profile: - if body.app_upd_qo_s_profile.latency_constraints: - originating_ao_instance.update( - orig_ao_app_qos_profile_latency_constraints=body.app_upd_qo_s_profile.latency_constraints) - if body.app_upd_qo_s_profile.bandwidth_required: - originating_ao_instance.update( - orig_ao_app_qos_profile_bandwidth_required=body.app_upd_qo_s_profile.bandwidth_required) - if body.app_upd_qo_s_profile.multi_user_clients: - originating_ao_instance.update( - orig_ao_app_qos_profile_multi_user_clients=body.app_upd_qo_s_profile.multi_user_clients) - if body.app_upd_qo_s_profile.no_of_users_per_app_inst: - originating_ao_instance.update( - orig_ao_app_qos_profile_no_of_users_per_app_inst=body.app_upd_qo_s_profile.no_of_users_per_app_inst) - if body.app_upd_qo_s_profile.app_provisioning: - originating_ao_instance.update( - orig_ao_app_qos_profile_app_provisioning=body.app_upd_qo_s_profile.app_provisioning) - if body.app_upd_qo_s_profile.mobility_support: - originating_ao_instance.update( - orig_ao_app_meta_data_mobility_support=body.app_upd_qo_s_profile.mobility_support) - originating_ao_instance.update(orig_ao_app_component_specs=onboarding_update_data.get("app_component_specs")) - - # Create a new MongoEngine document and save it to MongoDB - new_onboarding_update = OriginatingApplicationOnboardingManagementUpdateOriginatingOP(**onboarding_update_data) - new_onboarding_update.save() diff --git a/src/adapters/fm_adapter/artefact_management.py b/src/adapters/fm_adapter/artefact_management.py deleted file mode 100644 index 2373bce923f4c458bf74d7a48590127a4becebcb..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/artefact_management.py +++ /dev/null @@ -1,354 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -from mongoengine.errors import ValidationError - -from models.mongo_document import OriginatingOperatorPlatformOriginatingOP -from models.mongo_document import OriginatingArtefactManagementOriginatingOP -from adapters.error import APIError -from clients import fed_manager as fm_client - - -def verify_required_header(partner_api_root): - if not partner_api_root: - raise APIError(400, "X-Partner-API-Root header is missing") - - -def get_artefact(federation_context_id, artefact_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves details about an artefact. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: InlineResponse2005 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find artefact at partner - response_get = fm_client.get_artefact(originating_op_instance.partner_federation_id, artefact_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "artefactId" in response_get: - if find_artefact_at_orig_op(federation_context_id, artefact_id): - return response_get - else: - raise APIError(409, "Artefact exist at partner operator but not in originating operator") - else: - if find_artefact_at_orig_op(federation_context_id, artefact_id): - raise APIError(409, "Artefact exist in originating operator but not in partner operator") - else: - raise APIError(404, "Artefact not Found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or artefact ID format: {federation_context_id}, {artefact_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while getting Artefact. Reason: {error}") - - -def remove_artefact(federation_context_id, artefact_id, bearer_token, partner_api_root): # noqa: E501 - """Removes an artefact from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find artefact at partner - response_get = fm_client.get_artefact(originating_op_instance.partner_federation_id, artefact_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "artefactId" in response_get: - originating_am_objects = find_artefact_at_orig_op(federation_context_id, artefact_id) - if originating_am_objects: - # Delete artefact from partner - response_data = fm_client.delete_artefact(originating_op_instance.partner_federation_id, artefact_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "deletion" in response_data: - # If artefact has been removed, remove artefact from originating - originating_am_objects.delete() - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - else: - raise APIError(409, "Artefact exist at partner operator but not in originating operator") - else: - if find_artefact_at_orig_op(federation_context_id, artefact_id): - raise APIError(409, "Artefact exist in originating operator but not in partner operator") - else: - raise APIError(404, "Artefact not Found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or artefact ID format: {federation_context_id}, {artefact_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while deleting Artefact. Reason: {error}") - - -def upload_artefact(body, federation_context_id, bearer_token, partner_api_root): # noqa: E501 - """Uploads application artefact on partner OP. Artefact is a zip file containing scripts and/or packaging files like Terraform or Helm which are required to create an instance of an application. - - # noqa: E501 - - :param body: - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find artefact at partner - response_get = fm_client.get_artefact(originating_op_instance.partner_federation_id, body.artefact_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_get and "status_code" in response_get: - # If it's a 404, that means artefact doesn't exist at partner, which is what we want for upload - if response_get["status_code"] != 404: - status_code = response_get["status_code"] - error_message = response_get["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - # 404 means artefact doesn't exist at partner, continue with upload logic - if find_artefact_at_orig_op(federation_context_id, body.artefact_id): - raise APIError(409, "Artefact exist in Originating Operator but not in Partner Operator") - else: - # Create artefact in partner - response_data = fm_client.create_artefact(originating_op_instance.partner_federation_id, body, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "uploaded" in response_data: - # Create artefact in originating - create_artefact_originating_op(federation_context_id, originating_op_instance.partner_federation_id, - body) - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - elif "artefactId" in response_get: - if find_artefact_at_orig_op(federation_context_id, body.artefact_id): - raise APIError(409, "Artefact already exists") - else: - raise APIError(409, "Artefact exist in Partner Operator but not in Originating Operator") - else: - if find_artefact_at_orig_op(federation_context_id, body.artefact_id): - raise APIError(409, "Artefact exist in Originating Operator but not in Partner Operator") - else: - # Create artefact in partner - response_data = fm_client.create_artefact(originating_op_instance.partner_federation_id, body, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "uploaded" in response_data: - # Create artefact in originating - create_artefact_originating_op(federation_context_id, originating_op_instance.partner_federation_id, - body) - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while creating Artefact. Reason: {error}") - - -def find_artefact_at_orig_op(federation_id, artefact_id): - originating_am_objects = OriginatingArtefactManagementOriginatingOP.objects( - orig_am_federation_context_id=federation_id, - orig_am_artefact_id=artefact_id) - - return originating_am_objects - - -def create_artefact_originating_op(federation_id, partner_federation_id, body): - component_spec_list = [] - for c in body.component_spec: - - exposed_interfaces_list = [] - for e in c.exposed_interfaces or []: - data_ei = { - "orig_ei_interface_id": e.interface_id, - "orig_ei_comm_protocol": e.comm_protocol, - "orig_ei_comm_port": e.comm_port, - "orig_ei_visibility_type": e.visibility_type, - "orig_ei_network": e.network, - "orig_ei_interface_name": e.interface_name - } - exposed_interfaces_list.append(data_ei) - - gpu_list = [] - for g in c.compute_resource_profile.gpu or []: - data_gpu = { - "orig_g_gpu_vendor_type": g.gpu_vendor_type, - "orig_g_gpu_mode_name": g.gpu_mode_name, - "orig_g_gpu_memory": g.gpu_memory, - "orig_g_num_gpu": g.num_gpu, - } - gpu_list.append(data_gpu) - - huge_pages_list = [] - for h in c.compute_resource_profile.hugepages or []: - data_hp = { - "orig_h_page_size": h.page_size, - "orig_h_number": h.number - } - huge_pages_list.append(data_hp) - - comp_env_params_list = [] - for cep in c.comp_env_params or []: - data_comp = { - "orig_cep_env_var_name": cep.env_var_name, - "orig_cep_env_value_type": cep.env_value_type, - "orig_cep_env_var_value": cep.env_var_value, - "orig_cep_env_var_src": cep.env_var_src - } - comp_env_params_list.append(data_comp) - - pv_list = [] - for v in c.persistent_volumes or []: - data_pv = { - "orig_pv_volume_size": v.volume_size, - "orig_pv_volume_mounth_path": v.volume_mount_path, - "orig_pv_volume_name": v.volume_name, - "orig_pv_ephemeral_type": v.ephemeral_type, - "orig_pv_access_mode": v.access_mode, - "orig_pv_sharing_policy": v.sharing_policy - } - pv_list.append(data_pv) - - command_line_params_command = None - command_line_params_command_args = None - if c.command_line_params: - command_line_params_command = c.command_line_params.command - command_line_params_command_args = c.command_line_params.command_args - - deployment_config_config_type = None - deployment_config_contents = None - if c.deployment_config: - deployment_config_config_type = c.deployment_config.config_type - deployment_config_contents = c.deployment_config.contents - - data_ce = { - "orig_ce_component_name": c.component_name, - "orig_ce_component_spec_images": c.images, - "orig_ce_component_spec_num_of_instances": c.num_of_instances, - "orig_ce_component_spec_restart_policy": c.restart_policy, - "orig_ce_component_spec_command_line_params_command": command_line_params_command, - "orig_ce_component_spec_command_line_params_command_args": command_line_params_command_args, - "orig_ce_component_spec_exposed_interfaces": exposed_interfaces_list, - "orig_ce_component_spec_compute_resource_profile_cpuarchtype": c.compute_resource_profile.cpu_arch_type, - "orig_ce_component_spec_compute_resource_profile_numcpu": c.compute_resource_profile.num_cpu, - "orig_ce_component_spec_compute_resource_profile_memory": c.compute_resource_profile.memory, - "orig_ce_component_spec_compute_resource_profile_diskstorage": c.compute_resource_profile.disk_storage, - "orig_ce_component_spec_compute_resource_profile_gpu": gpu_list, - "orig_ce_component_spec_compute_resource_profile_vpu": c.compute_resource_profile.vpu, - "orig_ce_component_spec_compute_resource_profile_fpga": c.compute_resource_profile.fpga, - "orig_ce_component_spec_compute_resource_profile_hugepages": huge_pages_list, - "orig_ce_component_spec_compute_resource_profile_cpuexclusivity": c.compute_resource_profile.cpu_exclusivity, - "orig_ce_component_spec_comp_env_params": comp_env_params_list, - "orig_ce_component_spec_deployment_config_config_type": deployment_config_config_type, - "orig_ce_component_spec_deployment_config_contents": deployment_config_contents, - "orig_ce_component_spec_persistent_volumes": pv_list - } - component_spec_list.append(data_ce) - - artefact_data = { - "orig_am_federation_context_id": federation_id, - "orig_am_artefact_id": body.artefact_id, - "orig_am_app_provider_id": body.app_provider_id, - "orig_am_artefact_name": body.artefact_name, - "orig_am_artefact_version_info": body.artefact_version_info, - "orig_am_artefact_description": body.artefact_description, - "orig_am_artefact_virt_type": body.artefact_virt_type, - "orig_am_artefact_filename": body.artefact_file_name, - "orig_am_artefact_file_format": body.artefact_file_format, - "orig_am_artefact_descriptor_type": body.artefact_descriptor_type, - "orig_am_repo_type": body.repo_type, - "orig_am_artefact_repo_location_repo_url": body.artefact_repo_location.repo_url, - "orig_am_artefact_repo_location_user_name": body.artefact_repo_location.user_name, - "orig_am_artefact_repo_location_password": body.artefact_repo_location.password, - "orig_am_artefact_repo_location_token": body.artefact_repo_location.token, - "orig_am_artefact_file": "", - "orig_am_component_spec": json.dumps(component_spec_list), - "partner_federation_id": partner_federation_id - } - # Create a new MongoEngine document and save it to MongoDB - new_artefact = OriginatingArtefactManagementOriginatingOP(**artefact_data) - new_artefact.save() diff --git a/src/adapters/fm_adapter/availability_zone_info_synchronization.py b/src/adapters/fm_adapter/availability_zone_info_synchronization.py deleted file mode 100644 index 27437a1a90aaab0a9bf2150cd6e8b36ce99ca4e0..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/availability_zone_info_synchronization.py +++ /dev/null @@ -1,221 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -from mongoengine.errors import ValidationError - -from adapters.error import APIError -from clients import fed_manager as fm_client -from models.zone_registered_data import ZoneRegisteredData # noqa: E501 -from models.zone_registration_response_data import ZoneRegistrationResponseData # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatformOriginatingOP -from models.mongo_document import OriginatingZoneInfoOriginatingOP - - -def verify_required_header(partner_api_root): - if not partner_api_root: - raise APIError(400, "X-Partner-API-Root header is missing") - - -def get_zone_data(federation_context_id, zone_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves details about the computation and network resources that partner OP has reserved for this zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: ZoneRegisteredData - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Forward request to partner OP - zone_response_data = fm_client.get_availability_zones(originating_op_instance.partner_federation_id, zone_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in zone_response_data and "status_code" in zone_response_data: - status_code = zone_response_data["status_code"] - error_message = zone_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "zoneId" in zone_response_data: - # Find zone in originating OP - if find_zone_at_originating_op(federation_context_id, zone_id): - zone_response_data = ZoneRegisteredData.from_dict(zone_response_data) - return zone_response_data, 200 - else: - raise APIError(409, "Zone exists at partner operator but not in originating operator") - else: - if find_zone_at_originating_op(federation_context_id, zone_id): - raise APIError(409, "Zone exists in originating operator but not at partner operator") - else: - raise APIError(404, "Zone not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or zone ID format: {federation_context_id}, {zone_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while getting zone data. Reason: {error}") - - -def zone_subscribe(federation_context_id, body, bearer_token, partner_api_root): # noqa: E501 - """Originating OP informs partner OP that it is willing to access the specified zones and partner OP shall reserve compute and network resources for these zones. - - # noqa: E501 - - :param body: - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: ZoneRegistrationResponseData - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Forward request to partner OP - zone_response_data = fm_client.create_availability_zones(originating_op_instance.partner_federation_id, - body, bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in zone_response_data and "status_code" in zone_response_data: - status_code = zone_response_data["status_code"] - error_message = zone_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "acceptedZoneResourceInfo" in zone_response_data: - # Create zone subscription in originating OP - create_zone_subscription_originating_op(federation_context_id, - originating_op_instance.partner_federation_id, body) - zone_response_data = ZoneRegistrationResponseData.from_dict(zone_response_data) - return zone_response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {zone_response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while creating zone subscription. Reason: {error}") - - -def zone_unsubscribe(federation_context_id, zone_id, bearer_token, partner_api_root): # noqa: E501 - """Assert usage of a partner OP zone. Originating OP informs partner OP that it will no longer access the specified zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - # Find federation at originating OP - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - # Find zone subscription at partner - zone_response_data = fm_client.get_availability_zones(originating_op_instance.partner_federation_id, zone_id, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in zone_response_data and "status_code" in zone_response_data: - status_code = zone_response_data["status_code"] - error_message = zone_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "zoneId" in zone_response_data: - originating_zi_objects = find_zone_at_originating_op(federation_context_id, zone_id) - if originating_zi_objects: - # Delete zone subscription from partner - response_data = fm_client.delete_availability_zones(originating_op_instance.partner_federation_id, - zone_id, bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "deregistered" in response_data: - # If zone subscription has been removed, remove zone subscription from originating - delete_zone_subscription_originating_op(originating_zi_objects) - return response_data, 200 - else: - raise APIError(422, f"Unexpected response from partner API: {response_data}") - else: - raise APIError(409, "Zone subscription exists at partner operator but not in originating operator") - else: - if find_zone_at_originating_op(federation_context_id, zone_id): - raise APIError(409, "Zone subscription exists in originating operator but not at partner operator") - else: - raise APIError(404, "Zone subscription not found") - except ValidationError: - raise APIError(400, f"Invalid federation context ID or zone ID format: {federation_context_id}, {zone_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while deleting zone subscription. Reason: {error}") - - -def create_zone_subscription_originating_op(federation_id, partner_federation_id, body): - zone_data = { - "orig_zi_federation_context_id": federation_id, - "orig_zi_acceptedAvailabilityZones": body.accepted_availability_zones, - "partner_federation_id": partner_federation_id - } - - # Create a new MongoEngine document and save it to MongoDB - new_zone_subscription = OriginatingZoneInfoOriginatingOP(**zone_data) - new_zone_subscription.save() - - -def delete_zone_subscription_originating_op(originating_zi_objects): - # Delete zone subscription - originating_zi_objects.delete() - - -def find_zone_at_originating_op(federation_id, zone_id): - originating_zi_objects = OriginatingZoneInfoOriginatingOP.objects( - orig_zi_federation_context_id=federation_id) - - for zone_info in originating_zi_objects: - if zone_id in zone_info.orig_zi_acceptedAvailabilityZones: - return zone_info - return None diff --git a/src/adapters/fm_adapter/federation_management.py b/src/adapters/fm_adapter/federation_management.py deleted file mode 100644 index 9dc20be6210b8233821163657295f112a0d30944..0000000000000000000000000000000000000000 --- a/src/adapters/fm_adapter/federation_management.py +++ /dev/null @@ -1,347 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from configparser import ConfigParser -from mongoengine.errors import ValidationError -import os - - -from models.federation_context_id import FederationContextId # noqa: E501 -from models.federation_response_data import FederationResponseData # noqa: E501 -from models.inline_response2001 import InlineResponse2001 # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatformOriginatingOP -from models.mongo_document import OriginatingOperatorPlatformUpdateOriginatingOP -from clients import fed_manager as fm_client -from adapters.error import APIError - - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -partnerOPFederationId = CONFIG.get("op_data", "partnerOPFederationId") -partnerOPCountryCode = CONFIG.get("op_data", "partnerOPCountryCode") -partnerOPMobileNetworkCode_MCC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MCC") -partnerOPMobileNetworkCode_MNC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MNC") -partnerOPFixedNetworkCode = CONFIG.get("op_data", "partnerOPFixedNetworkCode") -partnerOPPlatformCaps = CONFIG.get("op_data", "platformCaps") - - -def verify_required_header(partner_api_root): - if not partner_api_root: - raise APIError(400, "X-Partner-API-Root header is missing") - - -def create_federation(body, bearer_token, partner_api_root): # noqa: E501 - """Creates one direction federation with partner operator platform. - - # noqa: E501 - - :param body: - :type body: dict | bytes - - :rtype: FederationResponseData - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - # Forward request to partner OP - try: - federation_response_data = fm_client.create_federation(body, bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in federation_response_data and "status_code" in federation_response_data: - status_code = federation_response_data["status_code"] - error_message = federation_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif federation_response_data.get("federationContextId"): - federation_response_data = create_federation_at_originating_op(body, bearer_token, - federation_response_data) - federation_response_data = FederationResponseData.from_dict(federation_response_data) - return federation_response_data, 200 - else: - return federation_response_data, 422 - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while creating Federation. Reason: {error}") - - -def get_federation_details(federation_context_id, bearer_token, partner_api_root): # noqa: E501 - """Retrieves details about the federation context with the partner OP. The response shall provide info about the zones offered by the partner, partner OP network codes, information about edge discovery and LCM service etc. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - # Forward request to partner OP - try: - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - federation_response_data = fm_client.get_federation(originating_op_instance.partner_federation_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in federation_response_data and "status_code" in federation_response_data: - status_code = federation_response_data["status_code"] - error_message = federation_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "offeredAvailabilityZones" in federation_response_data or "platformCaps" in federation_response_data: - federation_response_data = InlineResponse2001.from_dict(federation_response_data) - return federation_response_data, 200 - else: - raise APIError(422, f"Conflict between originating operator and partner operator. Reason: {federation_response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while getting Federation. Reason: {error}") - - -def update_federation(federation_context_id, body, bearer_token, partner_api_root): # noqa: E501 - """API used by the Originating OP towards the partner OP, to update the parameters associated to the existing federation - - # noqa: E501 - - :param body: Details about changes origination OP wished to apply - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - # Forward request to partner OP - try: - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - federation_response_data = fm_client.update_federation(originating_op_instance.partner_federation_id, body, - bearer_token, partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in federation_response_data and "status_code" in federation_response_data: - status_code = federation_response_data["status_code"] - error_message = federation_response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "offeredAvailabilityZones" in federation_response_data or "platformCaps" in federation_response_data: - federation_response_data = update_federation_at_originating_op(originating_op_instance, body, - federation_response_data) - federation_response_data = InlineResponse2001.from_dict(federation_response_data) - return federation_response_data, 200 - else: - raise APIError(422, f"Conflict between originating operator and partner operator. Reason: {federation_response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while updating Federation. Reason: {error}") - - -def delete_federation_details(federation_context_id, bearer_token, partner_api_root): # noqa: E501 - """Remove existing federation with the partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - # Forward request to partner OP - try: - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - - response_data = fm_client.delete_federation(originating_op_instance.partner_federation_id, bearer_token, - partner_api_root) - - # Check if the response contains an error from the partner API - if "error" in response_data and "status_code" in response_data: - status_code = response_data["status_code"] - error_message = response_data["error"] - raise APIError(status_code, f"Partner API error: {error_message}") - elif "removed" in response_data: - delete_federation_originating_op(originating_op_instance) - return response_data, 200 - else: - raise APIError(422, f"Conflict between originating operator and partner operator. Reason: {response_data}") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while deleting Federation. Reason: {error}") - - -def get_federation_context_id(bearer_token, partner_api_root): # noqa: E501 - """Retrieves the existing federationContextId with partner operator platform. - - # noqa: E501 - - :rtype: InlineResponse2002 - """ - - # Verify partner API root is provided - verify_required_header(partner_api_root) - - try: - originating_op_objects = OriginatingOperatorPlatformOriginatingOP.objects(partner_bearer_token=bearer_token) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - federation_context_id_data = { - "federationContextId": str(originating_op_instance.id) - } - federation_context_id = FederationContextId.from_dict(federation_context_id_data) - return federation_context_id - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation context ID. Reason: {error}") - - -def create_federation_at_originating_op(body, bearer_token, federation_response_data): - mcc = None - mncs = None - token_url = None - client_id = None - client_secret = None - if body.orig_op_mobile_network_codes: - mcc = body.orig_op_mobile_network_codes.mcc or None - mncs = body.orig_op_mobile_network_codes.mncs or None - if body.partner_callback_credentials: - token_url = body.partner_callback_credentials.token_url or None - client_id = body.partner_callback_credentials.client_id or None - client_secret = body.partner_callback_credentials.client_secret or None - federation_data = { - "orig_op_federation_id": body.orig_op_federation_id, - "orig_op_country_code": body.orig_op_country_code, - "orig_op_mobile_network_codes_mcc": mcc, - "orig_op_mobile_network_codes_mncs": mncs, - "orig_op_fixed_network_codes": body.orig_op_fixed_network_codes, - "initial_date": body.initial_date, - "partner_status_link": body.partner_status_link, - "partner_callback_credentials_token_url": token_url, - "partner_callback_credentials_client_id": client_id, - "partner_callback_credentials_client_secret": client_secret, - "partner_bearer_token": bearer_token, - "partner_federation_id": federation_response_data.get("federationContextId") - } - - # Create a new MongoEngine document and save it to MongoDB - new_federation = OriginatingOperatorPlatformOriginatingOP(**federation_data) - new_federation.save() - - response_data = federation_response_data - response_data["federationContextId"] = str(new_federation.id) - - return response_data - - -def update_federation_at_originating_op(originating_op_instance, body, federation_response_data): - partner_update_data = { - "object_type": body.object_type, - "operation_type": body.operation_type, - "modification_date": body.modification_date, - "federation_context_id": str(originating_op_instance.id), - "partner_federation_id": originating_op_instance.partner_federation_id - } - - if body.object_type == "MOBILE_NETWORK_CODES": - mncs = originating_op_instance.orig_op_mobile_network_codes_mncs - if body.operation_type == "ADD_CODES": - partner_update_data["add_mobile_network_ids_mcc"] = body.add_mobile_network_ids.mcc - partner_update_data["add_mobile_network_ids_mncs"] = body.add_mobile_network_ids.mncs - mncs.extend(body.add_mobile_network_ids.mncs) - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.operation_type == "REMOVE_CODES": - partner_update_data["remove_mobile_network_ids_mcc"] = body.remove_mobile_network_ids.mcc - partner_update_data["remove_mobile_network_ids_mncs"] = body.remove_mobile_network_ids.mncs - mncs = [code for code in mncs if code not in body.remove_mobile_network_ids.mncs] - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.operation_type == "UPDATE_CODES": - partner_update_data["add_mobile_network_ids_mcc"] = body.add_mobile_network_ids.mcc - partner_update_data["add_mobile_network_ids_mncs"] = body.add_mobile_network_ids.mncs - partner_update_data["remove_mobile_network_ids_mcc"] = body.remove_mobile_network_ids.mcc - partner_update_data["remove_mobile_network_ids_mncs"] = body.remove_mobile_network_ids.mncs - originating_op_instance.update(set__orig_op_mobile_network_codes_mcc=body.add_mobile_network_ids.mcc) - mncs = body.add_mobile_network_ids.mncs - if body.remove_mobile_network_ids.mcc == body.add_mobile_network_ids.mcc: - mncs = [code for code in body.add_mobile_network_ids.mncs if code not in body.remove_mobile_network_ids.mncs] - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.object_type == "FIXED_NETWORK_CODES": - original_fixed_codes = originating_op_instance.orig_op_fixed_network_codes - if body.operation_type == "ADD_CODES": - partner_update_data["add_fixed_network_ids"] = body.add_fixed_network_ids - fixed_codes = original_fixed_codes - fixed_codes.extend(body.add_fixed_network_ids) - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - if body.operation_type == "REMOVE_CODES": - partner_update_data["remove_fixed_network_ids"] = body.remove_fixed_network_ids - fixed_codes = [code for code in original_fixed_codes if code not in body.remove_fixed_network_ids] - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - elif body.operation_type == "UPDATE_CODES": - partner_update_data["add_fixed_network_ids"] = body.add_fixed_network_ids - partner_update_data["remove_fixed_network_ids"] = body.remove_fixed_network_ids - fixed_codes = [code for code in body.add_fixed_network_ids if code not in body.remove_fixed_network_ids] - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - - # Create a new MongoEngine document and save it to MongoDB - new_federation = OriginatingOperatorPlatformUpdateOriginatingOP(**partner_update_data) - new_federation.save() - - response_data = federation_response_data - response_data["federationContextId"] = str(originating_op_instance.id) - - return response_data - - -def delete_federation_originating_op(originating_op_instance): - # Delete all the federation updates related to federation - id_federation = originating_op_instance.id - originating_op_instance_update_objects = OriginatingOperatorPlatformUpdateOriginatingOP.objects() - for o in originating_op_instance_update_objects: - try: - if o.federation_context_id.pk == id_federation: - o.delete() - except Exception: - pass - - # Delete Federation - originating_op_instance.delete() diff --git a/src/adapters/injector.py b/src/adapters/injector.py deleted file mode 100644 index 753077847133484863063db68faf35d8216b6939..0000000000000000000000000000000000000000 --- a/src/adapters/injector.py +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from adapters import tf_adapter -from adapters import fm_adapter - - -def resolve_adapter(headers): - if headers.get("X-Internal"): - return fm_adapter - return tf_adapter diff --git a/src/adapters/tf_adapter/__init__.py b/src/adapters/tf_adapter/__init__.py deleted file mode 100644 index 3566adf51d36c03ef9a3c6101dcaa34e1c519b9e..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import importlib -import pkgutil - - -package_name = __name__ - -for _, module_name, is_pkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("_"): - importlib.import_module(f"{package_name}.{module_name}") diff --git a/src/adapters/tf_adapter/application_deployment_management.py b/src/adapters/tf_adapter/application_deployment_management.py deleted file mode 100644 index 3689e490465749371a2403d10aae089dd368dffb..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/application_deployment_management.py +++ /dev/null @@ -1,540 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from mongoengine.errors import ValidationError - -from models.inline_response2008 import InlineResponse2008 # noqa: E501 -from models.inline_response2009 import InlineResponse2009 # noqa: E501 -from models.inline_response202 import InlineResponse202 # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatform -from models.mongo_document import OriginatingApplicationOnboardingManagement -from models.mongo_document import OriginatingApplicationDeploymentManagement -from adapters.error import APIError -from clients import srm - - -def _delete_stale_app_version_records(originating_ad_version_objects, app_id): - for deployment in originating_ad_version_objects: - try: - response = srm.get_app_by_zone_app_instance_id( - app_id, - deployment.orig_ad_instance_id, - deployment.orig_ad_zone_info_zone_id, - ) - if response.status_code == 404: - deployment.delete() - except Exception: - continue - - -def get_all_app_instances(federation_context_id, app_id, app_provider_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves all application instance of partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_provider_id: - :type app_provider_id: dict | bytes - - :rtype: List[InlineResponse2009] - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not Found at Application Onboarding Management") - - # Check if exist application deployment by federation id, app Id, and app provider id - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=app_id, - orig_ad_app_provider_id=app_provider_id - ) - if not originating_ad_objects: - raise APIError(404, "Application Deployment Management Not Found by Federation Context, " - "appId and appProviderId") - - # Get list of zones and their instances to fill response data - instances_deployment = originating_ad_objects.filter() - list_zones_instances = get_list_zones_instances(instances_deployment) - - # Fill response data from the list of zones and their instances - list_responses = [] - zones_id = {} - instances_id = [] - for zi in list_zones_instances: - # Add instances for each zone - for ins in zi[1]: - # Find instance state from Edge Cloud Platform - instance_state = find_instance_state(app_id, ins, zi[0]) - instances_id.append({"appInstIdentifier": ins, "appInstanceState": instance_state}) - zones_id = {"zoneId": str(zi[0]), "appInstanceInfo": instances_id} - # Add InlineResponse2009 to the list of responses - list_responses.append(InlineResponse2009.from_dict(zones_id)) - # Clear instances array for the next zone - instances_id = [] - - deployment_response_data = list_responses - return deployment_response_data - - -def get_app_instance_details(federation_context_id, app_id, app_instance_id, zone_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves an application instance details from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: InlineResponse2008 - """ - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not Found at Application Onboarding Management") - - # Check if exist instance id at Edge Cloud Platform - try: - response = srm.get_app_by_zone_app_instance_id(app_id, app_instance_id, zone_id) - if response.status_code != 200: - raise APIError(500, f"Error: {response.status_code} from srm. {response.content}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist zone id at Edge Cloud Platform - try: - if not srm.get_zone_by_zone_id(zone_id): - raise APIError(422, "Zone Id not found at Edge Cloud Platform") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - onboarding_instance = originating_ao_objects.get() - # check if exist zone for this federation at Availability Zones of onboarding - # Because zone id of the deployment can be assigned automatically if we do not specify the zone - # when create deployment, it has not sense this validation - #if not check_zone_by_federation_and_onboarding(zone_id, onboarding_instance): - # raise APIError(422, f"Zone id not found for this Federation at Availability Zones of onboarding") - - # Check if exist application deployment by federation id, app Id, instance Id and zone Id - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=app_id, - orig_ad_instance_id=app_instance_id, - orig_ad_zone_info_zone_id=zone_id - ) - if not originating_ad_objects: - raise APIError(404, "Application Deployment Management Not Found by Federation Context, " - "appId, appInstanceId and zoneId") - - response_data = create_response_instance_details(app_id, app_instance_id, zone_id) - if response_data == "": - raise APIError(422, "Unable to get app by zone id and app name form Edge Cloud Platform") - - deployment_response_data = InlineResponse2008.from_dict(response_data) - return deployment_response_data - - -def install_app(federation_context_id, body, bearer_token=None, partner_api_root=None): # noqa: E501 - """Instantiates an application on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param body: Details about application and zones where application instance should be created. It also defines a call back URI which the partner OP shall use update home OP about a change in instance status. - :type body: dict | bytes - - :rtype: InlineResponse202 - """ - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=body.app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not Found at Application Onboarding Management") - - onboarding_instance = originating_ao_objects.get() - - zone_in_blanks = False - if body.zone_info.zone_id == "": - zone_in_blanks = True - if not check_flavour_in_tf_sdk(body.zone_info.flavour_id): - raise APIError(404, "Flavour id not found at Edge Cloud Platform") - else: - # Check zone and flavour provided by the body - try: - if not check_zone_and_flavour(body): - raise APIError(404, "Flavour for this zone not found at Edge Cloud Platform") - except Exception as error: - raise APIError(422, f"Error: {error}") - - # check if exist zone for this federation at Availability Zones of the onboarding - if not check_zone_by_federation_and_onboarding(body.zone_info.zone_id, onboarding_instance): - raise APIError(422, f"Zone id not found for this Federation at Availability Zones of the onboarding") - - # check if the provider is the same that the provider of the app id - if body.app_provider_id != onboarding_instance.orig_ao_app_provider_id: - raise APIError(404, "Provider does not match with the Provider of the Application Onboarding") - - # check if exist a version in the application deployment with the same app id - originating_ad_version_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=body.app_id, - orig_ad_app_version=body.app_version - ) - if originating_ad_version_objects: - _delete_stale_app_version_records(originating_ad_version_objects, body.app_id) - originating_ad_version_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=body.app_id, - orig_ad_app_version=body.app_version - ) - if originating_ad_version_objects: - raise APIError(409, "App Version already exists for the App Id in the Application Deployment Management") - - # Create app command at Edge Cloud Platform - # Retrieve JSON - instance_id = "" - instance_id_data = {} - try: - response = srm.post_app_command(body.to_gsma_input()) - if response.status_code != 202: - raise APIError(500, f"Error {response.status_code} - {response.content}") - instance_id_data = response.json() - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Get instance id and zone id from response - instance_id = instance_id_data.get("appInstIdentifier") - zone_id = instance_id_data.get("zoneID") - - # Check if exist application deployment by federation, appId and instance Id - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=body.app_id, - orig_ad_instance_id=instance_id - ) - if originating_ad_objects: - # if not is possible to create deployment in FM, delete the app command created - try: - response = srm.delete_app(body.app_id, instance_id, zone_id) - if response.status_code != 200: - raise APIError(500, f"Unable to delete app in tf_sdk when is not possible create deployment in FM. " - f"Error {response.status_code} - {response.content}") - except Exception as error: - raise APIError(500, "Unable to create Application Deployment Management and delete app in Edge Cloud Platform") - raise APIError(409, "Application Deployment Management already exist for Federation Context, " - "appId and appInstanceId") - - # Convert the original model instance to the MongoEngine document - deployment_data = fill_application_deployment_mongo_document(federation_context_id, instance_id, body, - zone_in_blanks, zone_id) - - # Create a new MongoEngine document and save it to MongoDB - new_deployment = OriginatingApplicationDeploymentManagement(**deployment_data) - new_deployment.save() - - zone_response = "" - if zone_in_blanks: - zone_response = zone_id - else: - zone_response = body.zone_info.zone_id - response_data = { - "zoneId": zone_response, - "appInstIdentifier": instance_id - } - deployment_response_data = InlineResponse202.from_dict(response_data) - return deployment_response_data, 202 - - -def remove_app(federation_context_id, app_id, app_instance_id, zone_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Terminate an application instance on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not Found at Application Onboarding Management") - - # Check if exist application deployment by federation id, app Id, instance Id and zone Id - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=app_id, - orig_ad_instance_id=app_instance_id, - orig_ad_zone_info_zone_id=zone_id - ) - if not originating_ad_objects: - raise APIError(404, "Application Deployment Management Not Found by Federation Context, " - "appId, appInstanceId and zoneId") - - # Check if exist instance id at Edge Cloud Platform and delete - response = srm.get_app_by_zone_app_instance_id(app_id, app_instance_id, zone_id) - if response.status_code == 404: - originating_ad_objects.delete() - return 'Application instance termination request accepted', 200 - if response.status_code == 200 or response.status_code == 503: - # Delete Application command at Edge Cloud Platform - try: - response = srm.delete_app(app_id, app_instance_id, zone_id) - if response.status_code == 200 or response.status_code == 404: - # Delete Application Deployment - originating_ad_objects.delete() - else: - raise APIError(500, f"Unable to delete App Command at Edge Cloud Platform. Error {response.status_code} - {response.content}") - except Exception as error: - raise APIError(500, f"Unable to delete App Command. Error: {error}") - else: - raise APIError(500, f"Unable to delete App Command. Error {response.status_code} - {response.content}") - - return 'Application instance termination request accepted', 200 - - -def fill_application_deployment_mongo_document(federation_context_id, instance_id, body, zone_in_blanks, zone_id): - - zone = "" - if zone_in_blanks: - zone = zone_id - else: - zone = body.zone_info.zone_id - deployment_data = { - "orig_ad_federation_context_id": federation_context_id, - "orig_ad_instance_id": instance_id, - "orig_ad_app_id": body.app_id, - "orig_ad_app_version": body.app_version, - "orig_ad_app_provider_id": body.app_provider_id, - "orig_ad_zone_info_zone_id": zone, - "orig_ad_zone_info_flavour_id": body.zone_info.flavour_id, - "orig_ad_zone_info_resource_consumption": body.zone_info.resource_consumption, - "orig_ad_zone_info_res_pool": body.zone_info.res_pool, - "orig_ad_app_inst_callback_link": body.app_inst_callback_link - } - - return deployment_data - - -def check_zone_and_flavour(body): - correct = True - - zone_data = srm.get_zone_by_zone_id(body.zone_info.zone_id) - if not zone_data: - return False - - flavours = zone_data.get("flavoursSupported") - if len(flavours) < 1: - return False - - found_flavour = False - for f in flavours: - if f.get("flavourId") == body.zone_info.flavour_id: - found_flavour = True - break - if not found_flavour: - return False - - return correct - - -def check_zone_by_federation_and_onboarding(zone_id, onboarding_instance): - exist_zone = True - - # check Zones of the Onboarding - zones = onboarding_instance.orig_ao_app_deployment_zones - - # Check if exist Zone Id in Availability Zones of the onboarding - if zones and zone_id not in zones: - exist_zone = False - - return exist_zone - - -# Get the list of zones with their instances -def get_list_zones_instances(instances_deployment): - zone_previous = "" - zones = [] - instances = [] - for query in instances_deployment.order_by('orig_ad_zone_info_zone_id', 'orig_ad_instance_id'): - if zone_previous == "": - zone_previous = query.orig_ad_zone_info_zone_id - - if zone_previous != query.orig_ad_zone_info_zone_id: - zones.append([zone_previous, instances]) - zone_previous = query.orig_ad_zone_info_zone_id - instances = [] - - instances.append(query.orig_ad_instance_id) - - if len(instances) > 0: - zones.append([zone_previous, instances]) - - return zones - - -# Check if exist flavour in some zone of Edge Cloud Platform -def check_flavour_in_tf_sdk(flavour_id): - exist = False - - zone_data = srm.get_zones() - if not zone_data: - return False - - found_flavour = False - for zone in zone_data: - if found_flavour: - break - flavours = zone.get("flavoursSupported") - if flavours and len(flavours) > 0: - for f in flavours: - if f.get("flavourId") == flavour_id: - exist = True - found_flavour = True - break - return exist - - -def find_instance_state(app_id, instance_id, zone_id): - instance_state = "" - - try: - response = srm.get_app_by_zone_app_instance_id(app_id, instance_id, zone_id) - if response.status_code != 200: - return f"Error {response.status_code} - {response.content}" - data = response.json() - instance_state = data.get("appInstanceState") - except Exception as error: - return f"Error: {error}" - - return instance_state - - -def create_response_instance_details(app_id, instance_id, zone_id): - response_data = "" - - try: - response = srm.get_app_by_zone_app_instance_id(app_id, instance_id, zone_id) - data = response.json() - - if isinstance(data, dict): - list_points_info = [] - - for point in data.get("accesspointInfo"): - access_points = point.get("accessPoints") - port = access_points.get("port") - if not port: - port = 0 - list_points_info.append( - { - "interfaceId": point.get("interfaceId"), - "accessPoints": { - "port": port, - "fqdn": access_points.get("fqdn"), - "ipv4Addresses": access_points.get("ipv4Addresses"), - "ipv6Addresses": [] - } - } - ) - - response_data = { - "appInstanceState": data.get("appInstanceState"), - "accesspointInfo": list_points_info - } - else: - response_data = "" - - except: - response_data = "" - - return response_data diff --git a/src/adapters/tf_adapter/application_onboarding_management.py b/src/adapters/tf_adapter/application_onboarding_management.py deleted file mode 100644 index dc3423de95321b0e45d82f164b32f00f2f524fb3..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/application_onboarding_management.py +++ /dev/null @@ -1,492 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -from mongoengine.errors import ValidationError - -from models.inline_response2007 import InlineResponse2007 # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatform -from models.mongo_document import OriginatingArtefactManagement -from models.mongo_document import OriginatingApplicationOnboardingManagement -from models.mongo_document import OriginatingApplicationOnboardingManagementUpdate -from models.mongo_document import OriginatingZoneInfo -from models.mongo_document import OriginatingApplicationDeploymentManagement -from adapters.error import APIError -from clients import srm - - -def _delete_onboarding_updates(originating_ao_objects): - obj_onboarding = originating_ao_objects.get() - id_onboarding = obj_onboarding.id - originating_ao_update_objects = OriginatingApplicationOnboardingManagementUpdate.objects() - for o in originating_ao_update_objects: - try: - if o.federation_context_app_id.pk == id_onboarding: - o.delete() - except Exception as error: - print(f"Unable to delete onboarding updates. Error: {error}") - - -def _prune_stale_onboarding_record(federation_context_id, app_id): - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects or check_child_onboarding(federation_context_id, app_id): - return - - try: - response = srm.get_onboarding(app_id) - if response.status_code == 404: - _delete_onboarding_updates(originating_ao_objects) - originating_ao_objects.delete() - except Exception: - return - - -def delete_app(federation_context_id, app_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Deboards the application from any zones, if any, and deletes the App. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not found at Application Onboarding Management") - - # Check if there are application deployments dependents of the onboarding - if check_child_onboarding(federation_context_id, app_id): - # Clean up stale deployment bookkeeping records so onboarding can be removed - _prune_orphan_deployment_records(federation_context_id, app_id) - - # Delete onboarding at edgecloud_client - try: - response = srm.delete_onboarding(app_id) - if response.status_code == 200 or response.status_code == 404: - # Delete all the onboarding updates related to onboarding application - _delete_onboarding_updates(originating_ao_objects) - # Delete Application Onboarding - originating_ao_objects.delete() - else: - raise APIError(500, f"Unable to delete App Onboarding at Edge Cloud Platform. Error {response.status_code} - {response.content}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Unable to delete Application Onboarding at Edge Cloud Platform. Error: {error}") - - return 'App deletion successful', 200 - - -def onboard_application(body, federation_context_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Submits an application details to a partner OP. Based on the details provided, partner OP shall do bookkeeping, resource validation and other pre-deployment operations. - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefacts, QoS profile and regions where application shall be made available etc. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=body.app_id) - if originating_ao_objects: - _prune_stale_onboarding_record(federation_context_id, body.app_id) - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=body.app_id) - if originating_ao_objects: - raise APIError(409, "Federation Context and App Id already exists at Application Onboarding Management") - - # Check if exist app id in the database. If found app id belongs to another federation - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_app_id=body.app_id) - if originating_ao_objects: - raise APIError(409, "App Id already exists for another Federation at Application Onboarding Management") - - # Check if exist artefact id for this federation context - if not check_artefact_id(federation_context_id, body): - raise APIError(404, "Federation Context and Artefact Id not found at Artefact Management") - - # Check if the provider of the body matches with the providers of the artefact in component specs - if not check_provider_with_artefact_id(federation_context_id, body): - raise APIError(404, "App provider do not matches with the providers of the artefact in component specs") - - # Check if exist zones for this federation context - if body.app_deployment_zones: - if not check_deployment_zones(federation_context_id, body): - raise APIError(404, "Deployment zones not found for the Federation Context Id or not found at Edge Cloud Platform") - - # Create onboarding at Edge Cloud Platform - try: - response = srm.post_onboarding(body.to_gsma_input()) - if response.status_code == 200: - # Convert the original model instance to the MongoEngine document - onboarding_data = fill_application_onboarding_mongo_document(federation_context_id, body) - - # Create a new MongoEngine document and save it to MongoDB - new_onboarding = OriginatingApplicationOnboardingManagement(**onboarding_data) - new_onboarding.save() - else: - raise APIError(500, f"Unable to save Application Onboarding at Edge Cloud Platform. Error {response.status_code} - {response.content}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Unable to save Application Onboarding at Edge Cloud Platform. Error: {error}") - - return 'Application onboarded request accepted', 202 - - -def update_application(body, federation_context_id, app_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Updates partner OP about changes in application compute resource requirements, QOS Profile, associated descriptor or change in associated components - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefact and QOS profile that needs to be updated. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not found at Application Onboarding Management") - originating_ao_instance = originating_ao_objects[0] - - # Check if exist artefact id for this federation context - if not check_artefact_id(federation_context_id, body): - raise APIError(404, "Federation Context and Artefact Id not found at Artefact Management") - - # Check if the provider of the onboarding natches with the providers of the artefact in component specs - if not check_provider_with_artefact_id(federation_context_id, body, originating_ao_instance.orig_ao_app_provider_id): - raise APIError(404, "App provider do not matches with the providers of the artefact in component specs") - - # Update onboarding at Edge Cloud Platform - # Retrieve JSON - try: - response = srm.update_onboarding(app_id, body.to_gsma_input()) - if response.status_code == 200: - # Update onboarding in FM - # Convert the original model instance to the MongoEngine document - onboarding_update_data = fill_update_application_onboarding_mongo_document(body, originating_ao_instance) - if body.app_upd_qo_s_profile: - if body.app_upd_qo_s_profile.latency_constraints: - originating_ao_instance.update(orig_ao_app_qos_profile_latency_constraints=body.app_upd_qo_s_profile.latency_constraints) - if body.app_upd_qo_s_profile.bandwidth_required: - originating_ao_instance.update(orig_ao_app_qos_profile_bandwidth_required=body.app_upd_qo_s_profile.bandwidth_required) - if body.app_upd_qo_s_profile.multi_user_clients: - originating_ao_instance.update(orig_ao_app_qos_profile_multi_user_clients=body.app_upd_qo_s_profile.multi_user_clients) - if body.app_upd_qo_s_profile.no_of_users_per_app_inst: - originating_ao_instance.update(orig_ao_app_qos_profile_no_of_users_per_app_inst=body.app_upd_qo_s_profile.no_of_users_per_app_inst) - if body.app_upd_qo_s_profile.app_provisioning: - originating_ao_instance.update(orig_ao_app_qos_profile_app_provisioning=body.app_upd_qo_s_profile.app_provisioning) - if body.app_upd_qo_s_profile.mobility_support: - originating_ao_instance.update(orig_ao_app_meta_data_mobility_support=body.app_upd_qo_s_profile.mobility_support) - originating_ao_instance.update(orig_ao_app_component_specs=onboarding_update_data.get("app_component_specs")) - - # Create a new MongoEngine document and save it to MongoDB - new_onboarding_update = OriginatingApplicationOnboardingManagementUpdate(**onboarding_update_data) - new_onboarding_update.save() - else: - raise APIError(500, f"Unable to update Application Onboarding. Error: {response.status_code} from Edge Cloud Platform. {response.content}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Unable to update Application Onboarding at Edge Cloud Platform. Error: {error}") - - return 'Application update request accepted', 202 - - -def view_application(federation_context_id, app_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves application details from partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: InlineResponse2007 - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and App Id in Application Onboarding Management - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if originating_ao_objects: - _prune_stale_onboarding_record(federation_context_id, app_id) - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_id=app_id) - if not originating_ao_objects: - raise APIError(404, "Federation Context and App Id not found at Application Onboarding Management") - - operator = originating_op_objects.get() - application = originating_ao_objects.get() - - appMetadata = {"'appName": application.orig_ao_app_meta_data_app_name, - "version": application.orig_ao_app_meta_data_version, - "appDescription": application.orig_ao_app_meta_data_app_description, - "mobilitySupport": application.orig_ao_app_meta_data_mobility_support, - "accessToken": application.orig_ao_app_meta_data_access_token, - "category": application.orig_ao_app_meta_data_category - } - - appQoSProfile = {"latencyConstraints": application.orig_ao_app_qos_profile_latency_constraints, - "bandwidthRequired": application.orig_ao_app_qos_profile_bandwidth_required, - "multiUserClients": application.orig_ao_app_qos_profile_multi_user_clients, - "noOfUsersPerAppInst": application.orig_ao_app_qos_profile_no_of_users_per_app_inst, - "appProvisioning": application.orig_ao_app_qos_profile_app_provisioning - } - - country_code = operator.orig_op_country_code or "US" - zones_list = [] - for z in application.orig_ao_app_deployment_zones: - zone_element = { - "countryCode": country_code, - "zoneInfo": z - } - zones_list.append(zone_element) - - response_data = { - "appId": application.orig_ao_app_id, - "appProviderId": application.orig_ao_app_provider_id, - "appDeploymentZones": zones_list, - "appMetaData": appMetadata, - "appQoSProfile": appQoSProfile, - "appComponentSpecs": json.loads(application.orig_ao_app_component_specs) - } - application_response_data = InlineResponse2007.from_dict(response_data) - return application_response_data - - -def check_artefact_id(federation_context_id, body): - exist_artefact = True - artefact_id = "" - - for acs in body.app_component_specs: - artefact_id = acs.get("artefactId") - # Check if exist Federation Context Id and Artefact Id in Artefact Management - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id, - orig_am_artefact_id=artefact_id) - if not originating_am_objects: - exist_artefact = False - break - - return exist_artefact - - -def check_provider_with_artefact_id(federation_context_id, body, app_provider_id=None): - same_provider = True - artefact_id = "" - - for acs in body.app_component_specs: - artefact_id = acs.get("artefactId") - - # Check if exist Federation Context Id and Artefact Id in Artefact Management - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id, - orig_am_artefact_id=artefact_id) - if not originating_am_objects: - same_provider = False - break - artefact = originating_am_objects.get() - # Check if the provider of the body matches with the provider of the artefact - if not app_provider_id: - app_provider_id = body.app_provider_id - if app_provider_id != artefact.orig_am_app_provider_id: - same_provider = False - break - - return same_provider - - -def check_deployment_zones(federation_context_id, body): - exist_zone = True - - # Check if exist Federation Context Id in Availability Zones - originating_zi_objects = OriginatingZoneInfo.objects(orig_zi_federation_context_id=federation_context_id) - if not originating_zi_objects: - raise APIError(404, "Availability Zones not found for this Federation Context. " - "Please subscribe to some zone before onboarding your app") - - # check Zones of the Federation Context Id - zones = originating_zi_objects.get() - for acs in body.app_deployment_zones: - # Check if exist Federation Context Id and Zone Id in Availability Zones - if acs not in zones.orig_zi_acceptedAvailabilityZones: - return False - - # Check if exist deployment zones in Edge Cloud Platform - for acs in body.app_deployment_zones: - # Check if exist Zone Id in i2edge - zone_data = srm.get_zone_by_zone_id(acs) - if not zone_data: - return False - - return exist_zone - - -def fill_application_onboarding_mongo_document(federation_context_id, body): - - onboarding_data = { - "orig_ao_federation_context_id": federation_context_id, - "orig_ao_app_id": body.app_id, - "orig_ao_app_provider_id": body.app_provider_id, - "orig_ao_app_deployment_zones": body.app_deployment_zones, - "orig_ao_app_meta_data_app_name": body.app_meta_data.app_name, - "orig_ao_app_meta_data_version": body.app_meta_data.version, - "orig_ao_app_meta_data_app_description": body.app_meta_data.app_description, - "orig_ao_app_meta_data_mobility_support": body.app_meta_data.mobility_support, - "orig_ao_app_meta_data_access_token": body.app_meta_data.access_token, - "orig_ao_app_meta_data_category": body.app_meta_data.category, - "orig_ao_app_qos_profile_latency_constraints": body.app_qo_s_profile.latency_constraints, - "orig_ao_app_qos_profile_bandwidth_required": body.app_qo_s_profile.bandwidth_required, - "orig_ao_app_qos_profile_multi_user_clients": body.app_qo_s_profile.multi_user_clients, - "orig_ao_app_qos_profile_no_of_users_per_app_inst": body.app_qo_s_profile.no_of_users_per_app_inst, - "orig_ao_app_qos_profile_app_provisioning": body.app_qo_s_profile.app_provisioning, - "orig_ao_app_component_specs": json.dumps(body.app_component_specs), - "orig_ao_app_status_callback_link": body.app_status_callback_link - } - - return onboarding_data - - -def fill_update_application_onboarding_mongo_document(body, originating_ao_instance): - - app_update_component_specs_list = [] - for acs in body.app_component_specs: - data_acs = { - "artefactId": acs.get("artefactId") - } - if acs.get("serviceNameNB"): - data_acs["serviceNameNB"] = acs.get("serviceNameNB") - if acs.get("serviceNameEW"): - data_acs["serviceNameEW"] = acs.get("serviceNameEW") - if acs.get("componentName"): - data_acs["componentName"] = acs.get("componentName") - app_update_component_specs_list.append(data_acs) - - onboarding_update_data = { - "app_component_specs": json.dumps(app_update_component_specs_list), - "federation_context_app_id": originating_ao_instance - } - if body.app_upd_qo_s_profile: - if body.app_upd_qo_s_profile.latency_constraints: - onboarding_update_data["app_qos_profile_latency_constraints"] = body.app_upd_qo_s_profile.latency_constraints - if body.app_upd_qo_s_profile.bandwidth_required: - onboarding_update_data["app_qos_profile_bandwidth_required"] = body.app_upd_qo_s_profile.bandwidth_required - if body.app_upd_qo_s_profile.multi_user_clients: - onboarding_update_data["app_qos_profile_multi_user_clients"] = body.app_upd_qo_s_profile.multi_user_clients - if body.app_upd_qo_s_profile.no_of_users_per_app_inst: - onboarding_update_data["app_qos_profile_no_of_users_per_app_inst"] = body.app_upd_qo_s_profile.no_of_users_per_app_inst - if body.app_upd_qo_s_profile.app_provisioning: - onboarding_update_data["app_qos_profile_app_provisioning"] = body.app_upd_qo_s_profile.app_provisioning - if body.app_upd_qo_s_profile.mobility_support: - onboarding_update_data["app_qos_profile_mobility_support"] = body.app_upd_qo_s_profile.mobility_support - - return onboarding_update_data - - -def _prune_orphan_deployment_records(federation_context_id, app_id): - """Remove deployment bookkeeping records that have no live instances.""" - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=app_id - ) - if originating_ad_objects: - originating_ad_objects.delete() - - -def check_child_onboarding(federation_context_id, app_id): - found = False - - originating_ad_objects = OriginatingApplicationDeploymentManagement.objects( - orig_ad_federation_context_id=federation_context_id, - orig_ad_app_id=app_id - ) - if originating_ad_objects: - return True - - return found diff --git a/src/adapters/tf_adapter/artefact_management.py b/src/adapters/tf_adapter/artefact_management.py deleted file mode 100644 index 1b5ecf228926fc9ef079af43d725272e849f83f4..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/artefact_management.py +++ /dev/null @@ -1,450 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import base64 -import json -from mongoengine.errors import ValidationError - -from models.inline_response2005 import InlineResponse2005 # noqa: E501 -import util -from adapters.error import APIError -from models.mongo_document import OriginatingOperatorPlatform -from models.mongo_document import OriginatingArtefactManagement -from models.mongo_document import OriginatingApplicationOnboardingManagement -from clients import artefact_manager -from clients import srm -from configparser import ConfigParser -import os - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -ARTEFACT_MANAGER_ENABLED = CONFIG.getboolean("artefact_manager", "enabled") -DST_REGISTRY = CONFIG.get("artefact_manager", "dst_registry") -DST_USERNAME = CONFIG.get("artefact_manager", "dst_username") -DST_PASSWORD = CONFIG.get("artefact_manager", "dst_password") -DST_TOKEN = CONFIG.get("artefact_manager", "dst_token") - - -def get_artefact(federation_context_id, artefact_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves details about an artefact. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: InlineResponse2005 - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and Artefact Id in Artefact Management - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id, - orig_am_artefact_id=artefact_id) - if not originating_am_objects: - raise APIError(404, "Federation Context and Artefact Id Not Found at Artefact Management") - - artefact = originating_am_objects.get() - - artefactRepoLocation = {'repoURL': artefact.orig_am_artefact_repo_location_repo_url, - 'userName': artefact.orig_am_artefact_repo_location_user_name, - 'password': artefact.orig_am_artefact_repo_location_password, - 'token': artefact.orig_am_artefact_repo_location_token} - - response_data = { - "artefactId": artefact.orig_am_artefact_id, - "appProviderId": artefact.orig_am_app_provider_id, - "artefactName": artefact.orig_am_artefact_name, - "artefactDescription": artefact.orig_am_artefact_description, - "artefactVersionInfo": artefact.orig_am_artefact_version_info, - "artefactVirtType": artefact.orig_am_artefact_virt_type, - "artefactFileName": artefact.orig_am_artefact_filename, - "artefactFileFormat": artefact.orig_am_artefact_file_format, - "artefactDescriptorType": artefact.orig_am_artefact_descriptor_type, - "repoType": artefact.orig_am_repo_type, - "artefactRepoLocation": artefactRepoLocation - } - artefact_response_data = InlineResponse2005.from_dict(response_data) - return artefact_response_data - - -def remove_artefact(federation_context_id, artefact_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Removes an artefact from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: None - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and Artefact Id in Artefact Management - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id, - orig_am_artefact_id=artefact_id) - if not originating_am_objects: - raise APIError(404, "Federation Context and Artefact Id Not Found at Artefact Management") - artefact_instance = originating_am_objects.get() - - # Check if there are onboardings dependents of the artefact by provider - if check_child_artefact(federation_context_id, artefact_id, artefact_instance): - raise APIError(409, "Unable to remove Artefact. There are application onboardings dependent. Remove it and try again ") - - try: - response = srm.delete_artefact(artefact_id) - if response.status_code != 200: - raise APIError(422, f"Unable to delete artefact from Edge Cloud Platform. Response: {response.content}") - except Exception as error: - raise APIError(422, f"Unable to delete artefact from Edge Cloud Platform. Error: {error}") - - # Delete artefact from Federation Manager - originating_am_objects.delete() - # TODO: delete artefact from AM - - return 'Artefact deletion successful', 200 - - -def upload_artefact(body, federation_context_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Uploads application artefact on partner OP. Artefact is a zip file containing scripts and/or packaging files like Terraform or Helm which are required to create an instance of an application. - - # noqa: E501 - - :param artefact_id: - :type artefact_id: dict | bytes - :param app_provider_id: - :type app_provider_id: dict | bytes - :param artefact_name: - :type artefact_name: str - :param artefact_version_info: - :type artefact_version_info: str - :param artefact_description: - :type artefact_description: str - :param artefact_virt_type: - :type artefact_virt_type: str - :param artefact_file_name: - :type artefact_file_name: str - :param artefact_file_format: - :type artefact_file_format: str - :param artefact_descriptor_type: - :type artefact_descriptor_type: str - :param repo_type: - :type repo_type: str - :param artefact_repo_location: - :type artefact_repo_location: dict | bytes - :param artefact_file: - :type artefact_file: strstr - :param component_spec: - :type component_spec: list | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id and Artefact Id in Artefact Management - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id, - orig_am_artefact_id=body.artefact_id) - if originating_am_objects: - raise APIError(409, "Federation Context and Artefact Id already exists at Artefact Management") - - # Check if exist artefact id in the database. If found artefact id belongs to another federation - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_artefact_id=body.artefact_id) - if originating_am_objects: - raise APIError(409, "Artefact Id already exists for another Federation at Artefact Management") - - # Provider is mandatory - if body.app_provider_id == "": - raise APIError(400, f"appProviderId is empty") - - # Artefact name is mandatory - if body.artefact_name == "": - raise APIError(400, f"artefactName is empty") - - # Artefact version info is mandatory - if body.artefact_version_info == "": - raise APIError(400, f"artefactVersionInfo is empty") - - # Artefact virtualization type is mandatory - if body.artefact_virt_type == "": - raise APIError(400, f"artefactVirtType is empty") - - # Artefact descriptor type is mandatory - if body.artefact_descriptor_type is None: - raise APIError(400, f"artefactDescriptorType is empty") - - if body.repo_type == util.RepoType.UPLOAD.value: - - # Check artefact file - if body.artefact_file == "": - raise APIError(400, f"artefactFile is empty") - - try: - decoded_data = base64.b64decode(body.artefact_file) - except Exception as error: - raise APIError(422, f"Incorrect Artefact File. Error: {error}") - - if body.repo_type == util.RepoType.PUBLIC.value: - if body.artefact_repo_location.repo_url == "": - raise APIError(400, f"You have chosen PUBLICREPO but the repoUrl is empty") - body.artefact_file = "" - - if body.repo_type == util.RepoType.PRIVATE.value: - if body.artefact_repo_location.repo_url == "": - raise APIError(400, f"You have chosen PRIVATEREPO but the repoUrl is empty") - if (body.artefact_repo_location.user_name == "" and body.artefact_repo_location.password == "" and - body.artefact_repo_location.token == ""): - raise APIError(400, f"You have chosen PRIVATEREPO but credentials or token are empty") - if body.artefact_repo_location.user_name != "" and body.artefact_repo_location.password == "": - raise APIError(400, f"You have chosen PRIVATEREPO with userName but Password is empty") - if body.artefact_repo_location.user_name == "" and body.artefact_repo_location.password != "": - raise APIError(400, f"You have chosen PRIVATEREPO with Password but userName is empty") - body.artefact_file = "" - - if ARTEFACT_MANAGER_ENABLED: - # Onboarding artefact to Artefact Manager - if body.repo_type == util.RepoType.PUBLIC.value or body.repo_type == util.RepoType.PRIVATE.value: - artefact_manager_adapted_body = create_artefact_manager_adapted_body(body) - artefact_manager_response = artefact_manager.post_copy_artefact(artefact_manager_adapted_body) - - if artefact_manager_response.status_code != 200: - raise APIError(422, f"Unable to copy artefact. Response: {artefact_manager_response.content}") - - body.artefact_repo_location.repo_url = DST_REGISTRY - body.artefact_repo_location.user_name = DST_USERNAME - body.artefact_repo_location.password = DST_PASSWORD - body.artefact_repo_location.token = DST_TOKEN - # TODO: RepoType = UPLOAD - - # Onboarding artefact to Edge Cloud Platform - try: - response = srm.onboarding_artefact(body.to_gsma_input()) - print(f"DEBUG: ECP response status: {response.status_code}, body: {response.text}") - if response.status_code not in [200, 201, 204]: - try: - response_data = response.json() - except ValueError: - response_data = response.text - return response_data, 409 - except Exception as error: - raise APIError(422, f"Unable to upload artefact to Edge Cloud Platform. Error: {error}") - - # Convert the original model instance to the MongoEngine document - artefact_data = fill_artefact_mongo_document(federation_context_id, body) - - # Create a new MongoEngine document and save it to MongoDB - new_artefact = OriginatingArtefactManagement(**artefact_data) - new_artefact.save() - - return 'Artefact uploaded successfully', 200 - - -def fill_artefact_mongo_document(federation_context_id, body): - - component_spec_list = [] - for c in body.component_spec: - - exposed_interfaces_list = [] - for e in c.exposed_interfaces or []: - data_ei = { - "orig_ei_interface_id": e.interface_id, - "orig_ei_comm_protocol": e.comm_protocol, - "orig_ei_comm_port": e.comm_port, - "orig_ei_visibility_type": e.visibility_type, - "orig_ei_network": e.network, - "orig_ei_interface_name": e.interface_name - } - exposed_interfaces_list.append(data_ei) - - gpu_list = [] - for g in c.compute_resource_profile.gpu or []: - data_gpu = { - "orig_g_gpu_vendor_type": g.gpu_vendor_type, - "orig_g_gpu_mode_name": g.gpu_mode_name, - "orig_g_gpu_memory": g.gpu_memory, - "orig_g_num_gpu": g.num_gpu, - } - gpu_list.append(data_gpu) - - huge_pages_list = [] - for h in c.compute_resource_profile.hugepages or []: - data_hp = { - "orig_h_page_size": h.page_size, - "orig_h_number": h.number - } - huge_pages_list.append(data_hp) - - comp_env_params_list = [] - for cep in c.comp_env_params or []: - data_comp = { - "orig_cep_env_var_name": cep.env_var_name, - "orig_cep_env_value_type": cep.env_value_type, - "orig_cep_env_var_value": cep.env_var_value, - "orig_cep_env_var_src": cep.env_var_src - } - comp_env_params_list.append(data_comp) - - pv_list = [] - for v in c.persistent_volumes or []: - data_pv = { - "orig_pv_volume_size": v.volume_size, - "orig_pv_volume_mounth_path": v.volume_mount_path, - "orig_pv_volume_name": v.volume_name, - "orig_pv_ephemeral_type": v.ephemeral_type, - "orig_pv_access_mode": v.access_mode, - "orig_pv_sharing_policy": v.sharing_policy - } - pv_list.append(data_pv) - - command_line_params_command = None - command_line_params_command_args = None - if c.command_line_params: - command_line_params_command = c.command_line_params.command - command_line_params_command_args = c.command_line_params.command_args - - deployment_config_config_type = None - deployment_config_contents = None - if c.deployment_config: - deployment_config_config_type = c.deployment_config.config_type - deployment_config_contents = c.deployment_config.contents - - data_ce = { - "orig_ce_component_name": c.component_name, - "orig_ce_component_spec_images": c.images, - "orig_ce_component_spec_num_of_instances": c.num_of_instances, - "orig_ce_component_spec_restart_policy": c.restart_policy, - "orig_ce_component_spec_command_line_params_command": command_line_params_command, - "orig_ce_component_spec_command_line_params_command_args": command_line_params_command_args, - "orig_ce_component_spec_exposed_interfaces": exposed_interfaces_list, - "orig_ce_component_spec_compute_resource_profile_cpuarchtype": c.compute_resource_profile.cpu_arch_type, - "orig_ce_component_spec_compute_resource_profile_numcpu": c.compute_resource_profile.num_cpu, - "orig_ce_component_spec_compute_resource_profile_memory": c.compute_resource_profile.memory, - "orig_ce_component_spec_compute_resource_profile_diskstorage": c.compute_resource_profile.disk_storage, - "orig_ce_component_spec_compute_resource_profile_gpu": gpu_list, - "orig_ce_component_spec_compute_resource_profile_vpu": c.compute_resource_profile.vpu, - "orig_ce_component_spec_compute_resource_profile_fpga": c.compute_resource_profile.fpga, - "orig_ce_component_spec_compute_resource_profile_hugepages": huge_pages_list, - "orig_ce_component_spec_compute_resource_profile_cpuexclusivity": c.compute_resource_profile.cpu_exclusivity, - "orig_ce_component_spec_comp_env_params": comp_env_params_list, - "orig_ce_component_spec_deployment_config_config_type": deployment_config_config_type, - "orig_ce_component_spec_deployment_config_contents": deployment_config_contents, - "orig_ce_component_spec_persistent_volumes": pv_list - } - component_spec_list.append(data_ce) - - artefact_data = { - "orig_am_federation_context_id": federation_context_id, - "orig_am_artefact_id": body.artefact_id, - "orig_am_app_provider_id": body.app_provider_id, - "orig_am_artefact_name": body.artefact_name, - "orig_am_artefact_version_info": body.artefact_version_info, - "orig_am_artefact_description": body.artefact_description, - "orig_am_artefact_virt_type": body.artefact_virt_type, - "orig_am_artefact_filename": body.artefact_file_name, - "orig_am_artefact_file_format": body.artefact_file_format, - "orig_am_artefact_descriptor_type": body.artefact_descriptor_type, - "orig_am_repo_type": body.repo_type, - "orig_am_artefact_repo_location_repo_url": body.artefact_repo_location.repo_url, - "orig_am_artefact_repo_location_user_name": body.artefact_repo_location.user_name, - "orig_am_artefact_repo_location_password": body.artefact_repo_location.password, - "orig_am_artefact_repo_location_token": body.artefact_repo_location.token, - # Once is uploaded the file to Edge Cloud Platform is not necessary to save the file in the MEF database - "orig_am_artefact_file": "", - # "orig_am_artefact_file": body.artefact_file, - "orig_am_component_spec": json.dumps(component_spec_list) - } - - return artefact_data - - -def check_child_artefact(federation_context_id, artefact_id, artefact_instance): - found = False - - provider_id = artefact_instance.orig_am_app_provider_id - - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id, - orig_ao_app_provider_id=provider_id - ) - if not originating_ao_objects: - return False - - instances_onboarding = originating_ao_objects.filter() - for elem in instances_onboarding: - list_specs = json.loads(elem.orig_ao_app_component_specs) - for l in list_specs: - if l.get("artefactId") == artefact_id: - return True - - return found - - -def create_artefact_manager_adapted_body(body): - artefact_repo_location = body.artefact_repo_location - repo_url = artefact_repo_location.repo_url - user_name = artefact_repo_location.user_name or None - password = artefact_repo_location.password or None - return {"src_registry_url": repo_url, - "src_artefact_name": body.artefact_name, - "src_artefact_tag": body.artefact_version_info, - "src_registry_username": user_name, - "src_registry_password": password, - "dst_registry_url": DST_REGISTRY, - "dst_artefact_name": body.artefact_name, - "dst_artefact_tag": body.artefact_version_info, - "dst_registry_username": DST_USERNAME, - "dst_registry_password": DST_PASSWORD} diff --git a/src/adapters/tf_adapter/availability_zone_info_synchronization.py b/src/adapters/tf_adapter/availability_zone_info_synchronization.py deleted file mode 100644 index a1da8d8bb27fd230a9a841f9eb1d1b86a30a682c..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/availability_zone_info_synchronization.py +++ /dev/null @@ -1,277 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -from mongoengine.errors import ValidationError - -from models.zone_registered_data import ZoneRegisteredData # noqa: E501 -from models.zone_registration_response_data import ZoneRegistrationResponseData # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatform -from models.mongo_document import OriginatingZoneInfo -from models.mongo_document import OriginatingApplicationOnboardingManagement -from adapters.error import APIError -from clients import srm - - -def get_zone_data(federation_context_id, zone_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves details about the computation and network resources that partner OP has reserved for this zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: ZoneRegisteredData - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if Federation Context Id exists in Availability Zones - originating_zi_objects = OriginatingZoneInfo.objects(orig_zi_federation_context_id=federation_context_id) - if not originating_zi_objects: - raise APIError(404, "Availability Zones not found for Federation Context") - - # Check if exist Zone at Edge Cloud Platform - try: - response_data = srm.get_zone_by_zone_id(zone_id) - resource = response_data.get("computeResourceQuotaLimits") - for d in resource: - huge = d.get("hugepages") - for h in huge: - page = h.get("pageSize") - page = page.replace("Gi", "GB") - page = page.replace("Mi", "MB") - h["pageSize"] = page - d["hugepages"] = huge - response_data["computeResourceQuotaLimits"] = resource - pass - except Exception as error: - raise APIError(422, f"Unable to retrieve zone from Edge Cloud Platform. Error: {error}") - if not response_data: - raise APIError(404, "Zone id do not exist at Edge Cloud Platform") - - # check if Zone id is in the list of availability zones of the document - zones = originating_zi_objects.get() - if zone_id not in zones.orig_zi_acceptedAvailabilityZones: - raise APIError(404, "Zone id not found for this Federation Context") - - try: - zone_response_data = ZoneRegisteredData.from_dict(response_data) - except Exception as error: - raise APIError(422, f"Retrieving zone information with issues from Edge Cloud Platform. Error: {error}") - - return zone_response_data - - -def zone_subscribe(federation_context_id, body, bearer_token=None, partner_api_root=None): # noqa: E501 - """Originating OP informs partner OP that it is willing to access the specified zones and partner OP shall reserve compute and network resources for these zones. - - # noqa: E501 - - :param body: - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: ZoneRegistrationResponseData - """ - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist availability zones in Edge Cloud Platform - try: - if not check_availability_zones(body.accepted_availability_zones): - raise APIError(404, "Availability Zones do not exist at Edge Cloud Platform") - except Exception as error: - raise APIError(422, f"Unable to get zones list from Edge Cloud Platform. Error: {error}") - - # Verifies this is a new zone request - all_originating_zones = OriginatingZoneInfo.objects() - for originating_zi in all_originating_zones: - if originating_zi.orig_zi_federation_context_id == federation_context_id: - raise APIError(409, "Availability Zone already exists for this Federation Context") - - try: - availability_zones = get_info_availability_zones_from_zones_edge_cloud_platform(body.accepted_availability_zones) - except Exception as error: - raise APIError(422, f"Unable to get zones from Edge Cloud Platform. Error: {error}") - response_data = { - "acceptedZoneResourceInfo": availability_zones - } - - try: - zone_response_data = ZoneRegistrationResponseData.from_dict(response_data) - except Exception as error: - raise APIError(422, f"Retrieving zone information with issues from Edge Cloud Platform. Error: {error}") - - # Convert the original model instance to the MongoEngine document - zone_data = { - "orig_zi_federation_context_id": federation_context_id, - "orig_zi_acceptedAvailabilityZones": body.accepted_availability_zones, - "orig_zi_availZoneNotifLink": body.avail_zone_notif_link - } - - # Create a new MongoEngine document and save it to MongoDB - new_zone = OriginatingZoneInfo(**zone_data) - new_zone.save() - - return zone_response_data - - -def zone_unsubscribe(federation_context_id, zone_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Assert usage of a partner OP zone. Originating OP informs partner OP that it will no longer access the specified zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - - # Check if exist Federation Context Id in Operator Platform - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found at Operator Platform") - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if exist Federation Context Id in Availability Zones - originating_zi_objects = OriginatingZoneInfo.objects(orig_zi_federation_context_id=federation_context_id) - if not originating_zi_objects: - raise APIError(404, "Federation Context not found at Availability Zones") - - # check if Zone id is in the list of availability zones of the document - zones = originating_zi_objects.get() - if zone_id not in zones.orig_zi_acceptedAvailabilityZones: - raise APIError(404, "Zone id not found for this Federation Context") - - # Check if there are onboardings dependents of the zone - if check_child_availability_zones(federation_context_id, zone_id): - raise APIError(409, "Unable to remove Zone. There are onboardings dependent. Remove it and try again ") - - # Get the list of the zones assigned to the federation context - availability_zones = zones.orig_zi_acceptedAvailabilityZones - try: - # To prevent if returns list as a Str - availability_zones = json.loads(availability_zones) - except Exception as error: - print(f"Unable to parse zone list JSON. Error: {error}") - - # Remove from the list the zone id passed as a parameter - availability_zones.remove(zone_id) - - # If the list of zones becomes empty, we delete the document from the collection - if len(availability_zones) == 0: - originating_zi_objects.delete() - else: - # The list is not empty and we update the document with the new list - zones.orig_zi_acceptedAvailabilityZones = availability_zones - zones.save() - - return 'Zone deregistered successfully', 200 - - -def check_availability_zones(accepted_availability_zones): - - # Get the zones list from Edge Cloud Platform - zones = srm.get_list_zones() - # Creates an array only with zone id from zones list - zone_id_array = [] - # zones = zones.json() - for zone in zones: - # If the zone value is a dict, is a correct zone, else there is an issue and returns a str - if isinstance(zone, dict): - zone_id_array.append(zone.get("zoneId")) - # remove duplicates - set_zones = set(zone_id_array) - zone_id_array = list(set_zones) - - # Compare matches between zones from Edge Cloud Platform and zones declared in the body - common = set(accepted_availability_zones) & set(zone_id_array) - - # if the matches are equal to the number of zones declared in the body returns True - if len(common) == len(accepted_availability_zones): - return True - else: - return False - - -def get_info_availability_zones_from_zones_edge_cloud_platform(availability_zones): - - # Retrieve zones from Edge Cloud Platform - info_zones_list = srm.get_zones() - zones_for_federation = [] - - # Loop zones assigned to our federation - for availability_zone in availability_zones: - - # If the availability zone matches with one of the zones of Edge Cloud Platform - # includes this zone in a table to mount response data - exit = False - for zone in info_zones_list: - # If the zone value is a dict, is a correct zone, else there is an issue and returns a str - if isinstance(zone, dict): - if availability_zone == zone.get("zoneId"): - zones_for_federation.append(zone) - break - - return zones_for_federation - - -def check_child_availability_zones(federation_context_id, zone_id): - found = False - - originating_ao_objects = OriginatingApplicationOnboardingManagement.objects( - orig_ao_federation_context_id=federation_context_id - ) - if not originating_ao_objects: - return False - - instances_onboarding = originating_ao_objects.filter() - - for elem in instances_onboarding: - list_zones = elem.orig_ao_app_deployment_zones - for l in list_zones: - if l == zone_id: - return True diff --git a/src/adapters/tf_adapter/federation_management.py b/src/adapters/tf_adapter/federation_management.py deleted file mode 100644 index bb0382a55d6bb7c17d4c555fef87c8c19c050386..0000000000000000000000000000000000000000 --- a/src/adapters/tf_adapter/federation_management.py +++ /dev/null @@ -1,411 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import json -from configparser import ConfigParser -from mongoengine.errors import ValidationError -import os - -from models.federation_context_id import FederationContextId # noqa: E501 -from models.federation_response_data import FederationResponseData # noqa: E501 -from models.inline_response2001 import InlineResponse2001 # noqa: E501 -from models.mongo_document import OriginatingOperatorPlatform -from models.mongo_document import OriginatingOperatorPlatformUpdate -from models.mongo_document import OriginatingZoneInfo -from models.mongo_document import OriginatingArtefactManagement -from adapters.error import APIError -from clients import srm - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -partnerOPFederationId = CONFIG.get("op_data", "partnerOPFederationId") -partnerOPCountryCode = CONFIG.get("op_data", "partnerOPCountryCode") -partnerOPMobileNetworkCode_MCC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MCC") -partnerOPMobileNetworkCode_MNC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MNC") -partnerOPFixedNetworkCode = CONFIG.get("op_data", "partnerOPFixedNetworkCode") -partnerOPPlatformCaps = CONFIG.get("op_data", "platformCaps") - - -def create_federation(body, bearer_token, partner_api_root=None): # noqa: E501 - """Creates one direction federation with partner operator platform. - - # noqa: E501 - - :param body: - :type body: dict | bytes - - :rtype: FederationResponseData - """ - - # Verifies this is a new federation request - all_originating_ops = OriginatingOperatorPlatform.objects() - for originating_op in all_originating_ops: - if originating_op.partner_bearer_token == bearer_token: - raise APIError(409, "Federation already exists") - - # Convert the original model instance to the MongoEngine document - mcc = None - mncs = None - token_url = None - client_id = None - client_secret = None - if body.orig_op_mobile_network_codes: - mcc = body.orig_op_mobile_network_codes.mcc or None - mncs = body.orig_op_mobile_network_codes.mncs or None - if body.partner_callback_credentials: - token_url = body.partner_callback_credentials.token_url or None - client_id = body.partner_callback_credentials.client_id or None - client_secret = body.partner_callback_credentials.client_secret or None - federation_data = { - "orig_op_federation_id": body.orig_op_federation_id, - "orig_op_country_code": body.orig_op_country_code, - "orig_op_mobile_network_codes_mcc": mcc, - "orig_op_mobile_network_codes_mncs": mncs, - "orig_op_fixed_network_codes": body.orig_op_fixed_network_codes, - "initial_date": body.initial_date, - "partner_status_link": body.partner_status_link, - "partner_callback_credentials_token_url": token_url, - "partner_callback_credentials_client_id": client_id, - "partner_callback_credentials_client_secret": client_secret, - "partner_bearer_token": bearer_token - } - - # Retrieve zone list from Edge Cloud Platform - try: - zones_list = prepare_offered_availability_zones() - except Exception as e: - raise APIError(422, f"Unable to get zones list from Edge Cloud Platform. Error: {e}") - - # Create a new MongoEngine document and save it to MongoDB - new_federation = OriginatingOperatorPlatform(**federation_data) - new_federation.save() - - response_data = { - "federationContextId": str(new_federation.id), - "partnerOPFederationId": partnerOPFederationId, - "partnerOPCountryCode": partnerOPCountryCode, - "partnerOPMobileNetworkCodes": { - "mcc": partnerOPMobileNetworkCode_MCC, - "mncs": [ - partnerOPMobileNetworkCode_MNC - ] - }, - "partnerOPFixedNetworkCodes": [ - partnerOPFixedNetworkCode - ], - "platformCaps": [ - partnerOPPlatformCaps - ], - "offeredAvailabilityZones": zones_list - } - federation_response_data = FederationResponseData.from_dict(response_data) - return federation_response_data, 200 - - -def get_federation_details(federation_context_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Retrieves details about the federation context with the partner OP. The response shall provide info about the zones offered by the partner, partner OP network codes, information about edge discovery and LCM service etc. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Retrieve zone list from Edge Cloud Platform - try: - zones_list = prepare_offered_availability_zones() - except: - raise APIError(422, "Unable to get zones list from Edge Cloud Platform") - - response_data = { - "allowedMobileNetworkIds": { - "mcc": originating_op_instance.orig_op_mobile_network_codes_mcc, - "mncs": originating_op_instance.orig_op_mobile_network_codes_mncs - }, - "allowedFixedNetworkIds": originating_op_instance.orig_op_fixed_network_codes, - "offeredAvailabilityZones": zones_list, - "platformCaps": [ - partnerOPPlatformCaps - ] - } - federation_response_data = InlineResponse2001.from_dict(response_data) - return federation_response_data - - -def update_federation(federation_context_id, body, bearer_token=None, partner_api_root=None): # noqa: E501 - """API used by the Originating OP towards the partner OP, to update the parameters associated to the existing federation - - # noqa: E501 - - :param body: Details about changes origination OP wished to apply - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - partner_update_data = { - "object_type": body.object_type, - "operation_type": body.operation_type, - "modification_date": body.modification_date, - "federation_context_id": originating_op_instance - } - - if body.object_type == "MOBILE_NETWORK_CODES": - mncs = originating_op_instance.orig_op_mobile_network_codes_mncs - if body.operation_type == "ADD_CODES": - # addMobileNetworkIds is required - if not body.add_mobile_network_ids: - raise APIError(400, f"addMobileNetworkIds is empty") - if not body.add_mobile_network_ids.mcc: - raise APIError(400, f"mcc in addMobileNetworkIds is empty") - if not body.add_mobile_network_ids.mncs: - raise APIError(400, f"mncs in addMobileNetworkIds is empty") - if body.add_mobile_network_ids.mcc != originating_op_instance.orig_op_mobile_network_codes_mcc: - raise APIError(409, "MCC does not match with the one registered") - partner_update_data["add_mobile_network_ids_mcc"] = body.add_mobile_network_ids.mcc - partner_update_data["add_mobile_network_ids_mncs"] = body.add_mobile_network_ids.mncs - mncs.extend(body.add_mobile_network_ids.mncs) - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.operation_type == "REMOVE_CODES": - # removeMobileNetworkIds is required - if not body.remove_mobile_network_ids: - raise APIError(400, f"removeMobileNetworkIds is empty") - if not body.remove_mobile_network_ids.mcc: - raise APIError(400, f"mcc in removeMobileNetworkIds is empty") - if not body.remove_mobile_network_ids.mncs: - raise APIError(400, f"mncs in removeMobileNetworkIds is empty") - if body.remove_mobile_network_ids.mcc != originating_op_instance.orig_op_mobile_network_codes_mcc: - raise APIError(409, "MCC does not match with the one registered") - partner_update_data["remove_mobile_network_ids_mcc"] = body.remove_mobile_network_ids.mcc - partner_update_data["remove_mobile_network_ids_mncs"] = body.remove_mobile_network_ids.mncs - mncs = [code for code in mncs if code not in body.remove_mobile_network_ids.mncs] - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.operation_type == "UPDATE_CODES": - # addMobileNetworkIds and removeMobileNetworkIds are required - if not body.add_mobile_network_ids or not body.remove_mobile_network_ids: - raise APIError(400, f"addMobileNetworkIds or removeMobileNetworkIds are empty") - partner_update_data["add_mobile_network_ids_mcc"] = body.add_mobile_network_ids.mcc - partner_update_data["add_mobile_network_ids_mncs"] = body.add_mobile_network_ids.mncs - partner_update_data["remove_mobile_network_ids_mcc"] = body.remove_mobile_network_ids.mcc - partner_update_data["remove_mobile_network_ids_mncs"] = body.remove_mobile_network_ids.mncs - originating_op_instance.update(set__orig_op_mobile_network_codes_mcc=body.add_mobile_network_ids.mcc) - mncs = body.add_mobile_network_ids.mncs - if body.remove_mobile_network_ids.mcc == body.add_mobile_network_ids.mcc: - mncs = [code for code in body.add_mobile_network_ids.mncs if code not in body.remove_mobile_network_ids.mncs] - originating_op_instance.update(set__orig_op_mobile_network_codes_mncs=mncs) - elif body.object_type == "FIXED_NETWORK_CODES": - original_fixed_codes = originating_op_instance.orig_op_fixed_network_codes - if body.operation_type == "ADD_CODES": - # addFixedNetworkIds is required - if not body.add_fixed_network_ids: - raise APIError(400, f"addFixedNetworkIds is empty") - partner_update_data["add_fixed_network_ids"] = body.add_fixed_network_ids - fixed_codes = original_fixed_codes - fixed_codes.extend(body.add_fixed_network_ids) - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - if body.operation_type == "REMOVE_CODES": - # removeFixedNetworkIds is required - if not body.remove_fixed_network_ids: - raise APIError(400, f"removeFixedNetworkIds is empty") - partner_update_data["remove_fixed_network_ids"] = body.remove_fixed_network_ids - fixed_codes = [code for code in original_fixed_codes if code not in body.remove_fixed_network_ids] - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - elif body.operation_type == "UPDATE_CODES": - # addFixedNetworkIds and removeFixedNetworkIds are required - if not body.add_fixed_network_ids or not body.remove_fixed_network_ids: - raise APIError(400, f"addFixedNetworkIds or removeFixedNetworkIds are empty") - partner_update_data["add_fixed_network_ids"] = body.add_fixed_network_ids - partner_update_data["remove_fixed_network_ids"] = body.remove_fixed_network_ids - fixed_codes = [code for code in body.add_fixed_network_ids if code not in body.remove_fixed_network_ids] - originating_op_instance.update(set__orig_op_fixed_network_codes=fixed_codes) - - # Retrieve zone list from Edge Cloud Platform - try: - zones_list = prepare_offered_availability_zones() - except Exception: - raise APIError(422, "Unable to get zones list from Edge Cloud Platform") - - # Create a new MongoEngine document and save it to MongoDB - new_partner_update = OriginatingOperatorPlatformUpdate(**partner_update_data) - new_partner_update.save() - - # Re-fetch the federation instance (this should not fail since we validated it earlier) - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - originating_op_instance = originating_op_objects[0] - except Exception: - # This should never happen since we validated the ID earlier - raise APIError(500, f"Failed to re-fetch federation instance") - - response_data = { - "allowedMobileNetworkIds": { - "mcc": originating_op_instance.orig_op_mobile_network_codes_mcc, - "mncs": originating_op_instance.orig_op_mobile_network_codes_mncs - }, - "allowedFixedNetworkIds": originating_op_instance.orig_op_fixed_network_codes, - "offeredAvailabilityZones": zones_list, - "platformCaps": [ - partnerOPPlatformCaps - ] - } - federation_response_data = InlineResponse2001.from_dict(response_data) - - return federation_response_data - - -def delete_federation_details(federation_context_id, bearer_token=None, partner_api_root=None): # noqa: E501 - """Remove existing federation with the partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - try: - originating_op_objects = OriginatingOperatorPlatform.objects(id=federation_context_id) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - except ValidationError: - raise APIError(400, f"Invalid federation context ID format: {federation_context_id}") - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation. Reason: {error}") - - # Check if there are zones or artefacts dependents of the federation - if check_child_federation(federation_context_id): - raise APIError(409, "Unable to remove Federation. There are availability zones dependent. Remove it and try again ") - - # Delete all the federation updates related to federation - id_federation = originating_op_instance.id - originating_op_instance_update_objects = OriginatingOperatorPlatformUpdate.objects() - for o in originating_op_instance_update_objects: - try: - if o.federation_context_id.pk == id_federation: - o.delete() - except: - pass - - # Delete Federation - originating_op_instance.delete() - return 'Federation removed successfully', 200 - - -def get_federation_context_id(bearer_token, partner_api_root=None): # noqa: E501 - """Retrieves the existing federationContextId with partner operator platform. - - # noqa: E501 - - :rtype: InlineResponse2002 - """ - - try: - originating_op_objects = OriginatingOperatorPlatform.objects(partner_bearer_token=bearer_token) - if not originating_op_objects: - raise APIError(404, "Federation not found") - originating_op_instance = originating_op_objects[0] - federation_context_id_data = { - "federationContextId": str(originating_op_instance.id) - } - federation_context_id = FederationContextId.from_dict(federation_context_id_data) - return federation_context_id - except APIError: - raise # Re-raise APIError as-is - except Exception as error: - raise APIError(500, f"Error while retrieving federation context ID. Reason: {error}") - - -def prepare_offered_availability_zones(): - - offered_zones_array = [] - - # Get the zones list from Edge Cloud Platform - zones = srm.get_list_zones() - for zone in zones: - # If the zone value is a dict, is a correct zone, else there is an issue and returns a str - if isinstance(zone, dict): - geolocation = zone.get("geolocation") - if geolocation: - geolocation = geolocation.replace("_", ",") - - array_numbers = geolocation.split(",") - numberone = float(array_numbers[0]) - numbertwo = float(array_numbers[1]) - numberone_4 = f"{numberone:.4f}" - numbertwo_4 = f"{numbertwo:.4f}" - - geolocation = f"{numberone_4},{numbertwo_4}" # 4 decimals - else: - geolocation = "0.0000,0.0000" - - zone_data = { - "zoneId": zone.get("zoneId"), - "geographyDetails": zone.get("geographyDetails") or "unknown", - "geolocation": geolocation - } - offered_zones_array.append(zone_data) - - return offered_zones_array - - -def check_child_federation(federation_context_id): - found = False - - # Check zones - originating_az_objects = OriginatingZoneInfo.objects( - orig_zi_federation_context_id=federation_context_id - ) - if originating_az_objects: - return True - - # Check Artefacts - originating_am_objects = OriginatingArtefactManagement.objects( - orig_am_federation_context_id=federation_context_id) - - if originating_am_objects: - return True - - return found diff --git a/src/api/__init__.py b/src/api/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/api/application_deployment_management.py b/src/api/application_deployment_management.py deleted file mode 100644 index 55588b602c5ab680fe88e780c3a343c7be23ba1e..0000000000000000000000000000000000000000 --- a/src/api/application_deployment_management.py +++ /dev/null @@ -1,143 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from flask import abort - -from adapters.error import APIError -from adapters.injector import resolve_adapter -from models.application_lcm_body import ApplicationLcmBody # noqa: E501 -import connexion -import util - - -def get_all_app_instances(federation_context_id, app_id, app_provider_id): # noqa: E501 - """Retrieves all application instance of partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_provider_id: - :type app_provider_id: dict | bytes - - :rtype: List[InlineResponse2009] - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.application_deployment_management.get_all_app_instances(federation_context_id, app_id, - app_provider_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def get_app_instance_details(federation_context_id, app_id, app_instance_id, zone_id): # noqa: E501 - """Retrieves an application instance details from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: InlineResponse2008 - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.application_deployment_management.get_app_instance_details(federation_context_id, app_id, - app_instance_id, zone_id, - bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def install_app(federation_context_id, body=None): # noqa: E501 - """Instantiates an application on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param body: Details about application and zones where application instance should be created. It also definea call back URI which the partner OP shall use update home OP about a change in instance status. - :type body: dict | bytes - - :rtype: InlineResponse202 - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = ApplicationLcmBody.from_dict(body) # noqa: E501 - except Exception as error: - raise APIError(422, f" Error: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.application_deployment_management.install_app(federation_context_id, body, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def remove_app(federation_context_id, app_id, app_instance_id, zone_id): # noqa: E501 - """Terminate an application instance on a partner OP zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - :param app_instance_id: - :type app_instance_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.application_deployment_management.remove_app(federation_context_id, app_id, app_instance_id, - zone_id, bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) diff --git a/src/api/application_onboarding_management.py b/src/api/application_onboarding_management.py deleted file mode 100644 index 5a6b23efb10aa0ba22256a10139a2a574699e37b..0000000000000000000000000000000000000000 --- a/src/api/application_onboarding_management.py +++ /dev/null @@ -1,139 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from flask import abort - -from adapters.error import APIError -from adapters.injector import resolve_adapter -from models.application_onboarding_body import ApplicationOnboardingBody # noqa: E501 -from models.app_app_id_body import AppAppIdBody # noqa: E501 -import connexion -import util - - -def delete_app(federation_context_id, app_id): # noqa: E501 - """Deboards the application from any zones, if any, and deletes the App. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.application_onboarding_management.delete_app(federation_context_id, app_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def onboard_application(body, federation_context_id): # noqa: E501 - """Submits an application details to a partner OP. Based on the details provided, partner OP shall do bookkeeping, resource validation and other pre-deployment operations. - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefacts, QoS profile and regions where application shall be made available etc. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = ApplicationOnboardingBody.from_dict(connexion.request.get_json()) - except Exception as error: - abort(422, f"Application Onboarding Validation Error. Message: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.application_onboarding_management.onboard_application(body, federation_context_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def update_application(body, federation_context_id, app_id): # noqa: E501 - """Updates partner OP about changes in application compute resource requirements, QOS Profile, associated descriptor or change in associated components - - # noqa: E501 - - :param body: Details about application compute resource requirements, associated artefact and QOS profile that needs to be updated. - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = AppAppIdBody.from_dict(connexion.request.get_json()) - except Exception as error: - abort(422, f"Application Update Validation Error. Message: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.application_onboarding_management.update_application(body, federation_context_id, app_id, - bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def view_application(federation_context_id, app_id): # noqa: E501 - """Retrieves application details from partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param app_id: - :type app_id: dict | bytes - - :rtype: InlineResponse2007 - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.application_onboarding_management.view_application(federation_context_id, app_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) diff --git a/src/api/artefact_management.py b/src/api/artefact_management.py deleted file mode 100644 index 03ac59c8e75322b24539d89ecb1d60173f2fa646..0000000000000000000000000000000000000000 --- a/src/api/artefact_management.py +++ /dev/null @@ -1,127 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from flask import abort -from adapters.error import APIError -from adapters.injector import resolve_adapter -from models.federation_context_id_artefact_body import FederationContextIdArtefactBody -import connexion -import util - - -def get_artefact(federation_context_id, artefact_id): # noqa: E501 - """Retrieves details about an artefact. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: InlineResponse2005 - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.artefact_management.get_artefact(federation_context_id, artefact_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def remove_artefact(federation_context_id, artefact_id): # noqa: E501 - """Removes an artefact from partner OP. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param artefact_id: - :type artefact_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.artefact_management.remove_artefact(federation_context_id, artefact_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def upload_artefact(body, federation_context_id): # noqa: E501 - """Uploads application artefact on partner OP. Artefact is a zip file containing scripts and/or packaging files like Terraform or Helm which are required to create an instance of an application. - - # noqa: E501 - - :param artefact_id: - :type artefact_id: dict | bytes - :param app_provider_id: - :type app_provider_id: dict | bytes - :param artefact_name: - :type artefact_name: str - :param artefact_version_info: - :type artefact_version_info: str - :param artefact_description: - :type artefact_description: str - :param artefact_virt_type: - :type artefact_virt_type: str - :param artefact_file_name: - :type artefact_file_name: str - :param artefact_file_format: - :type artefact_file_format: str - :param artefact_descriptor_type: - :type artefact_descriptor_type: str - :param repo_type: - :type repo_type: str - :param artefact_repo_location: - :type artefact_repo_location: dict | bytes - :param artefact_file: - :type artefact_file: strstr - :param component_spec: - :type component_spec: list | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = FederationContextIdArtefactBody.from_dict(connexion.request.get_json()) - except Exception as error: - raise APIError(422, f"Artefact Validation Error. Message: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.artefact_management.upload_artefact(body, federation_context_id, bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) diff --git a/src/api/authorization.py b/src/api/authorization.py deleted file mode 100644 index 5e6570884b6f30a955a17f858480bf3b608b5364..0000000000000000000000000000000000000000 --- a/src/api/authorization.py +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - - -def check_oAuth2ClientCredentials(token): - return {'scopes': ['fed-mgmt'], 'uid': 'test_value'} - - -def validate_scope_oAuth2ClientCredentials(required_scopes, token_scopes): - return set(required_scopes).issubset(set(token_scopes)) diff --git a/src/api/availability_zone_info_synchronization.py b/src/api/availability_zone_info_synchronization.py deleted file mode 100644 index 4156faeb704b9fbf43fbe66dfc3cda43411cf2db..0000000000000000000000000000000000000000 --- a/src/api/availability_zone_info_synchronization.py +++ /dev/null @@ -1,105 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from flask import abort - -from adapters.error import APIError -from adapters.injector import resolve_adapter -from models.zone_registration_request_data import ZoneRegistrationRequestData # noqa: E501 -import connexion -import util - - -def get_zone_data(federation_context_id, zone_id): # noqa: E501 - """Retrieves details about the computation and network resources that partner OP has reserved for this zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: ZoneRegisteredData - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.availability_zone_info_synchronization.get_zone_data(federation_context_id, zone_id, - bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def zone_subscribe(body, federation_context_id): # noqa: E501 - """Originating OP informs partner OP that it is willing to access the specified zones and partner OP shall reserve compute and network resources for these zones. - - # noqa: E501 - - :param body: - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: ZoneRegistrationResponseData - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = ZoneRegistrationRequestData.from_dict(body) # noqa: E501 - except Exception as error: - raise APIError(422, f"Zone Validation Error. Message: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.availability_zone_info_synchronization.zone_subscribe(federation_context_id, body, - bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def zone_unsubscribe(federation_context_id, zone_id): # noqa: E501 - """Assert usage of a partner OP zone. Originating OP informs partner OP that it will no longer access the specified zone. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - :param zone_id: - :type zone_id: dict | bytes - - :rtype: None - """ - - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.availability_zone_info_synchronization.zone_unsubscribe(federation_context_id, zone_id, - bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) diff --git a/src/api/federation_management.py b/src/api/federation_management.py deleted file mode 100644 index 739dc7300eee43b1c061cc7422fc721bbd69259e..0000000000000000000000000000000000000000 --- a/src/api/federation_management.py +++ /dev/null @@ -1,157 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import connexion -from configparser import ConfigParser -from flask import abort -import os - -from adapters.error import APIError -import util - -from models.federation_request_data import FederationRequestData # noqa: E501 -from models.federation_context_id_partner_body import FederationContextIdPartnerBody # noqa: E501 -from adapters.injector import resolve_adapter - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -partnerOPFederationId = CONFIG.get("op_data", "partnerOPFederationId") -partnerOPCountryCode = CONFIG.get("op_data", "partnerOPCountryCode") -partnerOPMobileNetworkCode_MCC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MCC") -partnerOPMobileNetworkCode_MNC = CONFIG.get("op_data", "partnerOPMobileNetworkCode_MNC") -partnerOPFixedNetworkCode = CONFIG.get("op_data", "partnerOPFixedNetworkCode") -platformCaps = CONFIG.get("op_data", "platformCaps") - - -def create_federation(body): # noqa: E501 - """Creates one direction federation with partner operator platform. - - # noqa: E501 - - :param body: - :type body: dict | bytes - - :rtype: FederationResponseData - """ - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = FederationRequestData.from_dict(connexion.request.get_json()) # noqa: E501 - except Exception as error: - abort(422, f"Federation Validation Error. Message: {error}") - try: - adapter = resolve_adapter(headers) - return adapter.federation_management.create_federation(body, bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def get_federation_details(federation_context_id): # noqa: E501 - """Retrieves details about the federation context with the partner OP. The response shall provide info about the zones offered by the partner, partner OP network codes, information about edge discovery and LCM service etc. - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.federation_management.get_federation_details(federation_context_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def update_federation(federation_context_id, body): # noqa: E501 - """API used by the Originating OP towards the partner OP, to update the parameters associated to the existing federation - - # noqa: E501 - - :param body: Details about changes origination OP wished to apply - :type body: dict | bytes - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: InlineResponse2001 - """ - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - body = FederationContextIdPartnerBody.from_dict(body) # noqa: E501 - except Exception as error: - raise APIError(422, f"Federation Validation Error. Message: {error}") - - try: - adapter = resolve_adapter(headers) - return adapter.federation_management.update_federation(federation_context_id, body, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def delete_federation_details(federation_context_id): # noqa: E501 - """Remove existing federation with the partner OP - - # noqa: E501 - - :param federation_context_id: - :type federation_context_id: dict | bytes - - :rtype: None - """ - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.federation_management.delete_federation_details(federation_context_id, bearer_token, - partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) - - -def get_federation_context_id(): # noqa: E501 - """Retrieves the existing federationContextId with partner operator platform. - - # noqa: E501 - - :rtype: InlineResponse2002 - """ - # Extract the token and the headers - bearer_token = util.get_token_from_request(connexion) - headers = dict(connexion.request.headers) - partner_api_root = headers.get("X-Partner-Api-Root") - - try: - adapter = resolve_adapter(headers) - return adapter.federation_management.get_federation_context_id(bearer_token, partner_api_root) - except APIError as error: - abort(error.status_code, error.detail_error) diff --git a/src/clients/__init__.py b/src/clients/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/clients/artefact_manager.py b/src/clients/artefact_manager.py deleted file mode 100644 index 0a35c010ef6beeb22c746c8b3c9a721797e55067..0000000000000000000000000000000000000000 --- a/src/clients/artefact_manager.py +++ /dev/null @@ -1,36 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import requests -from configparser import ConfigParser -import os - -from requests import Response - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -HOST = CONFIG.get("artefact_manager", "host") -PORT = int(CONFIG.get("artefact_manager", "port")) -TIMEOUT_REQUESTS = 20 - - -def post_copy_artefact(params: dict) -> Response: - url = f"http://{HOST}:{PORT}/copy-artefact" - headers = { - "accept": "application/json", - "Content-Type": "application/json" - } - return requests.post(url, json=params, headers=headers, timeout=TIMEOUT_REQUESTS) diff --git a/src/clients/fed_manager.py b/src/clients/fed_manager.py deleted file mode 100644 index d77898df06e4fe43412cfa8fe0f93ff8305f9c0e..0000000000000000000000000000000000000000 --- a/src/clients/fed_manager.py +++ /dev/null @@ -1,425 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -import requests -from urllib.parse import urlparse - - -def _gsma_payload(body): - if hasattr(body, "to_gsma_input"): - return body.to_gsma_input() - return body - - -def check_url(api_root, path): - - url = f"{api_root}/operatorplatform/federation/v1/{path}" - parsed_url = urlparse(url) - if parsed_url.scheme and parsed_url.netloc: - return url - return None - - -def create_federation(body, token, api_root): - - headers = { - "Content-Type": "application/json", - "Accept": "application/json", - "Authorization": f"Bearer {token}" - } - - partner_op_url = check_url(api_root, "partner") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = body.to_gsma_input() - - response = requests.post(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def get_federation(federation_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/partner") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def update_federation(federation_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/partner") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = body.to_gsma_input() - - response = requests.patch(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def delete_federation(federation_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/partner") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.delete(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def get_federation_context_id(token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, "fed-context-id") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - return response.json() - - -def create_availability_zones(federation_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/zones") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = body.to_gsma_input() - - response = requests.post(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def get_availability_zones(federation_id, zone_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/zones/{zone_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Zone not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def delete_availability_zones(federation_id, zone_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/zones/{zone_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.delete(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Zone not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def create_artefact(federation_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/artefact") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = body.to_gsma_input() - - response = requests.post(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def get_artefact(federation_id, artefact_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/artefact/{artefact_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Artefact not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def delete_artefact(federation_id, artefact_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/artefact/{artefact_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.delete(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Artefact not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def create_profile(federation_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/application/onboarding") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = _gsma_payload(body) - - response = requests.post(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return { - "error": f"Federation not found: {response.text}", - "status_code": 404 - } - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def delete_profile(federation_id, app_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/application/onboarding/app/{app_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.delete(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def update_profile(federation_id, app_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/application/onboarding/app/{app_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = _gsma_payload(body) - - response = requests.patch(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def get_profile(federation_id, app_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/application/onboarding/app/{app_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def get_all_instances_deployment(federation_id, app_id, app_provider_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, - f"{federation_id}/application/lcm/app/{app_id}/appProvider/{app_provider_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application instances not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def get_instance_details_deployment(federation_id, app_id, app_instance_id, zone_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, - f"{federation_id}/application/lcm/app/{app_id}/instance/{app_instance_id}/zone/{zone_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.get(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application instance not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() - - -def install_app_deployment(federation_id, body, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, f"{federation_id}/application/lcm") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - json_payload = _gsma_payload(body) - - response = requests.post(partner_op_url, headers=headers, json=json_payload) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Federation not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - data_response = response.json() - - return data_response - - -def remove_app_deployment(federation_id, app_id, app_instance_id, zone_id, token, api_root): - - headers = {"Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Bearer {token}"} - - partner_op_url = check_url(api_root, - f"{federation_id}/application/lcm/app/{app_id}/instance/{app_instance_id}/zone/{zone_id}") - if not partner_op_url: - return {"error": f"Invalid URL: {partner_op_url}"} - - response = requests.delete(partner_op_url, headers=headers) - - # Handle different HTTP status codes - if response.status_code == 404: - return {"error": "Application instance not found", "status_code": 404} - elif response.status_code >= 400: - return {"error": f"HTTP {response.status_code}: {response.text}", "status_code": response.status_code} - - return response.json() diff --git a/src/clients/srm.py b/src/clients/srm.py deleted file mode 100644 index 499ab2f202770d4258c067e5580c4f7e2364cc29..0000000000000000000000000000000000000000 --- a/src/clients/srm.py +++ /dev/null @@ -1,84 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from configparser import ConfigParser -import os - -import requests - - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -HOST = CONFIG.get("service_resource_manager", "host") -PORT = int(CONFIG.get("service_resource_manager", "port")) -BASE_URL = f"http://{HOST}:{PORT}/srm/1.0.0/internal/fm" - - -def _request(method, path, json_payload=None): - return requests.request(method, f"{BASE_URL}{path}", json=json_payload, timeout=30) - - -def get_list_zones(): - response = _request("GET", "/zones/list") - return response.json() - - -def get_zones(): - response = _request("GET", "/zones") - return response.json() - - -def get_zone_by_zone_id(zone_id): - response = _request("GET", f"/zones/{zone_id}") - if response.status_code == 404: - return None - return response.json() - - -def onboarding_artefact(artefact_data): - return _request("POST", "/artefacts", artefact_data) - - -def delete_artefact(artefact_id): - return _request("DELETE", f"/artefacts/{artefact_id}") - - -def get_onboarding(app_id): - return _request("GET", f"/onboardings/{app_id}") - - -def post_onboarding(onboarding_data): - return _request("POST", "/onboardings", onboarding_data) - - -def update_onboarding(app_id, onboarding_data): - return _request("PATCH", f"/onboardings/{app_id}", onboarding_data) - - -def delete_onboarding(app_id): - return _request("DELETE", f"/onboardings/{app_id}") - - -def post_app_command(deployment_data): - return _request("POST", "/deployments", deployment_data) - - -def get_app_by_zone_app_instance_id(app_id, app_instance_id, zone_id): - return _request("GET", f"/deployments/{app_id}/instances/{app_instance_id}/zones/{zone_id}") - - -def delete_app(app_id, app_instance_id, zone_id): - return _request("DELETE", f"/deployments/{app_id}/instances/{app_instance_id}/zones/{zone_id}") diff --git a/src/clients/tf_sdk.py b/src/clients/tf_sdk.py deleted file mode 100644 index 856b2062eb33d8c064d27e2381555f488104ef89..0000000000000000000000000000000000000000 --- a/src/clients/tf_sdk.py +++ /dev/null @@ -1,255 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # -from configparser import ConfigParser -from sunrise6g_opensdk.common.sdk import Sdk as sdkclient -import logging -import os - -logger = logging.getLogger(__name__) -# TODO This is not mandatory for all TF SDK clients, adjust as needed -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -HOST = CONFIG.get("edge_cloud_platform", "host") -PORT = int(CONFIG.get("edge_cloud_platform", "port")) -CLIENT_NAME = CONFIG.get("edge_cloud_platform", "client_name") -FLAVOUR_ID = CONFIG.get("edge_cloud_platform", "flavour_id") - - -class EdgeCloudClient: - """ - EdgeCloud Client using sunrise6g_opensdk with _gsma functions for FM operations - """ - - _instance = None - - def __new__(cls): - if cls._instance is None: - cls._instance = super(EdgeCloudClient, cls).__new__(cls) - cls._instance._initialized = False - return cls._instance - - def __init__(self, host=HOST, port=PORT, client_name=CLIENT_NAME): - if self._initialized: - return - - self.host = host - self.port = port - self.base_url = f"http://{host}:{port}" - self.client_name = client_name - - client_specs = { - "edgecloud": { - "client_name": client_name, - "base_url": self.base_url, - "flavour_id": FLAVOUR_ID - } - } - - try: - clients = sdkclient.create_adapters_from(client_specs) - self.edgecloud_client = clients.get("edgecloud") - self._initialized = True - logger.info(f"EdgeCloud client initialized with base_url: {self.base_url}") - except Exception as e: - logger.error(f"Failed to initialize EdgeCloud client: {e}") - raise - - # Zone Management Functions - def get_list_zones(self): - """Get list of all available zones using GSMA-compliant API""" - try: - response = self.edgecloud_client.get_edge_cloud_zones_list_gsma() - return response.json() - except Exception as e: - logger.error(f"Error getting zones: {e}") - raise - - def get_zones(self): - """Get detailed info of all available zones using GSMA-compliant API""" - try: - response = self.edgecloud_client.get_edge_cloud_zones_gsma() - return response.json() - except Exception as e: - logger.error(f"Error getting zones: {e}") - raise - - def get_zone_by_zone_id(self, zone_id): - """Get zone details by zone ID using GSMA-compliant API""" - try: - response = self.edgecloud_client.get_edge_cloud_zone_details_gsma(zone_id) - return response.json() - except Exception as e: - logger.error(f"Error getting zone {zone_id}: {e}") - raise - - # Artefact Management Functions - def onboarding_artefact_gsma(self, artefact_data): - """Upload artefact using GSMA-compliant API""" - try: - return self.edgecloud_client.create_artefact_gsma(artefact_data) - except Exception as e: - logger.error(f"Error uploading artefact: {e}") - raise - - def delete_artefact_gsma(self, artefact_id): - """Delete artefact using GSMA-compliant API""" - try: - return self.edgecloud_client.delete_artefact_gsma(artefact_id) - except Exception as e: - logger.error(f"Error deleting artefact {artefact_id}: {e}") - raise - - # Application Onboarding Functions - def get_onboarding(self, app_id): - """Get application onboarding details using GSMA-compliant API""" - try: - return self.edgecloud_client.get_onboarded_app_gsma(app_id) - except Exception as e: - logger.error(f"Error getting onboarding for app {app_id}: {e}") - raise - - def post_onboarding(self, onboarding_data): - """Create application onboarding using GSMA-compliant API""" - try: - return self.edgecloud_client.onboard_app_gsma(onboarding_data) - except Exception as e: - logger.error(f"Error creating onboarding: {e}") - raise - - def update_onboarding(self, app_id, onboarding_data): - """Update application onboarding using GSMA-compliant API""" - try: - return self.edgecloud_client.patch_onboarded_app_gsma( - app_id, onboarding_data - ) - except Exception as e: - logger.error(f"Error updating onboarding for app {app_id}: {e}") - raise - - def delete_onboarding(self, app_id): - """Delete application onboarding using GSMA-compliant API""" - try: - return self.edgecloud_client.delete_onboarded_app_gsma(app_id) - except Exception as e: - logger.error(f"Error deleting onboarding for app {app_id}: {e}") - raise - - # Application Deployment Functions - def post_app_command(self, deployment_data): - """Deploy application using GSMA-compliant API""" - try: - return self.edgecloud_client.deploy_app_gsma(deployment_data) - except Exception as e: - logger.error(f"Error deploying app: {e}") - raise - - def get_app_by_zone_app_instance_id(self, app_id, app_instance_id, zone_id): - """Get application instance details using GSMA-compliant API""" - try: - return self.edgecloud_client.get_deployed_app_gsma( - app_id, app_instance_id, zone_id - ) - except Exception as e: - logger.error( - f"Error getting app instance {app_instance_id} in zone {zone_id}: {e}" - ) - raise - - def delete_app(self, app_id, app_instance_id, zone_id): - """Delete application instance using GSMA-compliant API""" - try: - return self.edgecloud_client.undeploy_app_gsma( - app_id, app_instance_id, zone_id - ) - except Exception as e: - logger.error(f"Error deleting app instance {app_instance_id}: {e}") - raise - - -# Global client instance -_client_instance = None - - -def get_client(): - """Get the singleton EdgeCloud client instance""" - global _client_instance - if _client_instance is None: - _client_instance = EdgeCloudClient() - return _client_instance - - -# Convenience functions for direct usage -def get_list_zones(): - """Get all available zones""" - return get_client().get_list_zones() - - -def get_zones(): - """Get all available zones""" - return get_client().get_zones() - - -def get_zone_by_zone_id(zone_id): - """Get zone details by zone ID""" - return get_client().get_zone_by_zone_id(zone_id) - - -def onboarding_artefact(artefact_data): - """Upload artefact""" - return get_client().onboarding_artefact_gsma(artefact_data) - - -def delete_artefact(artefact_id): - """Delete artefact""" - return get_client().delete_artefact_gsma(artefact_id) - - -def get_onboarding(app_id): - """Get application onboarding details""" - return get_client().get_onboarding(app_id) - - -def post_onboarding(onboarding_data): - """Create application onboarding""" - return get_client().post_onboarding(onboarding_data) - - -def update_onboarding(app_id, onboarding_data): - """Update application onboarding""" - return get_client().update_onboarding(app_id, onboarding_data) - - -def delete_onboarding(app_id): - """Delete application onboarding""" - return get_client().delete_onboarding(app_id) - - -def post_app_command(deployment_data): - """Deploy application""" - return get_client().post_app_command(deployment_data) - - -def get_app_by_zone_app_instance_id(app_id, app_instance_id, zone_id): - """Get application instance details""" - return get_client().get_app_by_zone_app_instance_id( - app_id, app_instance_id, zone_id - ) - - -def delete_app(app_id, app_instance_id, zone_id): - """Delete application instance""" - return get_client().delete_app(app_id, app_instance_id, zone_id) diff --git a/src/conf/config-fm-local.cfg b/src/conf/config-fm-local.cfg deleted file mode 100644 index 5e802f9aaf03ebb92d3848cc0905cee25ff2f688..0000000000000000000000000000000000000000 --- a/src/conf/config-fm-local.cfg +++ /dev/null @@ -1,55 +0,0 @@ -[keycloak] -client1_id = originating-op-1 -client1_secret = dd7vNwFqjNpYwaghlEwMbw10g0klWDHb -client2_id = originating-op-2 -client2_secret = 2mhznERfWclLDuVojY77Lp4Qd2r4e8Ms -scope = fed-mgmt -host = keycloak-local -port = 8080 -realm = federation - -[server] -host = 0.0.0.0 -port = 8989 -prefix = api -version = v1.0 -protocol = http - -[mongodb] -host = mongodb-local -port = 27017 - -[op_data] -partnerOPFederationId = Remote Operator -partnerOPCountryCode = ES -partnerOPMobileNetworkCode_MCC = 001 -partnerOPMobileNetworkCode_MNC = 01 -partnerOPFixedNetworkCode = 34 -platformCaps = homeRouting -edgeDiscoveryServiceEndPoint_port = -edgeDiscoveryServiceEndPoint_fqdn = discovery.operator1.com -edgeDiscoveryServiceEndPoint_ipv4Addresses = -edgeDiscoveryServiceEndPoint_ipv6Addresses = -lcmServiceEndPoint_port = 8989 -lcmServiceEndPoint_fqdn = -lcmServiceEndPoint_ipv4Addresses = 127.0.0.1 -lcmServiceEndPoint_ipv6Addresses = - -[service_resource_manager] -host = srm-local -port = 8080 - -[edge_cloud_platform] -host = lite2edge-local -port = 8080 -client_name = lite2edge -flavour_id = 67f3a0b0e3184a85952e174d - -[artefact_manager] -host = 192.168.123.237 -port = 30769 -enabled = false -dst_registry = -dst_username = -dst_password = -dst_token = diff --git a/src/conf/config-fm-remote.cfg b/src/conf/config-fm-remote.cfg deleted file mode 100644 index 0bb7b5a30fc56da8835997a709276cd2e44e69f6..0000000000000000000000000000000000000000 --- a/src/conf/config-fm-remote.cfg +++ /dev/null @@ -1,56 +0,0 @@ -[keycloak] -client1_id = originating-op-1 -client1_secret = dd7vNwFqjNpYwaghlEwMbw10g0klWDHb -client2_id = originating-op-2 -client2_secret = 2mhznERfWclLDuVojY77Lp4Qd2r4e8Ms -scope = fed-mgmt -host = keycloak-remote -port = 8080 -realm = federation - -[server] -host = 0.0.0.0 -port = 8989 -prefix = api -version = v1.0 -protocol = http - -[mongodb] -host = mongodb-remote -# host = 127.0.0.1 -port = 27017 - -[op_data] -partnerOPFederationId = Remote Operator -partnerOPCountryCode = ES -partnerOPMobileNetworkCode_MCC = 001 -partnerOPMobileNetworkCode_MNC = 01 -partnerOPFixedNetworkCode = 34 -platformCaps = homeRouting -edgeDiscoveryServiceEndPoint_port = -edgeDiscoveryServiceEndPoint_fqdn = discovery.operator1.com -edgeDiscoveryServiceEndPoint_ipv4Addresses = -edgeDiscoveryServiceEndPoint_ipv6Addresses = -lcmServiceEndPoint_port = 8989 -lcmServiceEndPoint_fqdn = -lcmServiceEndPoint_ipv4Addresses = 127.0.0.1 -lcmServiceEndPoint_ipv6Addresses = - -[service_resource_manager] -host = srm-remote -port = 8080 - -[edge_cloud_platform] -host = lite2edge-remote -port = 8080 -flavour_id = 694ad7d90e7025838c6af76b -client_name = lite2edge - -[artefact_manager] -enabled = false -host = 192.168.123.188 -port = 30080 -dst_registry = -dst_username = -dst_token = -dst_password = diff --git a/src/conf/config.cfg.sample b/src/conf/config.cfg.sample deleted file mode 100644 index c648a5b4a5962953f4fa7ad4c0c5d41bc16f4982..0000000000000000000000000000000000000000 --- a/src/conf/config.cfg.sample +++ /dev/null @@ -1,55 +0,0 @@ -[keycloak] -client1_id = originating-op-1 -client1_secret = dd7vNwFqjNpYwaghlEwMbw10g0klWDHb -client2_id = originating-op-2 -client2_secret = 2mhznERfWclLDuVojY77Lp4Qd2r4e8Ms -scope = fed-mgmt -host = keycloak -port = 8080 -realm = federation - -[server] -host = 127.0.0.1 -port = 8989 -prefix = api -version = v1.0 -protocol = http - -[mongodb] -host = mongodb -port = 27017 - -[op_data] -partnerOPFederationId = i2cat -partnerOPCountryCode = ES -partnerOPMobileNetworkCode_MCC = 001 -partnerOPMobileNetworkCode_MNC = 01 -partnerOPFixedNetworkCode = 34 -platformCaps = homeRouting -edgeDiscoveryServiceEndPoint_port = -edgeDiscoveryServiceEndPoint_fqdn = discovery.operator1.com -edgeDiscoveryServiceEndPoint_ipv4Addresses = -edgeDiscoveryServiceEndPoint_ipv6Addresses = -lcmServiceEndPoint_port = 8989 -lcmServiceEndPoint_fqdn = -lcmServiceEndPoint_ipv4Addresses = 127.0.0.1 -lcmServiceEndPoint_ipv6Addresses = - -[service_resource_manager] -host = 127.0.0.1 -port = 8080 - -[edge_cloud_platform] -host = 192.168.123.237 -port = 30769 -client_name = i2edge -flavour_id = 67f3a0b0e3184a85952e174d - -[artefact_manager] -host = 192.168.123.237 -port = 30769 -enabled = true -dst_registry = -dst_username = -dst_password = -dst_token = diff --git a/src/deploy/federation-manager.yaml b/src/deploy/federation-manager.yaml deleted file mode 100644 index 39b59e3a768dd96147a391358965cec0a15ec361..0000000000000000000000000000000000000000 --- a/src/deploy/federation-manager.yaml +++ /dev/null @@ -1,76 +0,0 @@ ---- -kind: Namespace -apiVersion: v1 -metadata: - name: federation-manager - labels: - name: federation-manager ---- -kind: Secret -apiVersion: v1 -metadata: - name: federation-manager-config - namespace: federation-manager -data: - config.cfg: >- - W2tleWNsb2FrXQpjbGllbnQxX2lkID0gb3JpZ2luYXRpbmctb3AtMQpjbGllbnQxX3NlY3JldCA9IGRkN3ZOd0Zxak5wWXdhZ2hsRXdNYncxMGcwa2xXREhiCmNsaWVudDJfaWQgPSBvcmlnaW5hdGluZy1vcC0yCmNsaWVudDJfc2VjcmV0ID0gMm1oem5FUmZXY2xMRHVWb2pZNzdMcDRRZDJyNGU4TXMKc2NvcGUgPSBmZWQtbWdtdApob3N0ID0ga2V5Y2xvYWsKcG9ydCA9IDgwODAKcmVhbG0gPSBmZWRlcmF0aW9uCgpbc2VydmVyXQpob3N0ID0gMTI3LjAuMC4xCnBvcnQgPSA4OTg5CnByZWZpeCA9IGFwaQp2ZXJzaW9uID0gdjEuMApwcm90b2NvbCA9IGh0dHAKClttb25nb2RiXQpob3N0ID0gbW9uZ29kYgpwb3J0ID0gMjcwMTcKCltvcF9kYXRhXQpwYXJ0bmVyT1BGZWRlcmF0aW9uSWQgPSBpMmNhdApwYXJ0bmVyT1BDb3VudHJ5Q29kZSA9IEVTCnBhcnRuZXJPUE1vYmlsZU5ldHdvcmtDb2RlX01DQyA9IDAwMQpwYXJ0bmVyT1BNb2JpbGVOZXR3b3JrQ29kZV9NTkMgPSAwMQpwYXJ0bmVyT1BGaXhlZE5ldHdvcmtDb2RlID0gMzQKcGxhdGZvcm1DYXBzID0gaG9tZVJvdXRpbmcKZWRnZURpc2NvdmVyeVNlcnZpY2VFbmRQb2ludF9wb3J0ID0KZWRnZURpc2NvdmVyeVNlcnZpY2VFbmRQb2ludF9mcWRuID0gZGlzY292ZXJ5Lm9wZXJhdG9yMS5jb20KZWRnZURpc2NvdmVyeVNlcnZpY2VFbmRQb2ludF9pcHY0QWRkcmVzc2VzID0KZWRnZURpc2NvdmVyeVNlcnZpY2VFbmRQb2ludF9pcHY2QWRkcmVzc2VzID0KbGNtU2VydmljZUVuZFBvaW50X3BvcnQgPSA4OTg5CmxjbVNlcnZpY2VFbmRQb2ludF9mcWRuID0KbGNtU2VydmljZUVuZFBvaW50X2lwdjRBZGRyZXNzZXMgPSAxMjcuMC4wLjEKbGNtU2VydmljZUVuZFBvaW50X2lwdjZBZGRyZXNzZXMgPQoKW2VkZ2VfY2xvdWRfcGxhdGZvcm1dCmhvc3QgPSAxOTIuMTY4LjEyMy40OApwb3J0ID0gMzA3NjkKY2xpZW50X25hbWUgPSBpMmVkZ2UKZmxhdm91cl9pZCA9IDY3ZjNhMGIwZTMxODRhODU5NTJlMTc0ZAoKW2FydGVmYWN0X21hbmFnZXJdCmhvc3QgPSAxOTIuMTY4LjEyMy4yMzcKcG9ydCA9IDMwNzY5CmVuYWJsZWQgPSBmYWxzZQpkc3RfcmVnaXN0cnkgPQpkc3RfdXNlcm5hbWUgPQpkc3RfcGFzc3dvcmQgPQpkc3RfdG9rZW4gPQo= -type: Opaque ---- -kind: Deployment -apiVersion: apps/v1 -metadata: - labels: - app: federation-manager - name: federation-manager - namespace: federation-manager -spec: - replicas: 1 - selector: - matchLabels: - app: federation-manager - template: - metadata: - labels: - app: federation-manager - spec: - containers: - - name: federation-manager - image: labs.etsi.org:5050/oop/code/federation-manager/federation-manager:temp-1d05bd0 - imagePullPolicy: Always - volumeMounts: - - name: config - readOnly: false - mountPath: /usr/app/src/conf/ - ports: - - containerPort: 8989 - protocol: TCP - resources: - requests: - cpu: "2" - memory: "4Gi" - limits: - cpu: "4" - memory: "6Gi" - volumes: - - name: config - secret: - secretName: federation-manager-config - defaultMode: 420 ---- -kind: Service -apiVersion: v1 -metadata: - labels: - app: federation-manager - name: federation-manager - namespace: federation-manager -spec: - type: NodePort - ports: - - name: http - port: 8989 - protocol: TCP - targetPort: 8989 - nodePort: 30989 - selector: - app: federation-manager diff --git a/src/deploy/keycloak.yaml b/src/deploy/keycloak.yaml deleted file mode 100644 index 9248af1bb6f07a70c9d956479653de03107dfddb..0000000000000000000000000000000000000000 --- a/src/deploy/keycloak.yaml +++ /dev/null @@ -1,92 +0,0 @@ ---- -kind: Namespace -apiVersion: v1 -metadata: - name: federation-manager - labels: - name: federation-manager ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: keycloak-config - namespace: federation-manager -data: - realm-import.json: | - { - "realm": "federation", - "enabled": true, - "clientScopes" : [ - { - "id" : "439d9c71-8a8a-469c-9280-058016000cc2", - "name" : "fed-mgmt", - "protocol": "openid-connect", - "description" : "fed-mgmt" - } - ], - "clients": [ - { - "clientId": "originating-op-1", - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "dd7vNwFqjNpYwaghlEwMbw10g0klWDHb", - "redirectUris": ["http://localhost:8080/*"], - "publicClient": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "defaultClientScopes": ["fed-mgmt"], - "webOrigins": ["*"] - } - ] - } ---- -kind: Deployment -apiVersion: apps/v1 -metadata: - name: keycloak - namespace: federation-manager -spec: - replicas: 1 - selector: - matchLabels: - app: keycloak - template: - metadata: - labels: - app: keycloak - spec: - containers: - - name: keycloak - image: quay.io/keycloak/keycloak:26.1.4 - ports: - - containerPort: 8080 - args: [ "start-dev", "--import-realm" ] - env: - - name: KC_BOOTSTRAP_ADMIN_USERNAME - value: admin - - name: KC_BOOTSTRAP_ADMIN_PASSWORD - value: admin - - name: KC_IMPORT - value: /opt/keycloak/data/import/realm-import.json - volumeMounts: - - name: realm-import - mountPath: /opt/keycloak/data/import/ - volumes: - - name: realm-import - configMap: - name: keycloak-config ---- -kind: Service -apiVersion: v1 -metadata: - name: keycloak - namespace: federation-manager -spec: - type: NodePort - ports: - - protocol: TCP - port: 8080 - targetPort: 8080 - nodePort: 30081 - selector: - app: keycloak diff --git a/src/deploy/mongo-db.yaml b/src/deploy/mongo-db.yaml deleted file mode 100644 index d41e786515ca93c0e52387e1fd9cc40f94455888..0000000000000000000000000000000000000000 --- a/src/deploy/mongo-db.yaml +++ /dev/null @@ -1,85 +0,0 @@ ---- -kind: Namespace -apiVersion: v1 -metadata: - name: federation-manager - labels: - name: federation-manager ---- -kind: PersistentVolume -apiVersion: v1 -metadata: - name: mongodb -spec: - capacity: - storage: 1Gi - hostPath: - path: /tmp/db - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: mongodb - namespace: federation-manager -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeName: mongodb ---- -kind: Deployment -apiVersion: apps/v1 -metadata: - name: mongodb - namespace: federation-manager -spec: - replicas: 1 - selector: - matchLabels: - app: mongodb - template: - metadata: - labels: - app: mongodb - spec: - volumes: - - name: storage - persistentVolumeClaim: - claimName: mongodb - containers: - - name: mongodb - image: 'mongo:7.0' - ports: - - containerPort: 27017 - protocol: TCP - env: - - name: MONGO_INITDB_DATABASE - value: federation-manager - - name: MONGODB_DATA_DIR - value: /data/db - - name: MONDODB_LOG_DIR - value: /dev/null - volumeMounts: - - name: storage - mountPath: /data/db - imagePullPolicy: IfNotPresent ---- -kind: Service -apiVersion: v1 -metadata: - name: mongodb - namespace: federation-manager -spec: - type: NodePort - ports: - - protocol: TCP - port: 27017 - targetPort: 27017 - nodePort: 30017 - selector: - app: mongodb diff --git a/src/encoder.py b/src/encoder.py deleted file mode 100644 index 36eee3a1782b80ba1a5eecf8a1c4c497c46d99f3..0000000000000000000000000000000000000000 --- a/src/encoder.py +++ /dev/null @@ -1,37 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - - -from connexion.apps.flask_app import FlaskJSONEncoder -import six - -from 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/src/init.py b/src/init.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/main.py b/src/main.py deleted file mode 100644 index 1f2645f1eabb3cb0758348362622ef1ad9daf8dc..0000000000000000000000000000000000000000 --- a/src/main.py +++ /dev/null @@ -1,76 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -""" -Federation Manager application -""" -import connexion -from flask import render_template -import encoder -import yaml -from flask_mongoengine import MongoEngine -from configparser import ConfigParser -import os - - -CONFIG = ConfigParser() -config_file = os.environ.get("FM_CONFIG_FILE", "conf/config.cfg") -CONFIG.read(config_file) -HOST = CONFIG.get("server", "host") -PORT = int(CONFIG.get("server", "port")) -MONGO_HOST = CONFIG.get("mongodb", "host") -MONGO_PORT = CONFIG.get("mongodb", "port") -KEYCLOAK_HOST = CONFIG.get("keycloak", "host") -KEYCLOAK_PORT = int(CONFIG.get("keycloak", "port")) -KEYCLOAK_REALM = CONFIG.get("keycloak", "realm") - - -app = connexion.App(__name__, specification_dir='./swagger/') -app.app.json_encoder = encoder.JSONEncoder -app.app.config['MONGODB_SETTINGS'] = { - 'host': 'mongodb://' + MONGO_HOST + ':' + MONGO_PORT + '/federation-manager' -} -DB = MongoEngine(app.app) - -# Load the swagger file and update the tokenUrl dynamically -with open("swagger/swagger.yaml", 'r') as f: - swagger_spec = yaml.safe_load(f) - -token_url = f"http://{KEYCLOAK_HOST}:{KEYCLOAK_PORT}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token" -swagger_spec['components']['securitySchemes']['oAuth2ClientCredentials']['flows']['clientCredentials']['tokenUrl'] = token_url - -# Update the static openapi.yaml file for the UI -try: - with open("static/openapi.yaml", "w") as f: - yaml.dump(swagger_spec, f) -except Exception as e: - print(f"Error updating static/openapi.yaml: {e}") - -app.add_api(swagger_spec, arguments={'title': 'Federation Management Service'}, pythonic_params=True) - - -@app.route("/", methods=["GET"]) -def documentation(): - """Endpoint to retrieve documentation""" - return render_template("swaggerui.html") - - -def main(): - app.run(host=HOST, port=PORT, threaded=True) - - -if __name__ == '__main__': - main() diff --git a/src/models/__init__.py b/src/models/__init__.py deleted file mode 100644 index 1891697831460fe42906567a14fc98856cbd9455..0000000000000000000000000000000000000000 --- a/src/models/__init__.py +++ /dev/null @@ -1,97 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -# flake8: noqa -from __future__ import absolute_import -# import models into model package -from models.app_app_id_body import AppAppIdBody -from models.app_component_specs import AppComponentSpecs -from models.app_component_specs_inner import AppComponentSpecsInner -from models.app_id_zone_forbid_body import AppIdZoneForbidBody -from models.app_identifier import AppIdentifier -from models.app_meta_data import AppMetaData -from models.app_provider_id import AppProviderId -from models.app_qo_s_profile import AppQoSProfile -from models.application_lcm_body import ApplicationLcmBody -from models.application_onboarding_body import ApplicationOnboardingBody -from models.artefact_id import ArtefactId -from models.authorization_token import AuthorizationToken -from models.cpu_arch_type import CPUArchType -from models.callback_credentials import CallbackCredentials -from models.command_line_params import CommandLineParams -from models.comp_env_params import CompEnvParams -from models.component_spec import ComponentSpec -from models.compute_resource_info import ComputeResourceInfo -from models.country_code import CountryCode -from models.deployment_config import DeploymentConfig -from models.federation_context_id import FederationContextId -from models.federation_context_id_artefact_body import FederationContextIdArtefactBody -from models.federation_context_id_files_body import FederationContextIdFilesBody -from models.federation_context_id_partner_body import FederationContextIdPartnerBody -from models.federation_context_idapplicationlcm_zone_info import FederationContextIdapplicationlcmZoneInfo -from models.federation_context_idapplicationlcmappapp_idapp_providerapp_provider_id_app_instance_info import FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo -from models.federation_context_idapplicationonboardingappapp_id_app_component_specs import FederationContextIdapplicationonboardingappappIdAppComponentSpecs -from models.federation_context_idapplicationonboardingappapp_id_app_upd_qo_s_profile import FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile -from models.federation_identifier import FederationIdentifier -from models.federation_request_data import FederationRequestData -from models.federation_response_data import FederationResponseData -from models.file_id import FileId -from models.fixed_network_ids import FixedNetworkIds -from models.flavour import Flavour -from models.flavour_id import FlavourId -from models.fqdn import Fqdn -from models.geo_location import GeoLocation -from models.gpu_info import GpuInfo -from models.huge_page import HugePage -from models.inline_response2001 import InlineResponse2001 -from models.inline_response2002 import InlineResponse2002 -from models.inline_response2005 import InlineResponse2005 -from models.inline_response2006 import InlineResponse2006 -from models.inline_response2007 import InlineResponse2007 -from models.inline_response2007_app_deployment_zones import InlineResponse2007AppDeploymentZones -from models.inline_response2008 import InlineResponse2008 -from models.inline_response2008_accesspoint_info import InlineResponse2008AccesspointInfo -from models.inline_response2009 import InlineResponse2009 -from models.inline_response202 import InlineResponse202 -from models.instance_identifier import InstanceIdentifier -from models.instance_state import InstanceState -from models.interface_details import InterfaceDetails -from models.invalid_param import InvalidParam -from models.ipv4_addr import Ipv4Addr -from models.ipv6_addr import Ipv6Addr -from models.mcc import Mcc -from models.mnc import Mnc -from models.mobile_network_ids import MobileNetworkIds -from models.os_type import OSType -from models.object_repo_location import ObjectRepoLocation -from models.persistent_volume_details import PersistentVolumeDetails -from models.port import Port -from models.problem_details import ProblemDetails -from models.service_endpoint import ServiceEndpoint -from models.uri import Uri -from models.vcpu import Vcpu -from models.version import Version -from models.virt_image_type import VirtImageType -from models.zone_details import ZoneDetails -from models.zone_identifier import ZoneIdentifier -from models.zone_registered_data import ZoneRegisteredData -from models.zone_registered_data_network_resources import ZoneRegisteredDataNetworkResources -from models.zone_registered_data_zone_service_level_objs_info import ZoneRegisteredDataZoneServiceLevelObjsInfo -from models.zone_registered_data_zone_service_level_objs_info_jitter_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges -from models.zone_registered_data_zone_service_level_objs_info_latency_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges -from models.zone_registered_data_zone_service_level_objs_info_throughput_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges -from models.zone_registration_request_data import ZoneRegistrationRequestData -from models.zone_registration_response_data import ZoneRegistrationResponseData diff --git a/src/models/app_app_id_body.py b/src/models/app_app_id_body.py deleted file mode 100644 index a4955d327cb7b642c337a18dad399ce6fec18734..0000000000000000000000000000000000000000 --- a/src/models/app_app_id_body.py +++ /dev/null @@ -1,118 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_component_specs import AppComponentSpecs # noqa: F401,E501 -from models.federation_context_idapplicationonboardingappapp_id_app_upd_qo_s_profile import FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile # noqa: F401,E501 -import util - - -class AppAppIdBody(Model): - def __init__(self, app_upd_qo_s_profile: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile=None, app_component_specs: AppComponentSpecs=None): # noqa: E501 - """AppAppIdBody - a model defined in Swagger - - :param app_upd_qo_s_profile: The app_upd_qo_s_profile of this AppAppIdBody. # noqa: E501 - :type app_upd_qo_s_profile: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile - :param app_component_specs: The app_component_specs of this AppAppIdBody. # noqa: E501 - :type app_component_specs: AppComponentSpecs - """ - self.swagger_types = { - 'app_upd_qo_s_profile': FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile, - 'app_component_specs': AppComponentSpecs - } - - self.attribute_map = { - 'app_upd_qo_s_profile': 'appUpdQoSProfile', - 'app_component_specs': 'appComponentSpecs' - } - self._app_upd_qo_s_profile = app_upd_qo_s_profile - self._app_component_specs = app_component_specs - - @classmethod - def from_dict(cls, dikt) -> 'AppAppIdBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The app_appId_body of this AppAppIdBody. # noqa: E501 - :rtype: AppAppIdBody - """ - return util.deserialize_model(dikt, cls) - - @property - def app_upd_qo_s_profile(self) -> FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile: - """Gets the app_upd_qo_s_profile of this AppAppIdBody. - - - :return: The app_upd_qo_s_profile of this AppAppIdBody. - :rtype: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile - """ - return self._app_upd_qo_s_profile - - @app_upd_qo_s_profile.setter - def app_upd_qo_s_profile(self, app_upd_qo_s_profile: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile): - """Sets the app_upd_qo_s_profile of this AppAppIdBody. - - - :param app_upd_qo_s_profile: The app_upd_qo_s_profile of this AppAppIdBody. - :type app_upd_qo_s_profile: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile - """ - - self._app_upd_qo_s_profile = app_upd_qo_s_profile - - @property - def app_component_specs(self) -> AppComponentSpecs: - """Gets the app_component_specs of this AppAppIdBody. - - An application may consist of more than one component. Each component is associated with a descriptor and may exposes its services externally or internally. App providers are required to provide details about all these components, their associated descriptors and their DNS names. # noqa: E501 - - :return: The app_component_specs of this AppAppIdBody. - :rtype: AppComponentSpecs - """ - return self._app_component_specs - - @app_component_specs.setter - def app_component_specs(self, app_component_specs: AppComponentSpecs): - """Sets the app_component_specs of this AppAppIdBody. - - An application may consist of more than one component. Each component is associated with a descriptor and may exposes its services externally or internally. App providers are required to provide details about all these components, their associated descriptors and their DNS names. # noqa: E501 - - :param app_component_specs: The app_component_specs of this AppAppIdBody. - :type app_component_specs: AppComponentSpecs - """ - - self._app_component_specs = app_component_specs - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/app_component_specs.py b/src/models/app_component_specs.py deleted file mode 100644 index c955473af82ef9723dc66253bad74c11ede0a209..0000000000000000000000000000000000000000 --- a/src/models/app_component_specs.py +++ /dev/null @@ -1,54 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_component_specs_inner import AppComponentSpecsInner # noqa: F401,E501 -import util - - -class AppComponentSpecs(Model): - def __init__(self): # noqa: E501 - """AppComponentSpecs - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'AppComponentSpecs': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppComponentSpecs of this AppComponentSpecs. # noqa: E501 - :rtype: AppComponentSpecs - """ - return util.deserialize_model(dikt, cls) - - def to_gsma_input(self): - return { - sdk_key: getattr(self, attr) - for attr, sdk_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/app_component_specs_inner.py b/src/models/app_component_specs_inner.py deleted file mode 100644 index c3e63e2f3a27850532ccc4d9072cb2797b77619c..0000000000000000000000000000000000000000 --- a/src/models/app_component_specs_inner.py +++ /dev/null @@ -1,167 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.artefact_id import ArtefactId # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class AppComponentSpecsInner(Model): - def __init__(self, service_name_nb: str=None, service_name_ew: str=None, component_name: str=None, artefact_id: ArtefactId=None): # noqa: E501 - """AppComponentSpecsInner - a model defined in Swagger - - :param service_name_nb: The service_name_nb of this AppComponentSpecsInner. # noqa: E501 - :type service_name_nb: str - :param service_name_ew: The service_name_ew of this AppComponentSpecsInner. # noqa: E501 - :type service_name_ew: str - :param component_name: The component_name of this AppComponentSpecsInner. # noqa: E501 - :type component_name: str - :param artefact_id: The artefact_id of this AppComponentSpecsInner. # noqa: E501 - :type artefact_id: ArtefactId - """ - self.swagger_types = { - 'service_name_nb': str, - 'service_name_ew': str, - 'component_name': str, - 'artefact_id': ArtefactId - } - - self.attribute_map = { - 'service_name_nb': 'serviceNameNB', - 'service_name_ew': 'serviceNameEW', - 'component_name': 'componentName', - 'artefact_id': 'artefactId' - } - self._service_name_nb = service_name_nb - self._service_name_ew = service_name_ew - self._component_name = component_name - self._artefact_id = artefact_id - - @classmethod - def from_dict(cls, dikt) -> 'AppComponentSpecsInner': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppComponentSpecs_inner of this AppComponentSpecsInner. # noqa: E501 - :rtype: AppComponentSpecsInner - """ - return util.deserialize_model(dikt, cls) - - @property - def service_name_nb(self) -> str: - """Gets the service_name_nb of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed over NBI. Access via serviceNameNB is restricted on specific ports. Platform shall expose component access externally via this DNS name # noqa: E501 - - :return: The service_name_nb of this AppComponentSpecsInner. - :rtype: str - """ - return self._service_name_nb - - @service_name_nb.setter - def service_name_nb(self, service_name_nb: str): - """Sets the service_name_nb of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed over NBI. Access via serviceNameNB is restricted on specific ports. Platform shall expose component access externally via this DNS name # noqa: E501 - - :param service_name_nb: The service_name_nb of this AppComponentSpecsInner. - :type service_name_nb: str - """ - - self._service_name_nb = service_name_nb - - @property - def service_name_ew(self) -> str: - """Gets the service_name_ew of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed via peer components. Access via serviceNameEW is open on all ports. Platform shall not expose serviceNameEW externally outside edge. # noqa: E501 - - :return: The service_name_ew of this AppComponentSpecsInner. - :rtype: str - """ - return self._service_name_ew - - @service_name_ew.setter - def service_name_ew(self, service_name_ew: str): - """Sets the service_name_ew of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed via peer components. Access via serviceNameEW is open on all ports. Platform shall not expose serviceNameEW externally outside edge. # noqa: E501 - - :param service_name_ew: The service_name_ew of this AppComponentSpecsInner. - :type service_name_ew: str - """ - - self._service_name_ew = service_name_ew - - @property - def component_name(self) -> str: - """Gets the component_name of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :return: The component_name of this AppComponentSpecsInner. - :rtype: str - """ - return self._component_name - - @component_name.setter - def component_name(self, component_name: str): - """Sets the component_name of this AppComponentSpecsInner. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :param component_name: The component_name of this AppComponentSpecsInner. - :type component_name: str - """ - - self._component_name = component_name - - @property - def artefact_id(self) -> ArtefactId: - """Gets the artefact_id of this AppComponentSpecsInner. - - - :return: The artefact_id of this AppComponentSpecsInner. - :rtype: ArtefactId - """ - return self._artefact_id - - @artefact_id.setter - def artefact_id(self, artefact_id: ArtefactId): - """Sets the artefact_id of this AppComponentSpecsInner. - - - :param artefact_id: The artefact_id of this AppComponentSpecsInner. - :type artefact_id: ArtefactId - """ - if artefact_id is None: - raise ValueError("Invalid value for `artefact_id`, must not be `None`") # noqa: E501 - - self._artefact_id = artefact_id - - def to_gsma_input(self): - return { - sdk_key: getattr(self, attr) - for attr, sdk_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/app_id_zone_forbid_body.py b/src/models/app_id_zone_forbid_body.py deleted file mode 100644 index 1de918979c9792d30ba1ec3498ef961dd3f4d42e..0000000000000000000000000000000000000000 --- a/src/models/app_id_zone_forbid_body.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class AppIdZoneForbidBody(Model): - def __init__(self): # noqa: E501 - """AppIdZoneForbidBody - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'AppIdZoneForbidBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The appId_zoneForbid_body of this AppIdZoneForbidBody. # noqa: E501 - :rtype: AppIdZoneForbidBody - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/app_identifier.py b/src/models/app_identifier.py deleted file mode 100644 index cfbb014cf5805b1a34ca65afceb63c7becae7124..0000000000000000000000000000000000000000 --- a/src/models/app_identifier.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class AppIdentifier(Model): - def __init__(self): # noqa: E501 - """AppIdentifier - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'AppIdentifier': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppIdentifier of this AppIdentifier. # noqa: E501 - :rtype: AppIdentifier - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/app_meta_data.py b/src/models/app_meta_data.py deleted file mode 100644 index 6be610633b24264548e8b8ffeec5fb1423301c6d..0000000000000000000000000000000000000000 --- a/src/models/app_meta_data.py +++ /dev/null @@ -1,234 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import re # noqa: F401,E501 -import util - - -class AppMetaData(Model): - def __init__(self, app_name: str=None, version: str=None, app_description: str=None, mobility_support: bool=False, access_token: str=None, category: str=None): # noqa: E501 - """AppMetaData - a model defined in Swagger - - :param app_name: The app_name of this AppMetaData. # noqa: E501 - :type app_name: str - :param version: The version of this AppMetaData. # noqa: E501 - :type version: str - :param app_description: The app_description of this AppMetaData. # noqa: E501 - :type app_description: str - :param mobility_support: The mobility_support of this AppMetaData. # noqa: E501 - :type mobility_support: bool - :param access_token: The access_token of this AppMetaData. # noqa: E501 - :type access_token: str - :param category: The category of this AppMetaData. # noqa: E501 - :type category: str - """ - self.swagger_types = { - 'app_name': str, - 'version': str, - 'app_description': str, - 'mobility_support': bool, - 'access_token': str, - 'category': str - } - - self.attribute_map = { - 'app_name': 'appName', - 'version': 'version', - 'app_description': 'appDescription', - 'mobility_support': 'mobilitySupport', - 'access_token': 'accessToken', - 'category': 'category' - } - self._app_name = app_name - self._version = version - self._app_description = app_description - self._mobility_support = mobility_support - self._access_token = access_token - self._category = category - - @classmethod - def from_dict(cls, dikt) -> 'AppMetaData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppMetaData of this AppMetaData. # noqa: E501 - :rtype: AppMetaData - """ - return util.deserialize_model(dikt, cls) - - @property - def app_name(self) -> str: - """Gets the app_name of this AppMetaData. - - Name of the application. Application provider define a human readable name for the application # noqa: E501 - - :return: The app_name of this AppMetaData. - :rtype: str - """ - return self._app_name - - @app_name.setter - def app_name(self, app_name: str): - """Sets the app_name of this AppMetaData. - - Name of the application. Application provider define a human readable name for the application # noqa: E501 - - :param app_name: The app_name of this AppMetaData. - :type app_name: str - """ - if app_name is None: - raise ValueError("Invalid value for `app_name`, must not be `None`") # noqa: E501 - - self._app_name = app_name - - @property - def version(self) -> str: - """Gets the version of this AppMetaData. - - Version info of the application # noqa: E501 - - :return: The version of this AppMetaData. - :rtype: str - """ - return self._version - - @version.setter - def version(self, version: str): - """Sets the version of this AppMetaData. - - Version info of the application # noqa: E501 - - :param version: The version of this AppMetaData. - :type version: str - """ - if version is None: - raise ValueError("Invalid value for `version`, must not be `None`") # noqa: E501 - - self._version = version - - @property - def app_description(self) -> str: - """Gets the app_description of this AppMetaData. - - Brief application description provided by application provider # noqa: E501 - - :return: The app_description of this AppMetaData. - :rtype: str - """ - return self._app_description - - @app_description.setter - def app_description(self, app_description: str): - """Sets the app_description of this AppMetaData. - - Brief application description provided by application provider # noqa: E501 - - :param app_description: The app_description of this AppMetaData. - :type app_description: str - """ - - self._app_description = app_description - - @property - def mobility_support(self) -> bool: - """Gets the mobility_support of this AppMetaData. - - Indicates if an application is sensitive to user mobility and can be relocated. Default is “FALSE” # noqa: E501 - - :return: The mobility_support of this AppMetaData. - :rtype: bool - """ - return self._mobility_support - - @mobility_support.setter - def mobility_support(self, mobility_support: bool): - """Sets the mobility_support of this AppMetaData. - - Indicates if an application is sensitive to user mobility and can be relocated. Default is “FALSE” # noqa: E501 - - :param mobility_support: The mobility_support of this AppMetaData. - :type mobility_support: bool - """ - - self._mobility_support = mobility_support - - @property - def access_token(self) -> str: - """Gets the access_token of this AppMetaData. - - An application Access key, to be used with UNI interface to authorize UCs Access to a given application # noqa: E501 - - :return: The access_token of this AppMetaData. - :rtype: str - """ - return self._access_token - - @access_token.setter - def access_token(self, access_token: str): - """Sets the access_token of this AppMetaData. - - An application Access key, to be used with UNI interface to authorize UCs Access to a given application # noqa: E501 - - :param access_token: The access_token of this AppMetaData. - :type access_token: str - """ - if access_token is None: - raise ValueError("Invalid value for `access_token`, must not be `None`") # noqa: E501 - - self._access_token = access_token - - @property - def category(self) -> str: - """Gets the category of this AppMetaData. - - Possible categorization of the application # noqa: E501 - - :return: The category of this AppMetaData. - :rtype: str - """ - return self._category - - @category.setter - def category(self, category: str): - """Sets the category of this AppMetaData. - - Possible categorization of the application # noqa: E501 - - :param category: The category of this AppMetaData. - :type category: str - """ - allowed_values = ["IOT", "HEALTH_CARE", "GAMING", "VIRTUAL_REALITY", "SOCIALIZING", "SURVEILLANCE", "ENTERTAINMENT", "CONNECTIVITY", "PRODUCTIVITY", "SECURITY", "INDUSTRIAL", "EDUCATION", "OTHERS"] # noqa: E501 - if category and category not in allowed_values: - raise ValueError( - "Invalid value for `category` ({0}), must be one of {1}" - .format(category, allowed_values) - ) - - self._category = category - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/app_provider_id.py b/src/models/app_provider_id.py deleted file mode 100644 index d57bf62461c06ff0b196d59d061b5dbe8c1cbee5..0000000000000000000000000000000000000000 --- a/src/models/app_provider_id.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class AppProviderId(Model): - def __init__(self): # noqa: E501 - """AppProviderId - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'AppProviderId': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppProviderId of this AppProviderId. # noqa: E501 - :rtype: AppProviderId - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/app_qo_s_profile.py b/src/models/app_qo_s_profile.py deleted file mode 100644 index 0e006d3d40595b2fbee7f6c8a0c4f31f3aecb354..0000000000000000000000000000000000000000 --- a/src/models/app_qo_s_profile.py +++ /dev/null @@ -1,205 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class AppQoSProfile(Model): - def __init__(self, latency_constraints: str=None, bandwidth_required: int=None, multi_user_clients: str='APP_TYPE_SINGLE_USER', no_of_users_per_app_inst: int=1, app_provisioning: bool=True): # noqa: E501 - """AppQoSProfile - a model defined in Swagger - - :param latency_constraints: The latency_constraints of this AppQoSProfile. # noqa: E501 - :type latency_constraints: str - :param bandwidth_required: The bandwidth_required of this AppQoSProfile. # noqa: E501 - :type bandwidth_required: int - :param multi_user_clients: The multi_user_clients of this AppQoSProfile. # noqa: E501 - :type multi_user_clients: str - :param no_of_users_per_app_inst: The no_of_users_per_app_inst of this AppQoSProfile. # noqa: E501 - :type no_of_users_per_app_inst: int - :param app_provisioning: The app_provisioning of this AppQoSProfile. # noqa: E501 - :type app_provisioning: bool - """ - self.swagger_types = { - 'latency_constraints': str, - 'bandwidth_required': int, - 'multi_user_clients': str, - 'no_of_users_per_app_inst': int, - 'app_provisioning': bool - } - - self.attribute_map = { - 'latency_constraints': 'latencyConstraints', - 'bandwidth_required': 'bandwidthRequired', - 'multi_user_clients': 'multiUserClients', - 'no_of_users_per_app_inst': 'noOfUsersPerAppInst', - 'app_provisioning': 'appProvisioning' - } - self._latency_constraints = latency_constraints - self._bandwidth_required = bandwidth_required - self._multi_user_clients = multi_user_clients - self._no_of_users_per_app_inst = no_of_users_per_app_inst - self._app_provisioning = app_provisioning - - @classmethod - def from_dict(cls, dikt) -> 'AppQoSProfile': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AppQoSProfile of this AppQoSProfile. # noqa: E501 - :rtype: AppQoSProfile - """ - return util.deserialize_model(dikt, cls) - - @property - def latency_constraints(self) -> str: - """Gets the latency_constraints of this AppQoSProfile. - - Latency requirements for the application. Allowed values (non-standardized) are none, low and ultra-low. Ultra-Low may corresponds to range 15 - 30 msec, Low correspond to range 30 - 50 msec. None means 51 and above # noqa: E501 - - :return: The latency_constraints of this AppQoSProfile. - :rtype: str - """ - return self._latency_constraints - - @latency_constraints.setter - def latency_constraints(self, latency_constraints: str): - """Sets the latency_constraints of this AppQoSProfile. - - Latency requirements for the application. Allowed values (non-standardized) are none, low and ultra-low. Ultra-Low may corresponds to range 15 - 30 msec, Low correspond to range 30 - 50 msec. None means 51 and above # noqa: E501 - - :param latency_constraints: The latency_constraints of this AppQoSProfile. - :type latency_constraints: str - """ - allowed_values = ["NONE", "LOW", "ULTRALOW"] # noqa: E501 - if latency_constraints not in allowed_values: - raise ValueError( - "Invalid value for `latency_constraints` ({0}), must be one of {1}" - .format(latency_constraints, allowed_values) - ) - - self._latency_constraints = latency_constraints - - @property - def bandwidth_required(self) -> int: - """Gets the bandwidth_required of this AppQoSProfile. - - Data transfer bandwidth requirement (minimum limit) for the application. It should in Mbits/sec # noqa: E501 - - :return: The bandwidth_required of this AppQoSProfile. - :rtype: int - """ - return self._bandwidth_required - - @bandwidth_required.setter - def bandwidth_required(self, bandwidth_required: int): - """Sets the bandwidth_required of this AppQoSProfile. - - Data transfer bandwidth requirement (minimum limit) for the application. It should in Mbits/sec # noqa: E501 - - :param bandwidth_required: The bandwidth_required of this AppQoSProfile. - :type bandwidth_required: int - """ - - self._bandwidth_required = bandwidth_required - - @property - def multi_user_clients(self) -> str: - """Gets the multi_user_clients of this AppQoSProfile. - - Single user type application are designed to serve just one client. Multi user type application is designed to serve multiple clients # noqa: E501 - - :return: The multi_user_clients of this AppQoSProfile. - :rtype: str - """ - return self._multi_user_clients - - @multi_user_clients.setter - def multi_user_clients(self, multi_user_clients: str): - """Sets the multi_user_clients of this AppQoSProfile. - - Single user type application are designed to serve just one client. Multi user type application is designed to serve multiple clients # noqa: E501 - - :param multi_user_clients: The multi_user_clients of this AppQoSProfile. - :type multi_user_clients: str - """ - allowed_values = ["APP_TYPE_SINGLE_USER", "APP_TYPE_MULTI_USER"] # noqa: E501 - if multi_user_clients not in allowed_values: - raise ValueError( - "Invalid value for `multi_user_clients` ({0}), must be one of {1}" - .format(multi_user_clients, allowed_values) - ) - - self._multi_user_clients = multi_user_clients - - @property - def no_of_users_per_app_inst(self) -> int: - """Gets the no_of_users_per_app_inst of this AppQoSProfile. - - Maximum no of clients that can connect to an instance of this application. This parameter is relevant only for application of type multi user # noqa: E501 - - :return: The no_of_users_per_app_inst of this AppQoSProfile. - :rtype: int - """ - return self._no_of_users_per_app_inst - - @no_of_users_per_app_inst.setter - def no_of_users_per_app_inst(self, no_of_users_per_app_inst: int): - """Sets the no_of_users_per_app_inst of this AppQoSProfile. - - Maximum no of clients that can connect to an instance of this application. This parameter is relevant only for application of type multi user # noqa: E501 - - :param no_of_users_per_app_inst: The no_of_users_per_app_inst of this AppQoSProfile. - :type no_of_users_per_app_inst: int - """ - - self._no_of_users_per_app_inst = no_of_users_per_app_inst - - @property - def app_provisioning(self) -> bool: - """Gets the app_provisioning of this AppQoSProfile. - - Define if application can be instantiated or not # noqa: E501 - - :return: The app_provisioning of this AppQoSProfile. - :rtype: bool - """ - return self._app_provisioning - - @app_provisioning.setter - def app_provisioning(self, app_provisioning: bool): - """Sets the app_provisioning of this AppQoSProfile. - - Define if application can be instantiated or not # noqa: E501 - - :param app_provisioning: The app_provisioning of this AppQoSProfile. - :type app_provisioning: bool - """ - - self._app_provisioning = app_provisioning - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/application_lcm_body.py b/src/models/application_lcm_body.py deleted file mode 100644 index e8cb42fc2f98002740ea56d1f37092f6178e91c0..0000000000000000000000000000000000000000 --- a/src/models/application_lcm_body.py +++ /dev/null @@ -1,209 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_identifier import AppIdentifier # noqa: F401,E501 -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.federation_context_idapplicationlcm_zone_info import FederationContextIdapplicationlcmZoneInfo # noqa: F401,E501 -from models.uri import Uri # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ApplicationLcmBody(Model): - def __init__(self, app_id: AppIdentifier=None, app_version: str=None, app_provider_id: AppProviderId=None, zone_info: FederationContextIdapplicationlcmZoneInfo=None, app_inst_callback_link: Uri=None): # noqa: E501 - """ApplicationLcmBody - a model defined in Swagger - - :param app_id: The app_id of this ApplicationLcmBody. # noqa: E501 - :type app_id: AppIdentifier - :param app_version: The app_version of this ApplicationLcmBody. # noqa: E501 - :type app_version: str - :param app_provider_id: The app_provider_id of this ApplicationLcmBody. # noqa: E501 - :type app_provider_id: AppProviderId - :param zone_info: The zone_info of this ApplicationLcmBody. # noqa: E501 - :type zone_info: FederationContextIdapplicationlcmZoneInfo - :param app_inst_callback_link: The app_inst_callback_link of this ApplicationLcmBody. # noqa: E501 - :type app_inst_callback_link: Uri - """ - self.swagger_types = { - 'app_id': AppIdentifier, - 'app_version': str, - 'app_provider_id': AppProviderId, - 'zone_info': FederationContextIdapplicationlcmZoneInfo, - 'app_inst_callback_link': Uri - } - - self.attribute_map = { - 'app_id': 'appId', - 'app_version': 'appVersion', - 'app_provider_id': 'appProviderId', - 'zone_info': 'zoneInfo', - 'app_inst_callback_link': 'appInstCallbackLink' - } - self._app_id = app_id - self._app_version = app_version - self._app_provider_id = app_provider_id - self._zone_info = zone_info - self._app_inst_callback_link = app_inst_callback_link - - @classmethod - def from_dict(cls, dikt) -> 'ApplicationLcmBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The application_lcm_body of this ApplicationLcmBody. # noqa: E501 - :rtype: ApplicationLcmBody - """ - return util.deserialize_model(dikt, cls) - - @property - def app_id(self) -> AppIdentifier: - """Gets the app_id of this ApplicationLcmBody. - - - :return: The app_id of this ApplicationLcmBody. - :rtype: AppIdentifier - """ - return self._app_id - - @app_id.setter - def app_id(self, app_id: AppIdentifier): - """Sets the app_id of this ApplicationLcmBody. - - - :param app_id: The app_id of this ApplicationLcmBody. - :type app_id: AppIdentifier - """ - if app_id is None: - raise ValueError("Invalid value for `app_id`, must not be `None`") # noqa: E501 - - self._app_id = app_id - - @property - def app_version(self) -> str: - """Gets the app_version of this ApplicationLcmBody. - - Version info of the application # noqa: E501 - - :return: The app_version of this ApplicationLcmBody. - :rtype: str - """ - return self._app_version - - @app_version.setter - def app_version(self, app_version: str): - """Sets the app_version of this ApplicationLcmBody. - - Version info of the application # noqa: E501 - - :param app_version: The app_version of this ApplicationLcmBody. - :type app_version: str - """ - if app_version is None: - raise ValueError("Invalid value for `app_version`, must not be `None`") # noqa: E501 - - self._app_version = app_version - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this ApplicationLcmBody. - - - :return: The app_provider_id of this ApplicationLcmBody. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this ApplicationLcmBody. - - - :param app_provider_id: The app_provider_id of this ApplicationLcmBody. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def zone_info(self) -> FederationContextIdapplicationlcmZoneInfo: - """Gets the zone_info of this ApplicationLcmBody. - - - :return: The zone_info of this ApplicationLcmBody. - :rtype: FederationContextIdapplicationlcmZoneInfo - """ - return self._zone_info - - @zone_info.setter - def zone_info(self, zone_info: FederationContextIdapplicationlcmZoneInfo): - """Sets the zone_info of this ApplicationLcmBody. - - - :param zone_info: The zone_info of this ApplicationLcmBody. - :type zone_info: FederationContextIdapplicationlcmZoneInfo - """ - if zone_info is None: - raise ValueError("Invalid value for `zone_info`, must not be `None`") # noqa: E501 - - self._zone_info = zone_info - - @property - def app_inst_callback_link(self) -> Uri: - """Gets the app_inst_callback_link of this ApplicationLcmBody. - - - :return: The app_inst_callback_link of this ApplicationLcmBody. - :rtype: Uri - """ - return self._app_inst_callback_link - - @app_inst_callback_link.setter - def app_inst_callback_link(self, app_inst_callback_link: Uri): - """Sets the app_inst_callback_link of this ApplicationLcmBody. - - - :param app_inst_callback_link: The app_inst_callback_link of this ApplicationLcmBody. - :type app_inst_callback_link: Uri - """ - if app_inst_callback_link is None: - raise ValueError("Invalid value for `app_inst_callback_link`, must not be `None`") # noqa: E501 - - self._app_inst_callback_link = app_inst_callback_link - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/application_onboarding_body.py b/src/models/application_onboarding_body.py deleted file mode 100644 index f05c22f5b712595ff7a1d59ece5df474863d3271..0000000000000000000000000000000000000000 --- a/src/models/application_onboarding_body.py +++ /dev/null @@ -1,266 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_component_specs import AppComponentSpecs # noqa: F401,E501 -from models.app_identifier import AppIdentifier # noqa: F401,E501 -from models.app_meta_data import AppMetaData # noqa: F401,E501 -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.app_qo_s_profile import AppQoSProfile # noqa: F401,E501 -from models.uri import Uri # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ApplicationOnboardingBody(Model): - def __init__(self, app_id: AppIdentifier=None, app_provider_id: AppProviderId=None, app_deployment_zones: List[ZoneIdentifier]=None, app_meta_data: AppMetaData=None, app_qo_s_profile: AppQoSProfile=None, app_component_specs: AppComponentSpecs=None, app_status_callback_link: Uri=None): # noqa: E501 - """ApplicationOnboardingBody - a model defined in Swagger - - :param app_id: The app_id of this ApplicationOnboardingBody. # noqa: E501 - :type app_id: AppIdentifier - :param app_provider_id: The app_provider_id of this ApplicationOnboardingBody. # noqa: E501 - :type app_provider_id: AppProviderId - :param app_deployment_zones: The app_deployment_zones of this ApplicationOnboardingBody. # noqa: E501 - :type app_deployment_zones: List[ZoneIdentifier] - :param app_meta_data: The app_meta_data of this ApplicationOnboardingBody. # noqa: E501 - :type app_meta_data: AppMetaData - :param app_qo_s_profile: The app_qo_s_profile of this ApplicationOnboardingBody. # noqa: E501 - :type app_qo_s_profile: AppQoSProfile - :param app_component_specs: The app_component_specs of this ApplicationOnboardingBody. # noqa: E501 - :type app_component_specs: AppComponentSpecs - :param app_status_callback_link: The app_status_callback_link of this ApplicationOnboardingBody. # noqa: E501 - :type app_status_callback_link: Uri - """ - self.swagger_types = { - 'app_id': AppIdentifier, - 'app_provider_id': AppProviderId, - 'app_deployment_zones': List[ZoneIdentifier], - 'app_meta_data': AppMetaData, - 'app_qo_s_profile': AppQoSProfile, - 'app_component_specs': AppComponentSpecs, - 'app_status_callback_link': Uri - } - - self.attribute_map = { - 'app_id': 'appId', - 'app_provider_id': 'appProviderId', - 'app_deployment_zones': 'appDeploymentZones', - 'app_meta_data': 'appMetaData', - 'app_qo_s_profile': 'appQoSProfile', - 'app_component_specs': 'appComponentSpecs', - 'app_status_callback_link': 'appStatusCallbackLink' - } - self._app_id = app_id - self._app_provider_id = app_provider_id - self._app_deployment_zones = app_deployment_zones - self._app_meta_data = app_meta_data - self._app_qo_s_profile = app_qo_s_profile - self._app_component_specs = app_component_specs - self._app_status_callback_link = app_status_callback_link - - @classmethod - def from_dict(cls, dikt) -> 'ApplicationOnboardingBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The application_onboarding_body of this ApplicationOnboardingBody. # noqa: E501 - :rtype: ApplicationOnboardingBody - """ - return util.deserialize_model(dikt, cls) - - @property - def app_id(self) -> AppIdentifier: - """Gets the app_id of this ApplicationOnboardingBody. - - - :return: The app_id of this ApplicationOnboardingBody. - :rtype: AppIdentifier - """ - return self._app_id - - @app_id.setter - def app_id(self, app_id: AppIdentifier): - """Sets the app_id of this ApplicationOnboardingBody. - - - :param app_id: The app_id of this ApplicationOnboardingBody. - :type app_id: AppIdentifier - """ - if app_id is None: - raise ValueError("Invalid value for `app_id`, must not be `None`") # noqa: E501 - - self._app_id = app_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this ApplicationOnboardingBody. - - - :return: The app_provider_id of this ApplicationOnboardingBody. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this ApplicationOnboardingBody. - - - :param app_provider_id: The app_provider_id of this ApplicationOnboardingBody. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def app_deployment_zones(self) -> List[ZoneIdentifier]: - """Gets the app_deployment_zones of this ApplicationOnboardingBody. - - Details about partner OP zones where the application should be made available; This field when specified will instruct the OP to restrict application instantiation only on the listed zones. # noqa: E501 - - :return: The app_deployment_zones of this ApplicationOnboardingBody. - :rtype: List[ZoneIdentifier] - """ - return self._app_deployment_zones - - @app_deployment_zones.setter - def app_deployment_zones(self, app_deployment_zones: List[ZoneIdentifier]): - """Sets the app_deployment_zones of this ApplicationOnboardingBody. - - Details about partner OP zones where the application should be made available; This field when specified will instruct the OP to restrict application instantiation only on the listed zones. # noqa: E501 - - :param app_deployment_zones: The app_deployment_zones of this ApplicationOnboardingBody. - :type app_deployment_zones: List[ZoneIdentifier] - """ - - self._app_deployment_zones = app_deployment_zones - - @property - def app_meta_data(self) -> AppMetaData: - """Gets the app_meta_data of this ApplicationOnboardingBody. - - - :return: The app_meta_data of this ApplicationOnboardingBody. - :rtype: AppMetaData - """ - return self._app_meta_data - - @app_meta_data.setter - def app_meta_data(self, app_meta_data: AppMetaData): - """Sets the app_meta_data of this ApplicationOnboardingBody. - - - :param app_meta_data: The app_meta_data of this ApplicationOnboardingBody. - :type app_meta_data: AppMetaData - """ - if app_meta_data is None: - raise ValueError("Invalid value for `app_meta_data`, must not be `None`") # noqa: E501 - - self._app_meta_data = app_meta_data - - @property - def app_qo_s_profile(self) -> AppQoSProfile: - """Gets the app_qo_s_profile of this ApplicationOnboardingBody. - - - :return: The app_qo_s_profile of this ApplicationOnboardingBody. - :rtype: AppQoSProfile - """ - return self._app_qo_s_profile - - @app_qo_s_profile.setter - def app_qo_s_profile(self, app_qo_s_profile: AppQoSProfile): - """Sets the app_qo_s_profile of this ApplicationOnboardingBody. - - - :param app_qo_s_profile: The app_qo_s_profile of this ApplicationOnboardingBody. - :type app_qo_s_profile: AppQoSProfile - """ - if app_qo_s_profile is None: - raise ValueError("Invalid value for `app_qo_s_profile`, must not be `None`") # noqa: E501 - - self._app_qo_s_profile = app_qo_s_profile - - @property - def app_component_specs(self) -> AppComponentSpecs: - """Gets the app_component_specs of this ApplicationOnboardingBody. - - - :return: The app_component_specs of this ApplicationOnboardingBody. - :rtype: AppComponentSpecs - """ - return self._app_component_specs - - @app_component_specs.setter - def app_component_specs(self, app_component_specs: AppComponentSpecs): - """Sets the app_component_specs of this ApplicationOnboardingBody. - - - :param app_component_specs: The app_component_specs of this ApplicationOnboardingBody. - :type app_component_specs: AppComponentSpecs - """ - if app_component_specs is None: - raise ValueError("Invalid value for `app_component_specs`, must not be `None`") # noqa: E501 - - self._app_component_specs = app_component_specs - - @property - def app_status_callback_link(self) -> Uri: - """Gets the app_status_callback_link of this ApplicationOnboardingBody. - - - :return: The app_status_callback_link of this ApplicationOnboardingBody. - :rtype: Uri - """ - return self._app_status_callback_link - - @app_status_callback_link.setter - def app_status_callback_link(self, app_status_callback_link: Uri): - """Sets the app_status_callback_link of this ApplicationOnboardingBody. - - - :param app_status_callback_link: The app_status_callback_link of this ApplicationOnboardingBody. - :type app_status_callback_link: Uri - """ - if app_status_callback_link is None: - raise ValueError("Invalid value for `app_status_callback_link`, must not be `None`") # noqa: E501 - - self._app_status_callback_link = app_status_callback_link - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/artefact_id.py b/src/models/artefact_id.py deleted file mode 100644 index f546c65cb56aaf8ace98260981cb4af35c98593d..0000000000000000000000000000000000000000 --- a/src/models/artefact_id.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ArtefactId(Model): - def __init__(self): # noqa: E501 - """ArtefactId - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'ArtefactId': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ArtefactId of this ArtefactId. # noqa: E501 - :rtype: ArtefactId - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/authorization_token.py b/src/models/authorization_token.py deleted file mode 100644 index 31a5aacf75394935318349d484736a790be95ad2..0000000000000000000000000000000000000000 --- a/src/models/authorization_token.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class AuthorizationToken(Model): - def __init__(self): # noqa: E501 - """AuthorizationToken - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'AuthorizationToken': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The AuthorizationToken of this AuthorizationToken. # noqa: E501 - :rtype: AuthorizationToken - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/base_model_.py b/src/models/base_model_.py deleted file mode 100644 index 3ab8e0ccd3df18e8da094618cbce5977f2ad3c51..0000000000000000000000000000000000000000 --- a/src/models/base_model_.py +++ /dev/null @@ -1,84 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -import pprint -import six -import typing -import util - -T = typing.TypeVar('T') - - -class Model(object): - # swaggerTypes: The key is attribute name and the - # value is attribute type. - swagger_types = {} # DictField(required=False) - - # attributeMap: The key is attribute name and the - # value is json key in definition. - attribute_map = {} # DictField(required=False) - # meta = {"allow_inheritance": True, "collection": "sample"} - - @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/src/models/callback_credentials.py b/src/models/callback_credentials.py deleted file mode 100644 index 9ce0d649125e60476774c6e9f41aba6159814a88..0000000000000000000000000000000000000000 --- a/src/models/callback_credentials.py +++ /dev/null @@ -1,142 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.uri import Uri # noqa: F401,E501 -import util - - -class CallbackCredentials(Model): - def __init__(self, token_url: Uri=None, client_id: str=None, client_secret: str=None): # noqa: E501 - """CallbackCredentials - a model defined in Swagger - - :param token_url: The token_url of this CallbackCredentials. # noqa: E501 - :type token_url: Uri - :param client_id: The client_id of this CallbackCredentials. # noqa: E501 - :type client_id: str - :param client_secret: The client_secret of this CallbackCredentials. # noqa: E501 - :type client_secret: str - """ - self.swagger_types = { - 'token_url': Uri, - 'client_id': str, - 'client_secret': str - } - - self.attribute_map = { - 'token_url': 'tokenUrl', - 'client_id': 'clientId', - 'client_secret': 'clientSecret' - } - self._token_url = token_url - self._client_id = client_id - self._client_secret = client_secret - - @classmethod - def from_dict(cls, dikt) -> 'CallbackCredentials': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The CallbackCredentials of this CallbackCredentials. # noqa: E501 - :rtype: CallbackCredentials - """ - return util.deserialize_model(dikt, cls) - - @property - def token_url(self) -> Uri: - """Gets the token_url of this CallbackCredentials. - - - :return: The token_url of this CallbackCredentials. - :rtype: Uri - """ - return self._token_url - - @token_url.setter - def token_url(self, token_url: Uri): - """Sets the token_url of this CallbackCredentials. - - - :param token_url: The token_url of this CallbackCredentials. - :type token_url: Uri - """ - if token_url is None: - raise ValueError("Invalid value for `token_url`, must not be `None`") # noqa: E501 - - self._token_url = token_url - - @property - def client_id(self) -> str: - """Gets the client_id of this CallbackCredentials. - - Client id for oauth2 client credentials flow. # noqa: E501 - - :return: The client_id of this CallbackCredentials. - :rtype: str - """ - return self._client_id - - @client_id.setter - def client_id(self, client_id: str): - """Sets the client_id of this CallbackCredentials. - - Client id for oauth2 client credentials flow. # noqa: E501 - - :param client_id: The client_id of this CallbackCredentials. - :type client_id: str - """ - if client_id is None: - raise ValueError("Invalid value for `client_id`, must not be `None`") # noqa: E501 - - self._client_id = client_id - - @property - def client_secret(self) -> str: - """Gets the client_secret of this CallbackCredentials. - - Client secret for oauth2 client credentials flow. # noqa: E501 - - :return: The client_secret of this CallbackCredentials. - :rtype: str - """ - return self._client_secret - - @client_secret.setter - def client_secret(self, client_secret: str): - """Sets the client_secret of this CallbackCredentials. - - Client secret for oauth2 client credentials flow. # noqa: E501 - - :param client_secret: The client_secret of this CallbackCredentials. - :type client_secret: str - """ - if client_secret is None: - raise ValueError("Invalid value for `client_secret`, must not be `None`") # noqa: E501 - - self._client_secret = client_secret - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/command_line_params.py b/src/models/command_line_params.py deleted file mode 100644 index db80385c87648331f15e62b4bf5e3f3212b9693b..0000000000000000000000000000000000000000 --- a/src/models/command_line_params.py +++ /dev/null @@ -1,111 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class CommandLineParams(Model): - def __init__(self, command: List[str]=None, command_args: List[str]=None): # noqa: E501 - """CommandLineParams - a model defined in Swagger - - :param command: The command of this CommandLineParams. # noqa: E501 - :type command: List[str] - :param command_args: The command_args of this CommandLineParams. # noqa: E501 - :type command_args: List[str] - """ - self.swagger_types = { - 'command': List[str], - 'command_args': List[str] - } - - self.attribute_map = { - 'command': 'command', - 'command_args': 'commandArgs' - } - self._command = command - self._command_args = command_args - - @classmethod - def from_dict(cls, dikt) -> 'CommandLineParams': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The CommandLineParams of this CommandLineParams. # noqa: E501 - :rtype: CommandLineParams - """ - return util.deserialize_model(dikt, cls) - - @property - def command(self) -> List[str]: - """Gets the command of this CommandLineParams. - - List of commands that application should invoke when an instance is created. # noqa: E501 - - :return: The command of this CommandLineParams. - :rtype: List[str] - """ - return self._command - - @command.setter - def command(self, command: List[str]): - """Sets the command of this CommandLineParams. - - List of commands that application should invoke when an instance is created. # noqa: E501 - - :param command: The command of this CommandLineParams. - :type command: List[str] - """ - if command is None: - raise ValueError("Invalid value for `command`, must not be `None`") # noqa: E501 - - self._command = command - - @property - def command_args(self) -> List[str]: - """Gets the command_args of this CommandLineParams. - - List of arguments required by the command. # noqa: E501 - - :return: The command_args of this CommandLineParams. - :rtype: List[str] - """ - return self._command_args - - @command_args.setter - def command_args(self, command_args: List[str]): - """Sets the command_args of this CommandLineParams. - - List of arguments required by the command. # noqa: E501 - - :param command_args: The command_args of this CommandLineParams. - :type command_args: List[str] - """ - - self._command_args = command_args - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/comp_env_params.py b/src/models/comp_env_params.py deleted file mode 100644 index 8ccbc9fea7de92b9d750cc95c8aeafdfd524f77d..0000000000000000000000000000000000000000 --- a/src/models/comp_env_params.py +++ /dev/null @@ -1,172 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import re # noqa: F401,E501 -import util - - -class CompEnvParams(Model): - def __init__(self, env_var_name: str=None, env_value_type: str=None, env_var_value: str=None, env_var_src: str=None): # noqa: E501 - """CompEnvParams - a model defined in Swagger - - :param env_var_name: The env_var_name of this CompEnvParams. # noqa: E501 - :type env_var_name: str - :param env_value_type: The env_value_type of this CompEnvParams. # noqa: E501 - :type env_value_type: str - :param env_var_value: The env_var_value of this CompEnvParams. # noqa: E501 - :type env_var_value: str - :param env_var_src: The env_var_src of this CompEnvParams. # noqa: E501 - :type env_var_src: str - """ - self.swagger_types = { - 'env_var_name': str, - 'env_value_type': str, - 'env_var_value': str, - 'env_var_src': str - } - - self.attribute_map = { - 'env_var_name': 'envVarName', - 'env_value_type': 'envValueType', - 'env_var_value': 'envVarValue', - 'env_var_src': 'envVarSrc' - } - self._env_var_name = env_var_name - self._env_value_type = env_value_type - self._env_var_value = env_var_value - self._env_var_src = env_var_src - - @classmethod - def from_dict(cls, dikt) -> 'CompEnvParams': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The CompEnvParams of this CompEnvParams. # noqa: E501 - :rtype: CompEnvParams - """ - return util.deserialize_model(dikt, cls) - - @property - def env_var_name(self) -> str: - """Gets the env_var_name of this CompEnvParams. - - Name of environment variable # noqa: E501 - - :return: The env_var_name of this CompEnvParams. - :rtype: str - """ - return self._env_var_name - - @env_var_name.setter - def env_var_name(self, env_var_name: str): - """Sets the env_var_name of this CompEnvParams. - - Name of environment variable # noqa: E501 - - :param env_var_name: The env_var_name of this CompEnvParams. - :type env_var_name: str - """ - if env_var_name is None: - raise ValueError("Invalid value for `env_var_name`, must not be `None`") # noqa: E501 - - self._env_var_name = env_var_name - - @property - def env_value_type(self) -> str: - """Gets the env_value_type of this CompEnvParams. - - - :return: The env_value_type of this CompEnvParams. - :rtype: str - """ - return self._env_value_type - - @env_value_type.setter - def env_value_type(self, env_value_type: str): - """Sets the env_value_type of this CompEnvParams. - - - :param env_value_type: The env_value_type of this CompEnvParams. - :type env_value_type: str - """ - allowed_values = ["USER_DEFINED", "PLATFORM_DEFINED_DYNAMIC_PORT", "PLATFORM_DEFINED_DNS", "PLATFORM_DEFINED_IP"] # noqa: E501 - if env_value_type not in allowed_values: - raise ValueError( - "Invalid value for `env_value_type` ({0}), must be one of {1}" - .format(env_value_type, allowed_values) - ) - - self._env_value_type = env_value_type - - @property - def env_var_value(self) -> str: - """Gets the env_var_value of this CompEnvParams. - - Value to be assigned to environment variable # noqa: E501 - - :return: The env_var_value of this CompEnvParams. - :rtype: str - """ - return self._env_var_value - - @env_var_value.setter - def env_var_value(self, env_var_value: str): - """Sets the env_var_value of this CompEnvParams. - - Value to be assigned to environment variable # noqa: E501 - - :param env_var_value: The env_var_value of this CompEnvParams. - :type env_var_value: str - """ - - self._env_var_value = env_var_value - - @property - def env_var_src(self) -> str: - """Gets the env_var_src of this CompEnvParams. - - Full path of parameter from componentSpec that should be used to generate the environment value. Eg. networkResourceProfile[1]. interfaceId. # noqa: E501 - - :return: The env_var_src of this CompEnvParams. - :rtype: str - """ - return self._env_var_src - - @env_var_src.setter - def env_var_src(self, env_var_src: str): - """Sets the env_var_src of this CompEnvParams. - - Full path of parameter from componentSpec that should be used to generate the environment value. Eg. networkResourceProfile[1]. interfaceId. # noqa: E501 - - :param env_var_src: The env_var_src of this CompEnvParams. - :type env_var_src: str - """ - - self._env_var_src = env_var_src - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/component_spec.py b/src/models/component_spec.py deleted file mode 100644 index c5216f519a20d53415708772b92ac00d351640ca..0000000000000000000000000000000000000000 --- a/src/models/component_spec.py +++ /dev/null @@ -1,356 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.command_line_params import CommandLineParams # noqa: F401,E501 -from models.comp_env_params import CompEnvParams # noqa: F401,E501 -from models.compute_resource_info import ComputeResourceInfo # noqa: F401,E501 -from models.deployment_config import DeploymentConfig # noqa: F401,E501 -from models.file_id import FileId # noqa: F401,E501 -from models.interface_details import InterfaceDetails # noqa: F401,E501 -from models.persistent_volume_details import PersistentVolumeDetails # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ComponentSpec(Model): - def __init__(self, component_name: str=None, images: List[FileId]=None, num_of_instances: int=None, restart_policy: str=None, command_line_params: CommandLineParams=None, exposed_interfaces: List[InterfaceDetails]=None, compute_resource_profile: ComputeResourceInfo=None, comp_env_params: List[CompEnvParams]=None, deployment_config: DeploymentConfig=None, persistent_volumes: List[PersistentVolumeDetails]=None): # noqa: E501 - """ComponentSpec - a model defined in Swagger - - :param component_name: The component_name of this ComponentSpec. # noqa: E501 - :type component_name: str - :param images: The images of this ComponentSpec. # noqa: E501 - :type images: List[FileId] - :param num_of_instances: The num_of_instances of this ComponentSpec. # noqa: E501 - :type num_of_instances: int - :param restart_policy: The restart_policy of this ComponentSpec. # noqa: E501 - :type restart_policy: str - :param command_line_params: The command_line_params of this ComponentSpec. # noqa: E501 - :type command_line_params: CommandLineParams - :param exposed_interfaces: The exposed_interfaces of this ComponentSpec. # noqa: E501 - :type exposed_interfaces: List[InterfaceDetails] - :param compute_resource_profile: The compute_resource_profile of this ComponentSpec. # noqa: E501 - :type compute_resource_profile: ComputeResourceInfo - :param comp_env_params: The comp_env_params of this ComponentSpec. # noqa: E501 - :type comp_env_params: List[CompEnvParams] - :param deployment_config: The deployment_config of this ComponentSpec. # noqa: E501 - :type deployment_config: DeploymentConfig - :param persistent_volumes: The persistent_volumes of this ComponentSpec. # noqa: E501 - :type persistent_volumes: List[PersistentVolumeDetails] - """ - self.swagger_types = { - 'component_name': str, - 'images': List[FileId], - 'num_of_instances': int, - 'restart_policy': str, - 'command_line_params': CommandLineParams, - 'exposed_interfaces': List[InterfaceDetails], - 'compute_resource_profile': ComputeResourceInfo, - 'comp_env_params': List[CompEnvParams], - 'deployment_config': DeploymentConfig, - 'persistent_volumes': List[PersistentVolumeDetails] - } - - self.attribute_map = { - 'component_name': 'componentName', - 'images': 'images', - 'num_of_instances': 'numOfInstances', - 'restart_policy': 'restartPolicy', - 'command_line_params': 'commandLineParams', - 'exposed_interfaces': 'exposedInterfaces', - 'compute_resource_profile': 'computeResourceProfile', - 'comp_env_params': 'compEnvParams', - 'deployment_config': 'deploymentConfig', - 'persistent_volumes': 'persistentVolumes' - } - self._component_name = component_name - self._images = images - self._num_of_instances = num_of_instances - self._restart_policy = restart_policy - self._command_line_params = command_line_params - self._exposed_interfaces = exposed_interfaces - self._compute_resource_profile = compute_resource_profile - self._comp_env_params = comp_env_params - self._deployment_config = deployment_config - self._persistent_volumes = persistent_volumes - - @classmethod - def from_dict(cls, dikt) -> 'ComponentSpec': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ComponentSpec of this ComponentSpec. # noqa: E501 - :rtype: ComponentSpec - """ - return util.deserialize_model(dikt, cls) - - @property - def component_name(self) -> str: - """Gets the component_name of this ComponentSpec. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :return: The component_name of this ComponentSpec. - :rtype: str - """ - return self._component_name - - @component_name.setter - def component_name(self, component_name: str): - """Sets the component_name of this ComponentSpec. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :param component_name: The component_name of this ComponentSpec. - :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 images(self) -> List[FileId]: - """Gets the images of this ComponentSpec. - - List of all images associated with the component. Images are specified using the file identifiers. Partner OP provides these images using file upload api. # noqa: E501 - - :return: The images of this ComponentSpec. - :rtype: List[FileId] - """ - return self._images - - @images.setter - def images(self, images: List[FileId]): - """Sets the images of this ComponentSpec. - - List of all images associated with the component. Images are specified using the file identifiers. Partner OP provides these images using file upload api. # noqa: E501 - - :param images: The images of this ComponentSpec. - :type images: List[FileId] - """ - if images is None: - raise ValueError("Invalid value for `images`, must not be `None`") # noqa: E501 - - self._images = images - - @property - def num_of_instances(self) -> int: - """Gets the num_of_instances of this ComponentSpec. - - Number of component instances to be launched. # noqa: E501 - - :return: The num_of_instances of this ComponentSpec. - :rtype: int - """ - return self._num_of_instances - - @num_of_instances.setter - def num_of_instances(self, num_of_instances: int): - """Sets the num_of_instances of this ComponentSpec. - - Number of component instances to be launched. # noqa: E501 - - :param num_of_instances: The num_of_instances of this ComponentSpec. - :type num_of_instances: int - """ - if num_of_instances is None: - raise ValueError("Invalid value for `num_of_instances`, must not be `None`") # noqa: E501 - - self._num_of_instances = num_of_instances - - @property - def restart_policy(self) -> str: - """Gets the restart_policy of this ComponentSpec. - - How the platform shall handle component failure # noqa: E501 - - :return: The restart_policy of this ComponentSpec. - :rtype: str - """ - return self._restart_policy - - @restart_policy.setter - def restart_policy(self, restart_policy: str): - """Sets the restart_policy of this ComponentSpec. - - How the platform shall handle component failure # noqa: E501 - - :param restart_policy: The restart_policy of this ComponentSpec. - :type restart_policy: str - """ - allowed_values = ["RESTART_POLICY_ALWAYS", "RESTART_POLICY_NEVER"] # noqa: E501 - if restart_policy not in allowed_values: - raise ValueError( - "Invalid value for `restart_policy` ({0}), must be one of {1}" - .format(restart_policy, allowed_values) - ) - - self._restart_policy = restart_policy - - @property - def command_line_params(self) -> CommandLineParams: - """Gets the command_line_params of this ComponentSpec. - - - :return: The command_line_params of this ComponentSpec. - :rtype: CommandLineParams - """ - return self._command_line_params - - @command_line_params.setter - def command_line_params(self, command_line_params: CommandLineParams): - """Sets the command_line_params of this ComponentSpec. - - - :param command_line_params: The command_line_params of this ComponentSpec. - :type command_line_params: CommandLineParams - """ - - self._command_line_params = command_line_params - - @property - def exposed_interfaces(self) -> List[InterfaceDetails]: - """Gets the exposed_interfaces of this ComponentSpec. - - 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. # noqa: E501 - - :return: The exposed_interfaces of this ComponentSpec. - :rtype: List[InterfaceDetails] - """ - return self._exposed_interfaces - - @exposed_interfaces.setter - def exposed_interfaces(self, exposed_interfaces: List[InterfaceDetails]): - """Sets the exposed_interfaces of this ComponentSpec. - - 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. # noqa: E501 - - :param exposed_interfaces: The exposed_interfaces of this ComponentSpec. - :type exposed_interfaces: List[InterfaceDetails] - """ - - self._exposed_interfaces = exposed_interfaces - - @property - def compute_resource_profile(self) -> ComputeResourceInfo: - """Gets the compute_resource_profile of this ComponentSpec. - - - :return: The compute_resource_profile of this ComponentSpec. - :rtype: ComputeResourceInfo - """ - return self._compute_resource_profile - - @compute_resource_profile.setter - def compute_resource_profile(self, compute_resource_profile: ComputeResourceInfo): - """Sets the compute_resource_profile of this ComponentSpec. - - - :param compute_resource_profile: The compute_resource_profile of this ComponentSpec. - :type compute_resource_profile: ComputeResourceInfo - """ - if compute_resource_profile is None: - raise ValueError("Invalid value for `compute_resource_profile`, must not be `None`") # noqa: E501 - - self._compute_resource_profile = compute_resource_profile - - @property - def comp_env_params(self) -> List[CompEnvParams]: - """Gets the comp_env_params of this ComponentSpec. - - - :return: The comp_env_params of this ComponentSpec. - :rtype: List[CompEnvParams] - """ - return self._comp_env_params - - @comp_env_params.setter - def comp_env_params(self, comp_env_params: List[CompEnvParams]): - """Sets the comp_env_params of this ComponentSpec. - - - :param comp_env_params: The comp_env_params of this ComponentSpec. - :type comp_env_params: List[CompEnvParams] - """ - - self._comp_env_params = comp_env_params - - @property - def deployment_config(self) -> DeploymentConfig: - """Gets the deployment_config of this ComponentSpec. - - - :return: The deployment_config of this ComponentSpec. - :rtype: DeploymentConfig - """ - return self._deployment_config - - @deployment_config.setter - def deployment_config(self, deployment_config: DeploymentConfig): - """Sets the deployment_config of this ComponentSpec. - - - :param deployment_config: The deployment_config of this ComponentSpec. - :type deployment_config: DeploymentConfig - """ - - self._deployment_config = deployment_config - - @property - def persistent_volumes(self) -> List[PersistentVolumeDetails]: - """Gets the persistent_volumes of this ComponentSpec. - - The ephemeral volume a container process may need to temporary store internal data # noqa: E501 - - :return: The persistent_volumes of this ComponentSpec. - :rtype: List[PersistentVolumeDetails] - """ - return self._persistent_volumes - - @persistent_volumes.setter - def persistent_volumes(self, persistent_volumes: List[PersistentVolumeDetails]): - """Sets the persistent_volumes of this ComponentSpec. - - The ephemeral volume a container process may need to temporary store internal data # noqa: E501 - - :param persistent_volumes: The persistent_volumes of this ComponentSpec. - :type persistent_volumes: List[PersistentVolumeDetails] - """ - - self._persistent_volumes = persistent_volumes - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/compute_resource_info.py b/src/models/compute_resource_info.py deleted file mode 100644 index 6f754dd41e02f6576dc504102c031331829dc937..0000000000000000000000000000000000000000 --- a/src/models/compute_resource_info.py +++ /dev/null @@ -1,322 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.gpu_info import GpuInfo # noqa: F401,E501 -from models.huge_page import HugePage # noqa: F401,E501 -from models.vcpu import Vcpu # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ComputeResourceInfo(Model): - def __init__(self, cpu_arch_type: str=None, num_cpu: Vcpu=None, memory: int=None, disk_storage: int=None, gpu: List[GpuInfo]=None, vpu: int=None, fpga: int=None, hugepages: List[HugePage]=None, cpu_exclusivity: bool=None): # noqa: E501 - """ComputeResourceInfo - a model defined in Swagger - - :param cpu_arch_type: The cpu_arch_type of this ComputeResourceInfo. # noqa: E501 - :type cpu_arch_type: str - :param num_cpu: The num_cpu of this ComputeResourceInfo. # noqa: E501 - :type num_cpu: Vcpu - :param memory: The memory of this ComputeResourceInfo. # noqa: E501 - :type memory: int - :param disk_storage: The disk_storage of this ComputeResourceInfo. # noqa: E501 - :type disk_storage: int - :param gpu: The gpu of this ComputeResourceInfo. # noqa: E501 - :type gpu: List[GpuInfo] - :param vpu: The vpu of this ComputeResourceInfo. # noqa: E501 - :type vpu: int - :param fpga: The fpga of this ComputeResourceInfo. # noqa: E501 - :type fpga: int - :param hugepages: The hugepages of this ComputeResourceInfo. # noqa: E501 - :type hugepages: List[HugePage] - :param cpu_exclusivity: The cpu_exclusivity of this ComputeResourceInfo. # noqa: E501 - :type cpu_exclusivity: bool - """ - self.swagger_types = { - 'cpu_arch_type': str, - 'num_cpu': Vcpu, - 'memory': int, - 'disk_storage': int, - 'gpu': List[GpuInfo], - 'vpu': int, - 'fpga': int, - 'hugepages': List[HugePage], - 'cpu_exclusivity': bool - } - - self.attribute_map = { - 'cpu_arch_type': 'cpuArchType', - 'num_cpu': 'numCPU', - 'memory': 'memory', - 'disk_storage': 'diskStorage', - 'gpu': 'gpu', - 'vpu': 'vpu', - 'fpga': 'fpga', - 'hugepages': 'hugepages', - 'cpu_exclusivity': 'cpuExclusivity' - } - self._cpu_arch_type = cpu_arch_type - self._num_cpu = num_cpu - self._memory = memory - self._disk_storage = disk_storage - self._gpu = gpu - self._vpu = vpu - self._fpga = fpga - self._hugepages = hugepages - self._cpu_exclusivity = cpu_exclusivity - - @classmethod - def from_dict(cls, dikt) -> 'ComputeResourceInfo': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ComputeResourceInfo of this ComputeResourceInfo. # noqa: E501 - :rtype: ComputeResourceInfo - """ - return util.deserialize_model(dikt, cls) - - @property - def cpu_arch_type(self) -> str: - """Gets the cpu_arch_type of this ComputeResourceInfo. - - CPU Instruction Set Architecture (ISA) E.g., Intel, Arm etc. # noqa: E501 - - :return: The cpu_arch_type of this ComputeResourceInfo. - :rtype: str - """ - return self._cpu_arch_type - - @cpu_arch_type.setter - def cpu_arch_type(self, cpu_arch_type: str): - """Sets the cpu_arch_type of this ComputeResourceInfo. - - CPU Instruction Set Architecture (ISA) E.g., Intel, Arm etc. # noqa: E501 - - :param cpu_arch_type: The cpu_arch_type of this ComputeResourceInfo. - :type cpu_arch_type: str - """ - allowed_values = ["ISA_X86_64", "ISA_ARM_64"] # noqa: E501 - if cpu_arch_type not in allowed_values: - raise ValueError( - "Invalid value for `cpu_arch_type` ({0}), must be one of {1}" - .format(cpu_arch_type, allowed_values) - ) - - self._cpu_arch_type = cpu_arch_type - - @property - def num_cpu(self) -> Vcpu: - """Gets the num_cpu of this ComputeResourceInfo. - - - :return: The num_cpu of this ComputeResourceInfo. - :rtype: Vcpu - """ - return self._num_cpu - - @num_cpu.setter - def num_cpu(self, num_cpu: Vcpu): - """Sets the num_cpu of this ComputeResourceInfo. - - - :param num_cpu: The num_cpu of this ComputeResourceInfo. - :type num_cpu: Vcpu - """ - 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 ComputeResourceInfo. - - Amount of RAM in Mbytes # noqa: E501 - - :return: The memory of this ComputeResourceInfo. - :rtype: int - """ - return self._memory - - @memory.setter - def memory(self, memory: int): - """Sets the memory of this ComputeResourceInfo. - - Amount of RAM in Mbytes # noqa: E501 - - :param memory: The memory of this ComputeResourceInfo. - :type memory: int - """ - if memory is None: - raise ValueError("Invalid value for `memory`, must not be `None`") # noqa: E501 - - self._memory = memory - - @property - def disk_storage(self) -> int: - """Gets the disk_storage of this ComputeResourceInfo. - - Amount of disk storage in Gbytes for a given ISA type # noqa: E501 - - :return: The disk_storage of this ComputeResourceInfo. - :rtype: int - """ - return self._disk_storage - - @disk_storage.setter - def disk_storage(self, disk_storage: int): - """Sets the disk_storage of this ComputeResourceInfo. - - Amount of disk storage in Gbytes for a given ISA type # noqa: E501 - - :param disk_storage: The disk_storage of this ComputeResourceInfo. - :type disk_storage: int - """ - - self._disk_storage = disk_storage - - @property - def gpu(self) -> List[GpuInfo]: - """Gets the gpu of this ComputeResourceInfo. - - - :return: The gpu of this ComputeResourceInfo. - :rtype: List[GpuInfo] - """ - return self._gpu - - @gpu.setter - def gpu(self, gpu: List[GpuInfo]): - """Sets the gpu of this ComputeResourceInfo. - - - :param gpu: The gpu of this ComputeResourceInfo. - :type gpu: List[GpuInfo] - """ - - self._gpu = gpu - - @property - def vpu(self) -> int: - """Gets the vpu of this ComputeResourceInfo. - - Number of Intel VPUs available for a given ISA type # noqa: E501 - - :return: The vpu of this ComputeResourceInfo. - :rtype: int - """ - return self._vpu - - @vpu.setter - def vpu(self, vpu: int): - """Sets the vpu of this ComputeResourceInfo. - - Number of Intel VPUs available for a given ISA type # noqa: E501 - - :param vpu: The vpu of this ComputeResourceInfo. - :type vpu: int - """ - - self._vpu = vpu - - @property - def fpga(self) -> int: - """Gets the fpga of this ComputeResourceInfo. - - Number of FPGAs available for a given ISA type # noqa: E501 - - :return: The fpga of this ComputeResourceInfo. - :rtype: int - """ - return self._fpga - - @fpga.setter - def fpga(self, fpga: int): - """Sets the fpga of this ComputeResourceInfo. - - Number of FPGAs available for a given ISA type # noqa: E501 - - :param fpga: The fpga of this ComputeResourceInfo. - :type fpga: int - """ - - self._fpga = fpga - - @property - def hugepages(self) -> List[HugePage]: - """Gets the hugepages of this ComputeResourceInfo. - - - :return: The hugepages of this ComputeResourceInfo. - :rtype: List[HugePage] - """ - return self._hugepages - - @hugepages.setter - def hugepages(self, hugepages: List[HugePage]): - """Sets the hugepages of this ComputeResourceInfo. - - - :param hugepages: The hugepages of this ComputeResourceInfo. - :type hugepages: List[HugePage] - """ - - self._hugepages = hugepages - - @property - def cpu_exclusivity(self) -> bool: - """Gets the cpu_exclusivity of this ComputeResourceInfo. - - Support for exclusive CPUs # noqa: E501 - - :return: The cpu_exclusivity of this ComputeResourceInfo. - :rtype: bool - """ - return self._cpu_exclusivity - - @cpu_exclusivity.setter - def cpu_exclusivity(self, cpu_exclusivity: bool): - """Sets the cpu_exclusivity of this ComputeResourceInfo. - - Support for exclusive CPUs # noqa: E501 - - :param cpu_exclusivity: The cpu_exclusivity of this ComputeResourceInfo. - :type cpu_exclusivity: bool - """ - - self._cpu_exclusivity = cpu_exclusivity - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/country_code.py b/src/models/country_code.py deleted file mode 100644 index 34a0e41460f318f1d9209e0347d5f80822f75fbd..0000000000000000000000000000000000000000 --- a/src/models/country_code.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class CountryCode(Model): - def __init__(self): # noqa: E501 - """CountryCode - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'CountryCode': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The CountryCode of this CountryCode. # noqa: E501 - :rtype: CountryCode - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/cpu_arch_type.py b/src/models/cpu_arch_type.py deleted file mode 100644 index 5a619bd9c9c886a70ab6d6d880a48167aa58764e..0000000000000000000000000000000000000000 --- a/src/models/cpu_arch_type.py +++ /dev/null @@ -1,53 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class CPUArchType(Model): - """ - allowed enum values - """ - X86 = "ISA_X86" - X86_64 = "ISA_X86_64" - ARM_64 = "ISA_ARM_64" - - def __init__(self): # noqa: E501 - """CPUArchType - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'CPUArchType': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The CPUArchType of this CPUArchType. # noqa: E501 - :rtype: CPUArchType - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/deployment_config.py b/src/models/deployment_config.py deleted file mode 100644 index 7874836fa31d72d3e41277cdf7990164ff2fbaba..0000000000000000000000000000000000000000 --- a/src/models/deployment_config.py +++ /dev/null @@ -1,117 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class DeploymentConfig(Model): - def __init__(self, config_type: str=None, contents: str=None): # noqa: E501 - """DeploymentConfig - a model defined in Swagger - - :param config_type: The config_type of this DeploymentConfig. # noqa: E501 - :type config_type: str - :param contents: The contents of this DeploymentConfig. # noqa: E501 - :type contents: str - """ - self.swagger_types = { - 'config_type': str, - 'contents': str - } - - self.attribute_map = { - 'config_type': 'configType', - 'contents': 'contents' - } - self._config_type = config_type - self._contents = contents - - @classmethod - def from_dict(cls, dikt) -> 'DeploymentConfig': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The DeploymentConfig of this DeploymentConfig. # noqa: E501 - :rtype: DeploymentConfig - """ - return util.deserialize_model(dikt, cls) - - @property - def config_type(self) -> str: - """Gets the config_type of this DeploymentConfig. - - Config type. # noqa: E501 - - :return: The config_type of this DeploymentConfig. - :rtype: str - """ - return self._config_type - - @config_type.setter - def config_type(self, config_type: str): - """Sets the config_type of this DeploymentConfig. - - Config type. # noqa: E501 - - :param config_type: The config_type of this DeploymentConfig. - :type config_type: str - """ - allowed_values = ["DOCKER_COMPOSE", "KUBERNETES_MANIFEST", "CLOUD_INIT", "HELM_VALUES"] # noqa: E501 - if config_type not in allowed_values: - raise ValueError( - "Invalid value for `config_type` ({0}), must be one of {1}" - .format(config_type, allowed_values) - ) - - self._config_type = config_type - - @property - def contents(self) -> str: - """Gets the contents of this DeploymentConfig. - - Contents of the configuration. # noqa: E501 - - :return: The contents of this DeploymentConfig. - :rtype: str - """ - return self._contents - - @contents.setter - def contents(self, contents: str): - """Sets the contents of this DeploymentConfig. - - Contents of the configuration. # noqa: E501 - - :param contents: The contents of this DeploymentConfig. - :type contents: str - """ - if contents is None: - raise ValueError("Invalid value for `contents`, must not be `None`") # noqa: E501 - - self._contents = contents - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/federation_context_id.py b/src/models/federation_context_id.py deleted file mode 100644 index 1c4e043c61b8419cff3659bc44fc1581bf3bc0a1..0000000000000000000000000000000000000000 --- a/src/models/federation_context_id.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FederationContextId(Model): - def __init__(self): # noqa: E501 - """FederationContextId - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextId': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FederationContextId of this FederationContextId. # noqa: E501 - :rtype: FederationContextId - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/federation_context_id_artefact_body.py b/src/models/federation_context_id_artefact_body.py deleted file mode 100644 index 430461feabae27fa3676d3a5f677a45ec1382118..0000000000000000000000000000000000000000 --- a/src/models/federation_context_id_artefact_body.py +++ /dev/null @@ -1,464 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import - -import uuid -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.artefact_id import ArtefactId # noqa: F401,E501 -from models.component_spec import ComponentSpec # noqa: F401,E501 -from models.object_repo_location import ObjectRepoLocation # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationContextIdArtefactBody(Model): - def __init__(self, artefact_id: ArtefactId=None, app_provider_id: AppProviderId=None, artefact_name: str=None, artefact_version_info: str=None, artefact_description: str=None, artefact_virt_type: str=None, artefact_file_name: str=None, artefact_file_format: str=None, artefact_descriptor_type: str=None, repo_type: str=None, artefact_repo_location: ObjectRepoLocation=None, artefact_file: str=None, component_spec: List[ComponentSpec]=None): # noqa: E501 - """FederationContextIdArtefactBody - a model defined in Swagger - - :param artefact_id: The artefact_id of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_id: ArtefactId - :param app_provider_id: The app_provider_id of this FederationContextIdArtefactBody. # noqa: E501 - :type app_provider_id: AppProviderId - :param artefact_name: The artefact_name of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_name: str - :param artefact_version_info: The artefact_version_info of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_version_info: str - :param artefact_description: The artefact_description of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_description: str - :param artefact_virt_type: The artefact_virt_type of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_virt_type: str - :param artefact_file_name: The artefact_file_name of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_file_name: str - :param artefact_file_format: The artefact_file_format of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_file_format: str - :param artefact_descriptor_type: The artefact_descriptor_type of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_descriptor_type: str - :param repo_type: The repo_type of this FederationContextIdArtefactBody. # noqa: E501 - :type repo_type: str - :param artefact_repo_location: The artefact_repo_location of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_repo_location: ObjectRepoLocation - :param artefact_file: The artefact_file of this FederationContextIdArtefactBody. # noqa: E501 - :type artefact_file: str - :param component_spec: The component_spec of this FederationContextIdArtefactBody. # noqa: E501 - :type component_spec: List[ComponentSpec] - """ - self.swagger_types = { - 'artefact_id': ArtefactId, - 'app_provider_id': AppProviderId, - 'artefact_name': str, - 'artefact_version_info': str, - 'artefact_description': str, - 'artefact_virt_type': str, - 'artefact_file_name': str, - 'artefact_file_format': str, - 'artefact_descriptor_type': str, - 'repo_type': str, - 'artefact_repo_location': ObjectRepoLocation, - 'artefact_file': str, - 'component_spec': List[ComponentSpec] - } - - self.attribute_map = { - 'artefact_id': 'artefactId', - 'app_provider_id': 'appProviderId', - 'artefact_name': 'artefactName', - 'artefact_version_info': 'artefactVersionInfo', - 'artefact_description': 'artefactDescription', - 'artefact_virt_type': 'artefactVirtType', - 'artefact_file_name': 'artefactFileName', - 'artefact_file_format': 'artefactFileFormat', - 'artefact_descriptor_type': 'artefactDescriptorType', - 'repo_type': 'repoType', - 'artefact_repo_location': 'artefactRepoLocation', - 'artefact_file': 'artefactFile', - 'component_spec': 'componentSpec' - } - self._artefact_id = artefact_id - self._app_provider_id = app_provider_id - self._artefact_name = artefact_name - self._artefact_version_info = artefact_version_info - self._artefact_description = artefact_description - self._artefact_virt_type = artefact_virt_type - self._artefact_file_name = artefact_file_name - self._artefact_file_format = artefact_file_format - self._artefact_descriptor_type = artefact_descriptor_type - self._repo_type = repo_type - self._artefact_repo_location = artefact_repo_location - self._artefact_file = artefact_file - self._component_spec = component_spec - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdArtefactBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextId_artefact_body of this FederationContextIdArtefactBody. # noqa: E501 - :rtype: FederationContextIdArtefactBody - """ - return util.deserialize_model(dikt, cls) - - @property - def artefact_id(self) -> ArtefactId: - """Gets the artefact_id of this FederationContextIdArtefactBody. - - - :return: The artefact_id of this FederationContextIdArtefactBody. - :rtype: ArtefactId - """ - return self._artefact_id - - @artefact_id.setter - def artefact_id(self, artefact_id: ArtefactId): - """Sets the artefact_id of this FederationContextIdArtefactBody. - - - :param artefact_id: The artefact_id of this FederationContextIdArtefactBody. - :type artefact_id: ArtefactId - """ - if artefact_id is None: - raise ValueError("Invalid value for `artefact_id`, must not be `None`") # noqa: E501 - - try: - uuid.UUID(artefact_id) - except ValueError: - raise ValueError("Invalid value for `artefact_id`, must be UUID`") - - self._artefact_id = artefact_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this FederationContextIdArtefactBody. - - - :return: The app_provider_id of this FederationContextIdArtefactBody. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this FederationContextIdArtefactBody. - - - :param app_provider_id: The app_provider_id of this FederationContextIdArtefactBody. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def artefact_name(self) -> str: - """Gets the artefact_name of this FederationContextIdArtefactBody. - - Name of the artefact. # noqa: E501 - - :return: The artefact_name of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_name - - @artefact_name.setter - def artefact_name(self, artefact_name: str): - """Sets the artefact_name of this FederationContextIdArtefactBody. - - Name of the artefact. # noqa: E501 - - :param artefact_name: The artefact_name of this FederationContextIdArtefactBody. - :type artefact_name: str - """ - if artefact_name is None: - raise ValueError("Invalid value for `artefact_name`, must not be `None`") # noqa: E501 - - self._artefact_name = artefact_name - - @property - def artefact_version_info(self) -> str: - """Gets the artefact_version_info of this FederationContextIdArtefactBody. - - Artefact version information # noqa: E501 - - :return: The artefact_version_info of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_version_info - - @artefact_version_info.setter - def artefact_version_info(self, artefact_version_info: str): - """Sets the artefact_version_info of this FederationContextIdArtefactBody. - - Artefact version information # noqa: E501 - - :param artefact_version_info: The artefact_version_info of this FederationContextIdArtefactBody. - :type artefact_version_info: str - """ - if artefact_version_info is None: - raise ValueError("Invalid value for `artefact_version_info`, must not be `None`") # noqa: E501 - - self._artefact_version_info = artefact_version_info - - @property - def artefact_description(self) -> str: - """Gets the artefact_description of this FederationContextIdArtefactBody. - - Brief description of the artefact by the application provider # noqa: E501 - - :return: The artefact_description of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_description - - @artefact_description.setter - def artefact_description(self, artefact_description: str): - """Sets the artefact_description of this FederationContextIdArtefactBody. - - Brief description of the artefact by the application provider # noqa: E501 - - :param artefact_description: The artefact_description of this FederationContextIdArtefactBody. - :type artefact_description: str - """ - - self._artefact_description = artefact_description - - @property - def artefact_virt_type(self) -> str: - """Gets the artefact_virt_type of this FederationContextIdArtefactBody. - - - :return: The artefact_virt_type of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_virt_type - - @artefact_virt_type.setter - def artefact_virt_type(self, artefact_virt_type: str): - """Sets the artefact_virt_type of this FederationContextIdArtefactBody. - - - :param artefact_virt_type: The artefact_virt_type of this FederationContextIdArtefactBody. - :type artefact_virt_type: str - """ - allowed_values = ["VM_TYPE", "CONTAINER_TYPE"] # noqa: E501 - if artefact_virt_type not in allowed_values: - raise ValueError( - "Invalid value for `artefact_virt_type` ({0}), must be one of {1}" - .format(artefact_virt_type, allowed_values) - ) - - self._artefact_virt_type = artefact_virt_type - - @property - def artefact_file_name(self) -> str: - """Gets the artefact_file_name of this FederationContextIdArtefactBody. - - Name of the file. # noqa: E501 - - :return: The artefact_file_name of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_file_name - - @artefact_file_name.setter - def artefact_file_name(self, artefact_file_name: str): - """Sets the artefact_file_name of this FederationContextIdArtefactBody. - - Name of the file. # noqa: E501 - - :param artefact_file_name: The artefact_file_name of this FederationContextIdArtefactBody. - :type artefact_file_name: str - """ - - self._artefact_file_name = artefact_file_name - - @property - def artefact_file_format(self) -> str: - """Gets the artefact_file_format of this FederationContextIdArtefactBody. - - Artefacts like Helm charts or Terraform scripts may need compressed format. # noqa: E501 - - :return: The artefact_file_format of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_file_format - - @artefact_file_format.setter - def artefact_file_format(self, artefact_file_format: str): - """Sets the artefact_file_format of this FederationContextIdArtefactBody. - - Artefacts like Helm charts or Terraform scripts may need compressed format. # noqa: E501 - - :param artefact_file_format: The artefact_file_format of this FederationContextIdArtefactBody. - :type artefact_file_format: str - """ - allowed_values = ["WINZIP", "TAR", "TEXT", "TARGZ"] # noqa: E501 - if artefact_file_format not in allowed_values: - raise ValueError( - "Invalid value for `artefact_file_format` ({0}), must be one of {1}" - .format(artefact_file_format, allowed_values) - ) - - self._artefact_file_format = artefact_file_format - - @property - def artefact_descriptor_type(self) -> str: - """Gets the artefact_descriptor_type of this FederationContextIdArtefactBody. - - Type of descriptor present in the artefact. App provider can either define either a Helm chart or a Terraform script or container spec. # noqa: E501 - - :return: The artefact_descriptor_type of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_descriptor_type - - @artefact_descriptor_type.setter - def artefact_descriptor_type(self, artefact_descriptor_type: str): - """Sets the artefact_descriptor_type of this FederationContextIdArtefactBody. - - Type of descriptor present in the artefact. App provider can either define either a Helm chart or a Terraform script or container spec. # noqa: E501 - - :param artefact_descriptor_type: The artefact_descriptor_type of this FederationContextIdArtefactBody. - :type artefact_descriptor_type: str - """ - allowed_values = ["HELM", "TERRAFORM", "ANSIBLE", "SHELL", "COMPONENTSPEC"] # noqa: E501 - if artefact_descriptor_type not in allowed_values: - raise ValueError( - "Invalid value for `artefact_descriptor_type` ({0}), must be one of {1}" - .format(artefact_descriptor_type, allowed_values) - ) - - self._artefact_descriptor_type = artefact_descriptor_type - - @property - def repo_type(self) -> str: - """Gets the repo_type of this FederationContextIdArtefactBody. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :return: The repo_type of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._repo_type - - @repo_type.setter - def repo_type(self, repo_type: str): - """Sets the repo_type of this FederationContextIdArtefactBody. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :param repo_type: The repo_type of this FederationContextIdArtefactBody. - :type repo_type: str - """ - allowed_values = ["PRIVATEREPO", "PUBLICREPO", "UPLOAD"] # noqa: E501 - if repo_type not in allowed_values: - raise ValueError( - "Invalid value for `repo_type` ({0}), must be one of {1}" - .format(repo_type, allowed_values) - ) - - self._repo_type = repo_type - - @property - def artefact_repo_location(self) -> ObjectRepoLocation: - """Gets the artefact_repo_location of this FederationContextIdArtefactBody. - - - :return: The artefact_repo_location of this FederationContextIdArtefactBody. - :rtype: ObjectRepoLocation - """ - return self._artefact_repo_location - - @artefact_repo_location.setter - def artefact_repo_location(self, artefact_repo_location: ObjectRepoLocation): - """Sets the artefact_repo_location of this FederationContextIdArtefactBody. - - - :param artefact_repo_location: The artefact_repo_location of this FederationContextIdArtefactBody. - :type artefact_repo_location: ObjectRepoLocation - """ - - self._artefact_repo_location = artefact_repo_location - - @property - def artefact_file(self) -> str: - """Gets the artefact_file of this FederationContextIdArtefactBody. - - Helm archive/Terraform archive/container spec file or Binary image associated with an application component. # noqa: E501 - - :return: The artefact_file of this FederationContextIdArtefactBody. - :rtype: str - """ - return self._artefact_file - - @artefact_file.setter - def artefact_file(self, artefact_file: str): - """Sets the artefact_file of this FederationContextIdArtefactBody. - - Helm archive/Terraform archive/container spec file or Binary image associated with an application component. # noqa: E501 - - :param artefact_file: The artefact_file of this FederationContextIdArtefactBody. - :type artefact_file: str - """ - - self._artefact_file = artefact_file - - @property - def component_spec(self) -> List[ComponentSpec]: - """Gets the component_spec of this FederationContextIdArtefactBody. - - Details about compute, networking and storage requirements for each component of the application. App provider should define all information needed to instantiate the component. If artefact is being defined at component level this section should have information just about the component. In case the artefact is being defined at application level the section should provide details about all the components. # noqa: E501 - - :return: The component_spec of this FederationContextIdArtefactBody. - :rtype: List[ComponentSpec] - """ - return self._component_spec - - @component_spec.setter - def component_spec(self, component_spec: List[ComponentSpec]): - """Sets the component_spec of this FederationContextIdArtefactBody. - - Details about compute, networking and storage requirements for each component of the application. App provider should define all information needed to instantiate the component. If artefact is being defined at component level this section should have information just about the component. In case the artefact is being defined at application level the section should provide details about all the components. # noqa: E501 - - :param component_spec: The component_spec of this FederationContextIdArtefactBody. - :type component_spec: List[ComponentSpec] - """ - if component_spec is None: - raise ValueError("Invalid value for `component_spec`, must not be `None`") # noqa: E501 - - self._component_spec = component_spec - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/federation_context_id_files_body.py b/src/models/federation_context_id_files_body.py deleted file mode 100644 index a5e5d008a4427fb0a6293bd4bd85ef9cf7098c68..0000000000000000000000000000000000000000 --- a/src/models/federation_context_id_files_body.py +++ /dev/null @@ -1,397 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.cpu_arch_type import CPUArchType # noqa: F401,E501 -from models.file_id import FileId # noqa: F401,E501 -from models.object_repo_location import ObjectRepoLocation # noqa: F401,E501 -from models.os_type import OSType # noqa: F401,E501 -from models.virt_image_type import VirtImageType # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationContextIdFilesBody(Model): - def __init__(self, file_id: FileId=None, app_provider_id: AppProviderId=None, file_name: str=None, file_description: str=None, file_version_info: str=None, file_type: VirtImageType=None, checksum: str=None, img_os_type: OSType=None, img_ins_set_arch: CPUArchType=None, repo_type: str=None, file_repo_location: ObjectRepoLocation=None, file: str=None): # noqa: E501 - """FederationContextIdFilesBody - a model defined in Swagger - - :param file_id: The file_id of this FederationContextIdFilesBody. # noqa: E501 - :type file_id: FileId - :param app_provider_id: The app_provider_id of this FederationContextIdFilesBody. # noqa: E501 - :type app_provider_id: AppProviderId - :param file_name: The file_name of this FederationContextIdFilesBody. # noqa: E501 - :type file_name: str - :param file_description: The file_description of this FederationContextIdFilesBody. # noqa: E501 - :type file_description: str - :param file_version_info: The file_version_info of this FederationContextIdFilesBody. # noqa: E501 - :type file_version_info: str - :param file_type: The file_type of this FederationContextIdFilesBody. # noqa: E501 - :type file_type: VirtImageType - :param checksum: The checksum of this FederationContextIdFilesBody. # noqa: E501 - :type checksum: str - :param img_os_type: The img_os_type of this FederationContextIdFilesBody. # noqa: E501 - :type img_os_type: OSType - :param img_ins_set_arch: The img_ins_set_arch of this FederationContextIdFilesBody. # noqa: E501 - :type img_ins_set_arch: CPUArchType - :param repo_type: The repo_type of this FederationContextIdFilesBody. # noqa: E501 - :type repo_type: str - :param file_repo_location: The file_repo_location of this FederationContextIdFilesBody. # noqa: E501 - :type file_repo_location: ObjectRepoLocation - :param file: The file of this FederationContextIdFilesBody. # noqa: E501 - :type file: str - """ - self.swagger_types = { - 'file_id': FileId, - 'app_provider_id': AppProviderId, - 'file_name': str, - 'file_description': str, - 'file_version_info': str, - 'file_type': VirtImageType, - 'checksum': str, - 'img_os_type': OSType, - 'img_ins_set_arch': CPUArchType, - 'repo_type': str, - 'file_repo_location': ObjectRepoLocation, - 'file': str - } - - self.attribute_map = { - 'file_id': 'fileId', - 'app_provider_id': 'appProviderId', - 'file_name': 'fileName', - 'file_description': 'fileDescription', - 'file_version_info': 'fileVersionInfo', - 'file_type': 'fileType', - 'checksum': 'checksum', - 'img_os_type': 'imgOSType', - 'img_ins_set_arch': 'imgInsSetArch', - 'repo_type': 'repoType', - 'file_repo_location': 'fileRepoLocation', - 'file': 'file' - } - self._file_id = file_id - self._app_provider_id = app_provider_id - self._file_name = file_name - self._file_description = file_description - self._file_version_info = file_version_info - self._file_type = file_type - self._checksum = checksum - self._img_os_type = img_os_type - self._img_ins_set_arch = img_ins_set_arch - self._repo_type = repo_type - self._file_repo_location = file_repo_location - self._file = file - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdFilesBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextId_files_body of this FederationContextIdFilesBody. # noqa: E501 - :rtype: FederationContextIdFilesBody - """ - return util.deserialize_model(dikt, cls) - - @property - def file_id(self) -> FileId: - """Gets the file_id of this FederationContextIdFilesBody. - - - :return: The file_id of this FederationContextIdFilesBody. - :rtype: FileId - """ - return self._file_id - - @file_id.setter - def file_id(self, file_id: FileId): - """Sets the file_id of this FederationContextIdFilesBody. - - - :param file_id: The file_id of this FederationContextIdFilesBody. - :type file_id: FileId - """ - if file_id is None: - raise ValueError("Invalid value for `file_id`, must not be `None`") # noqa: E501 - - self._file_id = file_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this FederationContextIdFilesBody. - - - :return: The app_provider_id of this FederationContextIdFilesBody. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this FederationContextIdFilesBody. - - - :param app_provider_id: The app_provider_id of this FederationContextIdFilesBody. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def file_name(self) -> str: - """Gets the file_name of this FederationContextIdFilesBody. - - Name of the image file. App provides specifies this name when image is uploaded on originating OP over NBI. # noqa: E501 - - :return: The file_name of this FederationContextIdFilesBody. - :rtype: str - """ - return self._file_name - - @file_name.setter - def file_name(self, file_name: str): - """Sets the file_name of this FederationContextIdFilesBody. - - Name of the image file. App provides specifies this name when image is uploaded on originating OP over NBI. # noqa: E501 - - :param file_name: The file_name of this FederationContextIdFilesBody. - :type file_name: str - """ - if file_name is None: - raise ValueError("Invalid value for `file_name`, must not be `None`") # noqa: E501 - - self._file_name = file_name - - @property - def file_description(self) -> str: - """Gets the file_description of this FederationContextIdFilesBody. - - Brief description about the image file. # noqa: E501 - - :return: The file_description of this FederationContextIdFilesBody. - :rtype: str - """ - return self._file_description - - @file_description.setter - def file_description(self, file_description: str): - """Sets the file_description of this FederationContextIdFilesBody. - - Brief description about the image file. # noqa: E501 - - :param file_description: The file_description of this FederationContextIdFilesBody. - :type file_description: str - """ - - self._file_description = file_description - - @property - def file_version_info(self) -> str: - """Gets the file_version_info of this FederationContextIdFilesBody. - - File version information # noqa: E501 - - :return: The file_version_info of this FederationContextIdFilesBody. - :rtype: str - """ - return self._file_version_info - - @file_version_info.setter - def file_version_info(self, file_version_info: str): - """Sets the file_version_info of this FederationContextIdFilesBody. - - File version information # noqa: E501 - - :param file_version_info: The file_version_info of this FederationContextIdFilesBody. - :type file_version_info: str - """ - if file_version_info is None: - raise ValueError("Invalid value for `file_version_info`, must not be `None`") # noqa: E501 - - self._file_version_info = file_version_info - - @property - def file_type(self) -> VirtImageType: - """Gets the file_type of this FederationContextIdFilesBody. - - - :return: The file_type of this FederationContextIdFilesBody. - :rtype: VirtImageType - """ - return self._file_type - - @file_type.setter - def file_type(self, file_type: VirtImageType): - """Sets the file_type of this FederationContextIdFilesBody. - - - :param file_type: The file_type of this FederationContextIdFilesBody. - :type file_type: VirtImageType - """ - if file_type is None: - raise ValueError("Invalid value for `file_type`, must not be `None`") # noqa: E501 - - self._file_type = file_type - - @property - def checksum(self) -> str: - """Gets the checksum of this FederationContextIdFilesBody. - - MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 - - :return: The checksum of this FederationContextIdFilesBody. - :rtype: str - """ - return self._checksum - - @checksum.setter - def checksum(self, checksum: str): - """Sets the checksum of this FederationContextIdFilesBody. - - MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 - - :param checksum: The checksum of this FederationContextIdFilesBody. - :type checksum: str - """ - - self._checksum = checksum - - @property - def img_os_type(self) -> OSType: - """Gets the img_os_type of this FederationContextIdFilesBody. - - - :return: The img_os_type of this FederationContextIdFilesBody. - :rtype: OSType - """ - return self._img_os_type - - @img_os_type.setter - def img_os_type(self, img_os_type: OSType): - """Sets the img_os_type of this FederationContextIdFilesBody. - - - :param img_os_type: The img_os_type of this FederationContextIdFilesBody. - :type img_os_type: OSType - """ - if img_os_type is None: - raise ValueError("Invalid value for `img_os_type`, must not be `None`") # noqa: E501 - - self._img_os_type = img_os_type - - @property - def img_ins_set_arch(self) -> CPUArchType: - """Gets the img_ins_set_arch of this FederationContextIdFilesBody. - - - :return: The img_ins_set_arch of this FederationContextIdFilesBody. - :rtype: CPUArchType - """ - return self._img_ins_set_arch - - @img_ins_set_arch.setter - def img_ins_set_arch(self, img_ins_set_arch: CPUArchType): - """Sets the img_ins_set_arch of this FederationContextIdFilesBody. - - - :param img_ins_set_arch: The img_ins_set_arch of this FederationContextIdFilesBody. - :type img_ins_set_arch: CPUArchType - """ - if img_ins_set_arch is None: - raise ValueError("Invalid value for `img_ins_set_arch`, must not be `None`") # noqa: E501 - - self._img_ins_set_arch = img_ins_set_arch - - @property - def repo_type(self) -> str: - """Gets the repo_type of this FederationContextIdFilesBody. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :return: The repo_type of this FederationContextIdFilesBody. - :rtype: str - """ - return self._repo_type - - @repo_type.setter - def repo_type(self, repo_type: str): - """Sets the repo_type of this FederationContextIdFilesBody. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :param repo_type: The repo_type of this FederationContextIdFilesBody. - :type repo_type: str - """ - allowed_values = ["PRIVATEREPO", "PUBLICREPO", "UPLOAD"] # noqa: E501 - if repo_type not in allowed_values: - raise ValueError( - "Invalid value for `repo_type` ({0}), must be one of {1}" - .format(repo_type, allowed_values) - ) - - self._repo_type = repo_type - - @property - def file_repo_location(self) -> ObjectRepoLocation: - """Gets the file_repo_location of this FederationContextIdFilesBody. - - - :return: The file_repo_location of this FederationContextIdFilesBody. - :rtype: ObjectRepoLocation - """ - return self._file_repo_location - - @file_repo_location.setter - def file_repo_location(self, file_repo_location: ObjectRepoLocation): - """Sets the file_repo_location of this FederationContextIdFilesBody. - - - :param file_repo_location: The file_repo_location of this FederationContextIdFilesBody. - :type file_repo_location: ObjectRepoLocation - """ - - self._file_repo_location = file_repo_location - - @property - def file(self) -> str: - """Gets the file of this FederationContextIdFilesBody. - - Binary image associated with an application component. # noqa: E501 - - :return: The file of this FederationContextIdFilesBody. - :rtype: str - """ - return self._file - - @file.setter - def file(self, file: str): - """Sets the file of this FederationContextIdFilesBody. - - Binary image associated with an application component. # noqa: E501 - - :param file: The file of this FederationContextIdFilesBody. - :type file: str - """ - - self._file = file diff --git a/src/models/federation_context_id_partner_body.py b/src/models/federation_context_id_partner_body.py deleted file mode 100644 index c0d9b92b6ea2d09ec31e2365e5f7ffe4a3347dd2..0000000000000000000000000000000000000000 --- a/src/models/federation_context_id_partner_body.py +++ /dev/null @@ -1,262 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.fixed_network_ids import FixedNetworkIds # noqa: F401,E501 -from models.mobile_network_ids import MobileNetworkIds # noqa: F401,E501 -import util - - -class FederationContextIdPartnerBody(Model): - def __init__(self, object_type: str=None, operation_type: str=None, add_mobile_network_ids: MobileNetworkIds=None, remove_mobile_network_ids: MobileNetworkIds=None, add_fixed_network_ids: FixedNetworkIds=None, remove_fixed_network_ids: FixedNetworkIds=None, modification_date: datetime=None): # noqa: E501 - """FederationContextIdPartnerBody - a model defined in Swagger - - :param object_type: The object_type of this FederationContextIdPartnerBody. # noqa: E501 - :type object_type: str - :param operation_type: The operation_type of this FederationContextIdPartnerBody. # noqa: E501 - :type operation_type: str - :param add_mobile_network_ids: The add_mobile_network_ids of this FederationContextIdPartnerBody. # noqa: E501 - :type add_mobile_network_ids: MobileNetworkIds - :param remove_mobile_network_ids: The remove_mobile_network_ids of this FederationContextIdPartnerBody. # noqa: E501 - :type remove_mobile_network_ids: MobileNetworkIds - :param add_fixed_network_ids: The add_fixed_network_ids of this FederationContextIdPartnerBody. # noqa: E501 - :type add_fixed_network_ids: FixedNetworkIds - :param remove_fixed_network_ids: The remove_fixed_network_ids of this FederationContextIdPartnerBody. # noqa: E501 - :type remove_fixed_network_ids: FixedNetworkIds - :param modification_date: The modification_date of this FederationContextIdPartnerBody. # noqa: E501 - :type modification_date: datetime - """ - self.swagger_types = { - 'object_type': str, - 'operation_type': str, - 'add_mobile_network_ids': MobileNetworkIds, - 'remove_mobile_network_ids': MobileNetworkIds, - 'add_fixed_network_ids': FixedNetworkIds, - 'remove_fixed_network_ids': FixedNetworkIds, - 'modification_date': datetime - } - - self.attribute_map = { - 'object_type': 'objectType', - 'operation_type': 'operationType', - 'add_mobile_network_ids': 'addMobileNetworkIds', - 'remove_mobile_network_ids': 'removeMobileNetworkIds', - 'add_fixed_network_ids': 'addFixedNetworkIds', - 'remove_fixed_network_ids': 'removeFixedNetworkIds', - 'modification_date': 'modificationDate' - } - self._object_type = object_type - self._operation_type = operation_type - self._add_mobile_network_ids = add_mobile_network_ids - self._remove_mobile_network_ids = remove_mobile_network_ids - self._add_fixed_network_ids = add_fixed_network_ids - self._remove_fixed_network_ids = remove_fixed_network_ids - self._modification_date = modification_date - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdPartnerBody': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextId_partner_body of this FederationContextIdPartnerBody. # noqa: E501 - :rtype: FederationContextIdPartnerBody - """ - return util.deserialize_model(dikt, cls) - - @property - def object_type(self) -> str: - """Gets the object_type of this FederationContextIdPartnerBody. - - - :return: The object_type of this FederationContextIdPartnerBody. - :rtype: str - """ - return self._object_type - - @object_type.setter - def object_type(self, object_type: str): - """Sets the object_type of this FederationContextIdPartnerBody. - - - :param object_type: The object_type of this FederationContextIdPartnerBody. - :type object_type: str - """ - allowed_values = ["MOBILE_NETWORK_CODES", "FIXED_NETWORK_CODES"] # noqa: E501 - if object_type not in allowed_values: - raise ValueError( - "Invalid value for `object_type` ({0}), must be one of {1}" - .format(object_type, allowed_values) - ) - - self._object_type = object_type - - @property - def operation_type(self) -> str: - """Gets the operation_type of this FederationContextIdPartnerBody. - - - :return: The operation_type of this FederationContextIdPartnerBody. - :rtype: str - """ - return self._operation_type - - @operation_type.setter - def operation_type(self, operation_type: str): - """Sets the operation_type of this FederationContextIdPartnerBody. - - - :param operation_type: The operation_type of this FederationContextIdPartnerBody. - :type operation_type: str - """ - allowed_values = ["ADD_CODES", "REMOVE_CODES", "UPDATE_CODES"] # noqa: E501 - if operation_type not in allowed_values: - raise ValueError( - "Invalid value for `operation_type` ({0}), must be one of {1}" - .format(operation_type, allowed_values) - ) - - self._operation_type = operation_type - - @property - def add_mobile_network_ids(self) -> MobileNetworkIds: - """Gets the add_mobile_network_ids of this FederationContextIdPartnerBody. - - - :return: The add_mobile_network_ids of this FederationContextIdPartnerBody. - :rtype: MobileNetworkIds - """ - return self._add_mobile_network_ids - - @add_mobile_network_ids.setter - def add_mobile_network_ids(self, add_mobile_network_ids: MobileNetworkIds): - """Sets the add_mobile_network_ids of this FederationContextIdPartnerBody. - - - :param add_mobile_network_ids: The add_mobile_network_ids of this FederationContextIdPartnerBody. - :type add_mobile_network_ids: MobileNetworkIds - """ - - self._add_mobile_network_ids = add_mobile_network_ids - - @property - def remove_mobile_network_ids(self) -> MobileNetworkIds: - """Gets the remove_mobile_network_ids of this FederationContextIdPartnerBody. - - - :return: The remove_mobile_network_ids of this FederationContextIdPartnerBody. - :rtype: MobileNetworkIds - """ - return self._remove_mobile_network_ids - - @remove_mobile_network_ids.setter - def remove_mobile_network_ids(self, remove_mobile_network_ids: MobileNetworkIds): - """Sets the remove_mobile_network_ids of this FederationContextIdPartnerBody. - - - :param remove_mobile_network_ids: The remove_mobile_network_ids of this FederationContextIdPartnerBody. - :type remove_mobile_network_ids: MobileNetworkIds - """ - - self._remove_mobile_network_ids = remove_mobile_network_ids - - @property - def add_fixed_network_ids(self) -> FixedNetworkIds: - """Gets the add_fixed_network_ids of this FederationContextIdPartnerBody. - - - :return: The add_fixed_network_ids of this FederationContextIdPartnerBody. - :rtype: FixedNetworkIds - """ - return self._add_fixed_network_ids - - @add_fixed_network_ids.setter - def add_fixed_network_ids(self, add_fixed_network_ids: FixedNetworkIds): - """Sets the add_fixed_network_ids of this FederationContextIdPartnerBody. - - - :param add_fixed_network_ids: The add_fixed_network_ids of this FederationContextIdPartnerBody. - :type add_fixed_network_ids: FixedNetworkIds - """ - - self._add_fixed_network_ids = add_fixed_network_ids - - @property - def remove_fixed_network_ids(self) -> FixedNetworkIds: - """Gets the remove_fixed_network_ids of this FederationContextIdPartnerBody. - - - :return: The remove_fixed_network_ids of this FederationContextIdPartnerBody. - :rtype: FixedNetworkIds - """ - return self._remove_fixed_network_ids - - @remove_fixed_network_ids.setter - def remove_fixed_network_ids(self, remove_fixed_network_ids: FixedNetworkIds): - """Sets the remove_fixed_network_ids of this FederationContextIdPartnerBody. - - - :param remove_fixed_network_ids: The remove_fixed_network_ids of this FederationContextIdPartnerBody. - :type remove_fixed_network_ids: FixedNetworkIds - """ - - self._remove_fixed_network_ids = remove_fixed_network_ids - - @property - def modification_date(self) -> datetime: - """Gets the modification_date of this FederationContextIdPartnerBody. - - Date and time of the federation modification by the originating partner OP # noqa: E501 - - :return: The modification_date of this FederationContextIdPartnerBody. - :rtype: datetime - """ - return self._modification_date - - @modification_date.setter - def modification_date(self, modification_date: datetime): - """Sets the modification_date of this FederationContextIdPartnerBody. - - Date and time of the federation modification by the originating partner OP # noqa: E501 - - :param modification_date: The modification_date of this FederationContextIdPartnerBody. - :type modification_date: datetime - """ - if modification_date is None: - raise ValueError("Invalid value for `modification_date`, must not be `None`") # noqa: E501 - - self._modification_date = modification_date - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/federation_context_idapplicationlcm_zone_info.py b/src/models/federation_context_idapplicationlcm_zone_info.py deleted file mode 100644 index 624c7930b27d1696fe8799103094a691ce294f77..0000000000000000000000000000000000000000 --- a/src/models/federation_context_idapplicationlcm_zone_info.py +++ /dev/null @@ -1,179 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.flavour_id import FlavourId # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationContextIdapplicationlcmZoneInfo(Model): - def __init__(self, zone_id: ZoneIdentifier=None, flavour_id: FlavourId=None, resource_consumption: str='RESERVED_RES_AVOID', res_pool: str=None): # noqa: E501 - """FederationContextIdapplicationlcmZoneInfo - a model defined in Swagger - - :param zone_id: The zone_id of this FederationContextIdapplicationlcmZoneInfo. # noqa: E501 - :type zone_id: ZoneIdentifier - :param flavour_id: The flavour_id of this FederationContextIdapplicationlcmZoneInfo. # noqa: E501 - :type flavour_id: FlavourId - :param resource_consumption: The resource_consumption of this FederationContextIdapplicationlcmZoneInfo. # noqa: E501 - :type resource_consumption: str - :param res_pool: The res_pool of this FederationContextIdapplicationlcmZoneInfo. # noqa: E501 - :type res_pool: str - """ - self.swagger_types = { - 'zone_id': ZoneIdentifier, - 'flavour_id': FlavourId, - 'resource_consumption': str, - 'res_pool': str - } - - self.attribute_map = { - 'zone_id': 'zoneId', - 'flavour_id': 'flavourId', - 'resource_consumption': 'resourceConsumption', - 'res_pool': 'resPool' - } - self._zone_id = zone_id - self._flavour_id = flavour_id - self._resource_consumption = resource_consumption - self._res_pool = res_pool - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdapplicationlcmZoneInfo': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextIdapplicationlcm_zoneInfo of this FederationContextIdapplicationlcmZoneInfo. # noqa: E501 - :rtype: FederationContextIdapplicationlcmZoneInfo - """ - return util.deserialize_model(dikt, cls) - - @property - def zone_id(self) -> ZoneIdentifier: - """Gets the zone_id of this FederationContextIdapplicationlcmZoneInfo. - - - :return: The zone_id of this FederationContextIdapplicationlcmZoneInfo. - :rtype: ZoneIdentifier - """ - return self._zone_id - - @zone_id.setter - def zone_id(self, zone_id: ZoneIdentifier): - """Sets the zone_id of this FederationContextIdapplicationlcmZoneInfo. - - - :param zone_id: The zone_id of this FederationContextIdapplicationlcmZoneInfo. - :type zone_id: ZoneIdentifier - """ - if zone_id is None: - raise ValueError("Invalid value for `zone_id`, must not be `None`") # noqa: E501 - - if zone_id != "": - pattern = re.compile("^[A-Za-z0-9][A-Za-z0-9-]*$") - if not re.fullmatch(pattern, zone_id): - raise ValueError("'' does not match '^[A-Za-z0-9][A-Za-z0-9-]*$' - 'zoneInfo.zoneId'") - - self._zone_id = zone_id - - @property - def flavour_id(self) -> FlavourId: - """Gets the flavour_id of this FederationContextIdapplicationlcmZoneInfo. - - - :return: The flavour_id of this FederationContextIdapplicationlcmZoneInfo. - :rtype: FlavourId - """ - return self._flavour_id - - @flavour_id.setter - def flavour_id(self, flavour_id: FlavourId): - """Sets the flavour_id of this FederationContextIdapplicationlcmZoneInfo. - - - :param flavour_id: The flavour_id of this FederationContextIdapplicationlcmZoneInfo. - :type flavour_id: FlavourId - """ - if flavour_id is None: - raise ValueError("Invalid value for `flavour_id`, must not be `None`") # noqa: E501 - - self._flavour_id = flavour_id - - @property - def resource_consumption(self) -> str: - """Gets the resource_consumption of this FederationContextIdapplicationlcmZoneInfo. - - Specifies if the application can be instantiated using pre-reserved resource or not. App provider can pre-reserve a pool of compute resource on each zone. 'RESERVED_RES_SHALL' instruct OP to use only the pre-reserved resources. 'RESERVED_RES_PREFER' instruct to first try using pre-reserved resource, if none available go for non-reserved resources. 'RESERVED_RES_AVOID' instruct OP not to use pre-reserved resource if possible, it is a choice depending upon circumstances 'RESERVED_RES_FORBID' instruct OP not to use pre-reserved resources. # noqa: E501 - - :return: The resource_consumption of this FederationContextIdapplicationlcmZoneInfo. - :rtype: str - """ - return self._resource_consumption - - @resource_consumption.setter - def resource_consumption(self, resource_consumption: str): - """Sets the resource_consumption of this FederationContextIdapplicationlcmZoneInfo. - - Specifies if the application can be instantiated using pre-reserved resource or not. App provider can pre-reserve a pool of compute resource on each zone. 'RESERVED_RES_SHALL' instruct OP to use only the pre-reserved resources. 'RESERVED_RES_PREFER' instruct to first try using pre-reserved resource, if none available go for non-reserved resources. 'RESERVED_RES_AVOID' instruct OP not to use pre-reserved resource if possible, it is a choice depending upon circumstances 'RESERVED_RES_FORBID' instruct OP not to use pre-reserved resources. # noqa: E501 - - :param resource_consumption: The resource_consumption of this FederationContextIdapplicationlcmZoneInfo. - :type resource_consumption: str - """ - allowed_values = ["RESERVED_RES_SHALL", "RESERVED_RES_PREFER", "RESERVED_RES_AVOID", "RESERVED_RES_FORBID"] # noqa: E501 - if resource_consumption not in allowed_values: - raise ValueError( - "Invalid value for `resource_consumption` ({0}), must be one of {1}" - .format(resource_consumption, allowed_values) - ) - - self._resource_consumption = resource_consumption - - @property - def res_pool(self) -> str: - """Gets the res_pool of this FederationContextIdapplicationlcmZoneInfo. - - Resource pool to be used for application instantiation on this zone. Valid only if IE 'resourceConsumption' is set to 'RESERVED_RES_SHALL' or 'RESERVED_RES_PREFER' # noqa: E501 - - :return: The res_pool of this FederationContextIdapplicationlcmZoneInfo. - :rtype: str - """ - return self._res_pool - - @res_pool.setter - def res_pool(self, res_pool: str): - """Sets the res_pool of this FederationContextIdapplicationlcmZoneInfo. - - Resource pool to be used for application instantiation on this zone. Valid only if IE 'resourceConsumption' is set to 'RESERVED_RES_SHALL' or 'RESERVED_RES_PREFER' # noqa: E501 - - :param res_pool: The res_pool of this FederationContextIdapplicationlcmZoneInfo. - :type res_pool: str - """ - - self._res_pool = res_pool - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/federation_context_idapplicationlcmappapp_idapp_providerapp_provider_id_app_instance_info.py b/src/models/federation_context_idapplicationlcmappapp_idapp_providerapp_provider_id_app_instance_info.py deleted file mode 100644 index 3beadf58325fc378ec572b9f0d158d5071e0d838..0000000000000000000000000000000000000000 --- a/src/models/federation_context_idapplicationlcmappapp_idapp_providerapp_provider_id_app_instance_info.py +++ /dev/null @@ -1,105 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.instance_identifier import InstanceIdentifier # noqa: F401,E501 -from models.instance_state import InstanceState # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo(Model): - def __init__(self, app_inst_identifier: InstanceIdentifier=None, app_instance_state: InstanceState=None): # noqa: E501 - """FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo - a model defined in Swagger - - :param app_inst_identifier: The app_inst_identifier of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. # noqa: E501 - :type app_inst_identifier: InstanceIdentifier - :param app_instance_state: The app_instance_state of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. # noqa: E501 - :type app_instance_state: InstanceState - """ - self.swagger_types = { - 'app_inst_identifier': InstanceIdentifier, - 'app_instance_state': InstanceState - } - - self.attribute_map = { - 'app_inst_identifier': 'appInstIdentifier', - 'app_instance_state': 'appInstanceState' - } - self._app_inst_identifier = app_inst_identifier - self._app_instance_state = app_instance_state - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextIdapplicationlcmappappIdappProviderappProviderId_appInstanceInfo of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. # noqa: E501 - :rtype: FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo - """ - return util.deserialize_model(dikt, cls) - - @property - def app_inst_identifier(self) -> InstanceIdentifier: - """Gets the app_inst_identifier of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - - - :return: The app_inst_identifier of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - :rtype: InstanceIdentifier - """ - return self._app_inst_identifier - - @app_inst_identifier.setter - def app_inst_identifier(self, app_inst_identifier: InstanceIdentifier): - """Sets the app_inst_identifier of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - - - :param app_inst_identifier: The app_inst_identifier of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - :type app_inst_identifier: InstanceIdentifier - """ - if app_inst_identifier is None: - raise ValueError("Invalid value for `app_inst_identifier`, must not be `None`") # noqa: E501 - - self._app_inst_identifier = app_inst_identifier - - @property - def app_instance_state(self) -> InstanceState: - """Gets the app_instance_state of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - - - :return: The app_instance_state of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - :rtype: InstanceState - """ - return self._app_instance_state - - @app_instance_state.setter - def app_instance_state(self, app_instance_state: InstanceState): - """Sets the app_instance_state of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - - - :param app_instance_state: The app_instance_state of this FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo. - :type app_instance_state: InstanceState - """ - if app_instance_state is None: - raise ValueError("Invalid value for `app_instance_state`, must not be `None`") # noqa: E501 - - self._app_instance_state = app_instance_state diff --git a/src/models/federation_context_idapplicationonboardingappapp_id_app_component_specs.py b/src/models/federation_context_idapplicationonboardingappapp_id_app_component_specs.py deleted file mode 100644 index b7570881dd623962cc17664431b1f29f4c421a91..0000000000000000000000000000000000000000 --- a/src/models/federation_context_idapplicationonboardingappapp_id_app_component_specs.py +++ /dev/null @@ -1,160 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.artefact_id import ArtefactId # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationContextIdapplicationonboardingappappIdAppComponentSpecs(Model): - def __init__(self, service_name_nb: str=None, service_name_ew: str=None, component_name: str=None, artefact_id: ArtefactId=None): # noqa: E501 - """FederationContextIdapplicationonboardingappappIdAppComponentSpecs - a model defined in Swagger - - :param service_name_nb: The service_name_nb of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. # noqa: E501 - :type service_name_nb: str - :param service_name_ew: The service_name_ew of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. # noqa: E501 - :type service_name_ew: str - :param component_name: The component_name of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. # noqa: E501 - :type component_name: str - :param artefact_id: The artefact_id of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. # noqa: E501 - :type artefact_id: ArtefactId - """ - self.swagger_types = { - 'service_name_nb': str, - 'service_name_ew': str, - 'component_name': str, - 'artefact_id': ArtefactId - } - - self.attribute_map = { - 'service_name_nb': 'serviceNameNB', - 'service_name_ew': 'serviceNameEW', - 'component_name': 'componentName', - 'artefact_id': 'artefactId' - } - self._service_name_nb = service_name_nb - self._service_name_ew = service_name_ew - self._component_name = component_name - self._artefact_id = artefact_id - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdapplicationonboardingappappIdAppComponentSpecs': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextIdapplicationonboardingappappId_appComponentSpecs of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. # noqa: E501 - :rtype: FederationContextIdapplicationonboardingappappIdAppComponentSpecs - """ - return util.deserialize_model(dikt, cls) - - @property - def service_name_nb(self) -> str: - """Gets the service_name_nb of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed over NBI. Access via serviceNameNB is restricted on specific ports. Platform shall expose component access externally via this DNS name # noqa: E501 - - :return: The service_name_nb of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :rtype: str - """ - return self._service_name_nb - - @service_name_nb.setter - def service_name_nb(self, service_name_nb: str): - """Sets the service_name_nb of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed over NBI. Access via serviceNameNB is restricted on specific ports. Platform shall expose component access externally via this DNS name # noqa: E501 - - :param service_name_nb: The service_name_nb of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :type service_name_nb: str - """ - - self._service_name_nb = service_name_nb - - @property - def service_name_ew(self) -> str: - """Gets the service_name_ew of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed via peer components. Access via serviceNameEW is open on all ports. Platform shall not expose serviceNameEW externally outside edge. # noqa: E501 - - :return: The service_name_ew of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :rtype: str - """ - return self._service_name_ew - - @service_name_ew.setter - def service_name_ew(self, service_name_ew: str): - """Sets the service_name_ew of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. This defines the DNS name via which the component can be accessed via peer components. Access via serviceNameEW is open on all ports. Platform shall not expose serviceNameEW externally outside edge. # noqa: E501 - - :param service_name_ew: The service_name_ew of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :type service_name_ew: str - """ - - self._service_name_ew = service_name_ew - - @property - def component_name(self) -> str: - """Gets the component_name of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :return: The component_name of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :rtype: str - """ - return self._component_name - - @component_name.setter - def component_name(self, component_name: str): - """Sets the component_name of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - Must be a valid RFC 1035 label name. Component name must be unique with an application # noqa: E501 - - :param component_name: The component_name of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :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 artefact_id(self) -> ArtefactId: - """Gets the artefact_id of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - - :return: The artefact_id of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :rtype: ArtefactId - """ - return self._artefact_id - - @artefact_id.setter - def artefact_id(self, artefact_id: ArtefactId): - """Sets the artefact_id of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - - - :param artefact_id: The artefact_id of this FederationContextIdapplicationonboardingappappIdAppComponentSpecs. - :type artefact_id: ArtefactId - """ - - self._artefact_id = artefact_id diff --git a/src/models/federation_context_idapplicationonboardingappapp_id_app_upd_qo_s_profile.py b/src/models/federation_context_idapplicationonboardingappapp_id_app_upd_qo_s_profile.py deleted file mode 100644 index 54c0542efbdcc8f46107601b49cd9b69840a48cc..0000000000000000000000000000000000000000 --- a/src/models/federation_context_idapplicationonboardingappapp_id_app_upd_qo_s_profile.py +++ /dev/null @@ -1,233 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile(Model): - def __init__(self, latency_constraints: str=None, bandwidth_required: int=None, mobility_support: bool=False, multi_user_clients: str=None, no_of_users_per_app_inst: int=1, app_provisioning: bool=True): # noqa: E501 - """FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile - a model defined in Swagger - - :param latency_constraints: The latency_constraints of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type latency_constraints: str - :param bandwidth_required: The bandwidth_required of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type bandwidth_required: int - :param mobility_support: The mobility_support of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type mobility_support: bool - :param multi_user_clients: The multi_user_clients of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type multi_user_clients: str - :param no_of_users_per_app_inst: The no_of_users_per_app_inst of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type no_of_users_per_app_inst: int - :param app_provisioning: The app_provisioning of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :type app_provisioning: bool - """ - self.swagger_types = { - 'latency_constraints': str, - 'bandwidth_required': int, - 'mobility_support': bool, - 'multi_user_clients': str, - 'no_of_users_per_app_inst': int, - 'app_provisioning': bool - } - - self.attribute_map = { - 'latency_constraints': 'latencyConstraints', - 'bandwidth_required': 'bandwidthRequired', - 'mobility_support': 'mobilitySupport', - 'multi_user_clients': 'multiUserClients', - 'no_of_users_per_app_inst': 'noOfUsersPerAppInst', - 'app_provisioning': 'appProvisioning' - } - self._latency_constraints = latency_constraints - self._bandwidth_required = bandwidth_required - self._mobility_support = mobility_support - self._multi_user_clients = multi_user_clients - self._no_of_users_per_app_inst = no_of_users_per_app_inst - self._app_provisioning = app_provisioning - - @classmethod - def from_dict(cls, dikt) -> 'FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The federationContextIdapplicationonboardingappappId_appUpdQoSProfile of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. # noqa: E501 - :rtype: FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile - """ - return util.deserialize_model(dikt, cls) - - @property - def latency_constraints(self) -> str: - """Gets the latency_constraints of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Latency requirements for the application.Allowed values (non-standardized) are none, low and ultra-low. Ultra-Low may corresponds to range 15 - 30 msec, Low correspond to range 30 - 50 msec. None means 51 and above # noqa: E501 - - :return: The latency_constraints of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: str - """ - return self._latency_constraints - - @latency_constraints.setter - def latency_constraints(self, latency_constraints: str): - """Sets the latency_constraints of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Latency requirements for the application.Allowed values (non-standardized) are none, low and ultra-low. Ultra-Low may corresponds to range 15 - 30 msec, Low correspond to range 30 - 50 msec. None means 51 and above # noqa: E501 - - :param latency_constraints: The latency_constraints of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type latency_constraints: str - """ - allowed_values = ["NONE", "LOW", "ULTRALOW"] # noqa: E501 - if latency_constraints not in allowed_values: - raise ValueError( - "Invalid value for `latency_constraints` ({0}), must be one of {1}" - .format(latency_constraints, allowed_values) - ) - - self._latency_constraints = latency_constraints - - @property - def bandwidth_required(self) -> int: - """Gets the bandwidth_required of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Data transfer bandwidth requirement (minimum limit) for the application. It should in Mbits/sec # noqa: E501 - - :return: The bandwidth_required of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: int - """ - return self._bandwidth_required - - @bandwidth_required.setter - def bandwidth_required(self, bandwidth_required: int): - """Sets the bandwidth_required of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Data transfer bandwidth requirement (minimum limit) for the application. It should in Mbits/sec # noqa: E501 - - :param bandwidth_required: The bandwidth_required of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type bandwidth_required: int - """ - - self._bandwidth_required = bandwidth_required - - @property - def mobility_support(self) -> bool: - """Gets the mobility_support of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Indicates if an application is sensitive to user mobility and can be relocated. Default is “FALSE” # noqa: E501 - - :return: The mobility_support of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: bool - """ - return self._mobility_support - - @mobility_support.setter - def mobility_support(self, mobility_support: bool): - """Sets the mobility_support of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Indicates if an application is sensitive to user mobility and can be relocated. Default is “FALSE” # noqa: E501 - - :param mobility_support: The mobility_support of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type mobility_support: bool - """ - - self._mobility_support = mobility_support - - @property - def multi_user_clients(self) -> str: - """Gets the multi_user_clients of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Single user type application are designed to serve just one client. Multi user type application is designed to serve multiple clients # noqa: E501 - - :return: The multi_user_clients of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: str - """ - return self._multi_user_clients - - @multi_user_clients.setter - def multi_user_clients(self, multi_user_clients: str): - """Sets the multi_user_clients of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Single user type application are designed to serve just one client. Multi user type application is designed to serve multiple clients # noqa: E501 - - :param multi_user_clients: The multi_user_clients of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type multi_user_clients: str - """ - allowed_values = ["APP_TYPE_SINGLE_USER", "APP_TYPE_MULTI_USER"] # noqa: E501 - if multi_user_clients not in allowed_values: - raise ValueError( - "Invalid value for `multi_user_clients` ({0}), must be one of {1}" - .format(multi_user_clients, allowed_values) - ) - - self._multi_user_clients = multi_user_clients - - @property - def no_of_users_per_app_inst(self) -> int: - """Gets the no_of_users_per_app_inst of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Maximum no of clients that can connect to an instance of this application. This parameter is relevant only for application of type multi user # noqa: E501 - - :return: The no_of_users_per_app_inst of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: int - """ - return self._no_of_users_per_app_inst - - @no_of_users_per_app_inst.setter - def no_of_users_per_app_inst(self, no_of_users_per_app_inst: int): - """Sets the no_of_users_per_app_inst of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Maximum no of clients that can connect to an instance of this application. This parameter is relevant only for application of type multi user # noqa: E501 - - :param no_of_users_per_app_inst: The no_of_users_per_app_inst of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type no_of_users_per_app_inst: int - """ - - self._no_of_users_per_app_inst = no_of_users_per_app_inst - - @property - def app_provisioning(self) -> bool: - """Gets the app_provisioning of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Define if application can be instantiated or not # noqa: E501 - - :return: The app_provisioning of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :rtype: bool - """ - return self._app_provisioning - - @app_provisioning.setter - def app_provisioning(self, app_provisioning: bool): - """Sets the app_provisioning of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - - Define if application can be instantiated or not # noqa: E501 - - :param app_provisioning: The app_provisioning of this FederationContextIdapplicationonboardingappappIdAppUpdQoSProfile. - :type app_provisioning: bool - """ - - self._app_provisioning = app_provisioning - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/federation_identifier.py b/src/models/federation_identifier.py deleted file mode 100644 index 551c76fba105fe7c6f5fe334df1c1c87042663ed..0000000000000000000000000000000000000000 --- a/src/models/federation_identifier.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FederationIdentifier(Model): - def __init__(self): # noqa: E501 - """FederationIdentifier - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'FederationIdentifier': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FederationIdentifier of this FederationIdentifier. # noqa: E501 - :rtype: FederationIdentifier - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/federation_request_data.py b/src/models/federation_request_data.py deleted file mode 100644 index 6637c10282dca1be3659e847d5aca33eff8078a7..0000000000000000000000000000000000000000 --- a/src/models/federation_request_data.py +++ /dev/null @@ -1,256 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.callback_credentials import CallbackCredentials # noqa: F401,E501 -from models.country_code import CountryCode # noqa: F401,E501 -from models.federation_identifier import FederationIdentifier # noqa: F401,E501 -from models.fixed_network_ids import FixedNetworkIds # noqa: F401,E501 -from models.mobile_network_ids import MobileNetworkIds # noqa: F401,E501 -from models.uri import Uri # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationRequestData(Model): - def __init__(self, orig_op_federation_id: FederationIdentifier=None, orig_op_country_code: CountryCode=None, orig_op_mobile_network_codes: MobileNetworkIds=None, orig_op_fixed_network_codes: FixedNetworkIds=None, initial_date: datetime=None, partner_status_link: Uri=None, partner_callback_credentials: CallbackCredentials=None): # noqa: E501 - """FederationRequestData - a model defined in Swagger - - :param orig_op_federation_id: The orig_op_federation_id of this FederationRequestData. # noqa: E501 - :type orig_op_federation_id: FederationIdentifier - :param orig_op_country_code: The orig_op_country_code of this FederationRequestData. # noqa: E501 - :type orig_op_country_code: CountryCode - :param orig_op_mobile_network_codes: The orig_op_mobile_network_codes of this FederationRequestData. # noqa: E501 - :type orig_op_mobile_network_codes: MobileNetworkIds - :param orig_op_fixed_network_codes: The orig_op_fixed_network_codes of this FederationRequestData. # noqa: E501 - :type orig_op_fixed_network_codes: FixedNetworkIds - :param initial_date: The initial_date of this FederationRequestData. # noqa: E501 - :type initial_date: datetime - :param partner_status_link: The partner_status_link of this FederationRequestData. # noqa: E501 - :type partner_status_link: Uri - :param partner_callback_credentials: The partner_callback_credentials of this FederationRequestData. # noqa: E501 - :type partner_callback_credentials: CallbackCredentials - """ - self.swagger_types = { - 'orig_op_federation_id': FederationIdentifier, - 'orig_op_country_code': CountryCode, - 'orig_op_mobile_network_codes': MobileNetworkIds, - 'orig_op_fixed_network_codes': FixedNetworkIds, - 'initial_date': datetime, - 'partner_status_link': Uri, - 'partner_callback_credentials': CallbackCredentials - } - - self.attribute_map = { - 'orig_op_federation_id': 'origOPFederationId', - 'orig_op_country_code': 'origOPCountryCode', - 'orig_op_mobile_network_codes': 'origOPMobileNetworkCodes', - 'orig_op_fixed_network_codes': 'origOPFixedNetworkCodes', - 'initial_date': 'initialDate', - 'partner_status_link': 'partnerStatusLink', - 'partner_callback_credentials': 'partnerCallbackCredentials' - } - self._orig_op_federation_id = orig_op_federation_id - self._orig_op_country_code = orig_op_country_code - self._orig_op_mobile_network_codes = orig_op_mobile_network_codes - self._orig_op_fixed_network_codes = orig_op_fixed_network_codes - self._initial_date = initial_date - self._partner_status_link = partner_status_link - self._partner_callback_credentials = partner_callback_credentials - - @classmethod - def from_dict(cls, dikt) -> 'FederationRequestData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FederationRequestData of this FederationRequestData. # noqa: E501 - :rtype: FederationRequestData - """ - return util.deserialize_model(dikt, cls) - - @property - def orig_op_federation_id(self) -> FederationIdentifier: - """Gets the orig_op_federation_id of this FederationRequestData. - - - :return: The orig_op_federation_id of this FederationRequestData. - :rtype: FederationIdentifier - """ - return self._orig_op_federation_id - - @orig_op_federation_id.setter - def orig_op_federation_id(self, orig_op_federation_id: FederationIdentifier): - """Sets the orig_op_federation_id of this FederationRequestData. - - - :param orig_op_federation_id: The orig_op_federation_id of this FederationRequestData. - :type orig_op_federation_id: FederationIdentifier - """ - self._orig_op_federation_id = orig_op_federation_id - - @property - def orig_op_country_code(self) -> CountryCode: - """Gets the orig_op_country_code of this FederationRequestData. - - - :return: The orig_op_country_code of this FederationRequestData. - :rtype: CountryCode - """ - return self._orig_op_country_code - - @orig_op_country_code.setter - def orig_op_country_code(self, orig_op_country_code: CountryCode): - """Sets the orig_op_country_code of this FederationRequestData. - - - :param orig_op_country_code: The orig_op_country_code of this FederationRequestData. - :type orig_op_country_code: CountryCode - """ - - self._orig_op_country_code = orig_op_country_code - - @property - def orig_op_mobile_network_codes(self) -> MobileNetworkIds: - """Gets the orig_op_mobile_network_codes of this FederationRequestData. - - - :return: The orig_op_mobile_network_codes of this FederationRequestData. - :rtype: MobileNetworkIds - """ - return self._orig_op_mobile_network_codes - - @orig_op_mobile_network_codes.setter - def orig_op_mobile_network_codes(self, orig_op_mobile_network_codes: MobileNetworkIds): - """Sets the orig_op_mobile_network_codes of this FederationRequestData. - - - :param orig_op_mobile_network_codes: The orig_op_mobile_network_codes of this FederationRequestData. - :type orig_op_mobile_network_codes: MobileNetworkIds - """ - - self._orig_op_mobile_network_codes = orig_op_mobile_network_codes - - @property - def orig_op_fixed_network_codes(self) -> FixedNetworkIds: - """Gets the orig_op_fixed_network_codes of this FederationRequestData. - - - :return: The orig_op_fixed_network_codes of this FederationRequestData. - :rtype: FixedNetworkIds - """ - return self._orig_op_fixed_network_codes - - @orig_op_fixed_network_codes.setter - def orig_op_fixed_network_codes(self, orig_op_fixed_network_codes: FixedNetworkIds): - """Sets the orig_op_fixed_network_codes of this FederationRequestData. - - - :param orig_op_fixed_network_codes: The orig_op_fixed_network_codes of this FederationRequestData. - :type orig_op_fixed_network_codes: FixedNetworkIds - """ - - self._orig_op_fixed_network_codes = orig_op_fixed_network_codes - - @property - def initial_date(self) -> datetime: - """Gets the initial_date of this FederationRequestData. - - Time zone info of the federation initiated by the originating OP # noqa: E501 - - :return: The initial_date of this FederationRequestData. - :rtype: datetime - """ - return self._initial_date - - @initial_date.setter - def initial_date(self, initial_date: datetime): - """Sets the initial_date of this FederationRequestData. - - Time zone info of the federation initiated by the originating OP # noqa: E501 - - :param initial_date: The initial_date of this FederationRequestData. - :type initial_date: datetime - """ - if initial_date is None: - raise ValueError("Invalid value for `initial_date`, must not be `None`") # noqa: E501 - - self._initial_date = initial_date - - @property - def partner_status_link(self) -> Uri: - """Gets the partner_status_link of this FederationRequestData. - - - :return: The partner_status_link of this FederationRequestData. - :rtype: Uri - """ - return self._partner_status_link - - @partner_status_link.setter - def partner_status_link(self, partner_status_link: Uri): - """Sets the partner_status_link of this FederationRequestData. - - - :param partner_status_link: The partner_status_link of this FederationRequestData. - :type partner_status_link: Uri - """ - if partner_status_link is None: - raise ValueError("Invalid value for `partner_status_link`, must not be `None`") # noqa: E501 - - self._partner_status_link = partner_status_link - - @property - def partner_callback_credentials(self) -> CallbackCredentials: - """Gets the partner_callback_credentials of this FederationRequestData. - - - :return: The partner_callback_credentials of this FederationRequestData. - :rtype: CallbackCredentials - """ - return self._partner_callback_credentials - - @partner_callback_credentials.setter - def partner_callback_credentials(self, partner_callback_credentials: CallbackCredentials): - """Sets the partner_callback_credentials of this FederationRequestData. - - - :param partner_callback_credentials: The partner_callback_credentials of this FederationRequestData. - :type partner_callback_credentials: CallbackCredentials - """ - - self._partner_callback_credentials = partner_callback_credentials - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/federation_response_data.py b/src/models/federation_response_data.py deleted file mode 100644 index b68a6a483757db501a306554c305b4effc8136b7..0000000000000000000000000000000000000000 --- a/src/models/federation_response_data.py +++ /dev/null @@ -1,298 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.country_code import CountryCode # noqa: F401,E501 -from models.federation_context_id import FederationContextId # noqa: F401,E501 -from models.federation_identifier import FederationIdentifier # noqa: F401,E501 -from models.fixed_network_ids import FixedNetworkIds # noqa: F401,E501 -from models.mobile_network_ids import MobileNetworkIds # noqa: F401,E501 -from models.service_endpoint import ServiceEndpoint # noqa: F401,E501 -from models.zone_details import ZoneDetails # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class FederationResponseData(Model): - def __init__(self, partner_op_federation_id: FederationIdentifier=None, partner_op_country_code: CountryCode=None, federation_context_id: FederationContextId=None, edge_discovery_service_end_point: ServiceEndpoint=None, lcm_service_end_point: ServiceEndpoint=None, partner_op_mobile_network_codes: MobileNetworkIds=None, partner_op_fixed_network_codes: FixedNetworkIds=None, offered_availability_zones: List[ZoneDetails]=None, platform_caps: List[str]=None): # noqa: E501 - """FederationResponseData - a model defined in Swagger - - :param partner_op_federation_id: The partner_op_federation_id of this FederationResponseData. # noqa: E501 - :type partner_op_federation_id: FederationIdentifier - :param partner_op_country_code: The partner_op_country_code of this FederationResponseData. # noqa: E501 - :type partner_op_country_code: CountryCode - :param federation_context_id: The federation_context_id of this FederationResponseData. # noqa: E501 - :type federation_context_id: FederationContextId - :param edge_discovery_service_end_point: The edge_discovery_service_end_point of this FederationResponseData. # noqa: E501 - :type edge_discovery_service_end_point: ServiceEndpoint - :param lcm_service_end_point: The lcm_service_end_point of this FederationResponseData. # noqa: E501 - :type lcm_service_end_point: ServiceEndpoint - :param partner_op_mobile_network_codes: The partner_op_mobile_network_codes of this FederationResponseData. # noqa: E501 - :type partner_op_mobile_network_codes: MobileNetworkIds - :param partner_op_fixed_network_codes: The partner_op_fixed_network_codes of this FederationResponseData. # noqa: E501 - :type partner_op_fixed_network_codes: FixedNetworkIds - :param offered_availability_zones: The offered_availability_zones of this FederationResponseData. # noqa: E501 - :type offered_availability_zones: List[ZoneDetails] - :param platform_caps: The platform_caps of this FederationResponseData. # noqa: E501 - :type platform_caps: List[str] - """ - self.swagger_types = { - 'partner_op_federation_id': FederationIdentifier, - 'partner_op_country_code': CountryCode, - 'federation_context_id': FederationContextId, - 'edge_discovery_service_end_point': ServiceEndpoint, - 'lcm_service_end_point': ServiceEndpoint, - 'partner_op_mobile_network_codes': MobileNetworkIds, - 'partner_op_fixed_network_codes': FixedNetworkIds, - 'offered_availability_zones': List[ZoneDetails], - 'platform_caps': List[str] - } - - self.attribute_map = { - 'partner_op_federation_id': 'partnerOPFederationId', - 'partner_op_country_code': 'partnerOPCountryCode', - 'federation_context_id': 'federationContextId', - 'edge_discovery_service_end_point': 'edgeDiscoveryServiceEndPoint', - 'lcm_service_end_point': 'lcmServiceEndPoint', - 'partner_op_mobile_network_codes': 'partnerOPMobileNetworkCodes', - 'partner_op_fixed_network_codes': 'partnerOPFixedNetworkCodes', - 'offered_availability_zones': 'offeredAvailabilityZones', - 'platform_caps': 'platformCaps' - } - self._partner_op_federation_id = partner_op_federation_id - self._partner_op_country_code = partner_op_country_code - self._federation_context_id = federation_context_id - self._edge_discovery_service_end_point = edge_discovery_service_end_point - self._lcm_service_end_point = lcm_service_end_point - self._partner_op_mobile_network_codes = partner_op_mobile_network_codes - self._partner_op_fixed_network_codes = partner_op_fixed_network_codes - self._offered_availability_zones = offered_availability_zones - self._platform_caps = platform_caps - - @classmethod - def from_dict(cls, dikt) -> 'FederationResponseData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FederationResponseData of this FederationResponseData. # noqa: E501 - :rtype: FederationResponseData - """ - return util.deserialize_model(dikt, cls) - - @property - def partner_op_federation_id(self) -> FederationIdentifier: - """Gets the partner_op_federation_id of this FederationResponseData. - - - :return: The partner_op_federation_id of this FederationResponseData. - :rtype: FederationIdentifier - """ - return self._partner_op_federation_id - - @partner_op_federation_id.setter - def partner_op_federation_id(self, partner_op_federation_id: FederationIdentifier): - """Sets the partner_op_federation_id of this FederationResponseData. - - - :param partner_op_federation_id: The partner_op_federation_id of this FederationResponseData. - :type partner_op_federation_id: FederationIdentifier - """ - self._partner_op_federation_id = partner_op_federation_id - - @property - def partner_op_country_code(self) -> CountryCode: - """Gets the partner_op_country_code of this FederationResponseData. - - - :return: The partner_op_country_code of this FederationResponseData. - :rtype: CountryCode - """ - return self._partner_op_country_code - - @partner_op_country_code.setter - def partner_op_country_code(self, partner_op_country_code: CountryCode): - """Sets the partner_op_country_code of this FederationResponseData. - - - :param partner_op_country_code: The partner_op_country_code of this FederationResponseData. - :type partner_op_country_code: CountryCode - """ - - self._partner_op_country_code = partner_op_country_code - - @property - def federation_context_id(self) -> FederationContextId: - """Gets the federation_context_id of this FederationResponseData. - - - :return: The federation_context_id of this FederationResponseData. - :rtype: FederationContextId - """ - return self._federation_context_id - - @federation_context_id.setter - def federation_context_id(self, federation_context_id: FederationContextId): - """Sets the federation_context_id of this FederationResponseData. - - - :param federation_context_id: The federation_context_id of this FederationResponseData. - :type federation_context_id: FederationContextId - """ - if federation_context_id is None: - raise ValueError("Invalid value for `federation_context_id`, must not be `None`") # noqa: E501 - - self._federation_context_id = federation_context_id - - @property - def edge_discovery_service_end_point(self) -> ServiceEndpoint: - """Gets the edge_discovery_service_end_point of this FederationResponseData. - - - :return: The edge_discovery_service_end_point of this FederationResponseData. - :rtype: ServiceEndpoint - """ - return self._edge_discovery_service_end_point - - @edge_discovery_service_end_point.setter - def edge_discovery_service_end_point(self, edge_discovery_service_end_point: ServiceEndpoint): - """Sets the edge_discovery_service_end_point of this FederationResponseData. - - - :param edge_discovery_service_end_point: The edge_discovery_service_end_point of this FederationResponseData. - :type edge_discovery_service_end_point: ServiceEndpoint - """ - - self._edge_discovery_service_end_point = edge_discovery_service_end_point - - @property - def lcm_service_end_point(self) -> ServiceEndpoint: - """Gets the lcm_service_end_point of this FederationResponseData. - - - :return: The lcm_service_end_point of this FederationResponseData. - :rtype: ServiceEndpoint - """ - return self._lcm_service_end_point - - @lcm_service_end_point.setter - def lcm_service_end_point(self, lcm_service_end_point: ServiceEndpoint): - """Sets the lcm_service_end_point of this FederationResponseData. - - - :param lcm_service_end_point: The lcm_service_end_point of this FederationResponseData. - :type lcm_service_end_point: ServiceEndpoint - """ - - self._lcm_service_end_point = lcm_service_end_point - - @property - def partner_op_mobile_network_codes(self) -> MobileNetworkIds: - """Gets the partner_op_mobile_network_codes of this FederationResponseData. - - - :return: The partner_op_mobile_network_codes of this FederationResponseData. - :rtype: MobileNetworkIds - """ - return self._partner_op_mobile_network_codes - - @partner_op_mobile_network_codes.setter - def partner_op_mobile_network_codes(self, partner_op_mobile_network_codes: MobileNetworkIds): - """Sets the partner_op_mobile_network_codes of this FederationResponseData. - - - :param partner_op_mobile_network_codes: The partner_op_mobile_network_codes of this FederationResponseData. - :type partner_op_mobile_network_codes: MobileNetworkIds - """ - - self._partner_op_mobile_network_codes = partner_op_mobile_network_codes - - @property - def partner_op_fixed_network_codes(self) -> FixedNetworkIds: - """Gets the partner_op_fixed_network_codes of this FederationResponseData. - - - :return: The partner_op_fixed_network_codes of this FederationResponseData. - :rtype: FixedNetworkIds - """ - return self._partner_op_fixed_network_codes - - @partner_op_fixed_network_codes.setter - def partner_op_fixed_network_codes(self, partner_op_fixed_network_codes: FixedNetworkIds): - """Sets the partner_op_fixed_network_codes of this FederationResponseData. - - - :param partner_op_fixed_network_codes: The partner_op_fixed_network_codes of this FederationResponseData. - :type partner_op_fixed_network_codes: FixedNetworkIds - """ - - self._partner_op_fixed_network_codes = partner_op_fixed_network_codes - - @property - def offered_availability_zones(self) -> List[ZoneDetails]: - """Gets the offered_availability_zones of this FederationResponseData. - - List of zones, which the operator platform wishes to make available to developers/ISVs of requesting operator platform. # noqa: E501 - - :return: The offered_availability_zones of this FederationResponseData. - :rtype: List[ZoneDetails] - """ - return self._offered_availability_zones - - @offered_availability_zones.setter - def offered_availability_zones(self, offered_availability_zones: List[ZoneDetails]): - """Sets the offered_availability_zones of this FederationResponseData. - - List of zones, which the operator platform wishes to make available to developers/ISVs of requesting operator platform. # noqa: E501 - - :param offered_availability_zones: The offered_availability_zones of this FederationResponseData. - :type offered_availability_zones: List[ZoneDetails] - """ - - self._offered_availability_zones = offered_availability_zones - - @property - def platform_caps(self) -> List[str]: - """Gets the platform_caps of this FederationResponseData. - - - :return: The platform_caps of this FederationResponseData. - :rtype: List[str] - """ - return self._platform_caps - - @platform_caps.setter - def platform_caps(self, platform_caps: List[str]): - """Sets the platform_caps of this FederationResponseData. - - - :param platform_caps: The platform_caps of this FederationResponseData. - :type platform_caps: List[str] - """ - allowed_values = ["homeRouting", "Anchoring", "serviceAPIs", "faultMgmt", "eventMgmt", "resourceMonitor"] # noqa: E501 - if not set(platform_caps).issubset(set(allowed_values)): - raise ValueError( - "Invalid values for `platform_caps` [{0}], must be a subset of [{1}]" # noqa: E501 - .format(", ".join(map(str, set(platform_caps) - set(allowed_values))), # noqa: E501 - ", ".join(map(str, allowed_values))) - ) - - self._platform_caps = platform_caps diff --git a/src/models/file_id.py b/src/models/file_id.py deleted file mode 100644 index b658a7e4c36499bfcfc3a0987dbbd67c6a8a54cf..0000000000000000000000000000000000000000 --- a/src/models/file_id.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FileId(Model): - def __init__(self): # noqa: E501 - """FileId - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'FileId': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FileId of this FileId. # noqa: E501 - :rtype: FileId - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/fixed_network_ids.py b/src/models/fixed_network_ids.py deleted file mode 100644 index da01a421be5a2f19b2b2ec7da447a58780d98ed4..0000000000000000000000000000000000000000 --- a/src/models/fixed_network_ids.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FixedNetworkIds(Model): - def __init__(self): # noqa: E501 - """FixedNetworkIds - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'FixedNetworkIds': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FixedNetworkIds of this FixedNetworkIds. # noqa: E501 - :rtype: FixedNetworkIds - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/flavour.py b/src/models/flavour.py deleted file mode 100644 index 5e610cdb3e0bc3ac996faa1583aaf735977b27c6..0000000000000000000000000000000000000000 --- a/src/models/flavour.py +++ /dev/null @@ -1,363 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.cpu_arch_type import CPUArchType # noqa: F401,E501 -from models.flavour_id import FlavourId # noqa: F401,E501 -from models.gpu_info import GpuInfo # noqa: F401,E501 -from models.huge_page import HugePage # noqa: F401,E501 -from models.os_type import OSType # noqa: F401,E501 -import util - - -class Flavour(Model): - def __init__(self, flavour_id: FlavourId=None, cpu_arch_type: CPUArchType=None, supported_os_types: List[OSType]=None, num_cpu: int=None, memory_size: int=None, storage_size: int=None, gpu: List[GpuInfo]=None, fpga: int=None, vpu: int=None, hugepages: List[HugePage]=None, cpu_exclusivity: bool=None): # noqa: E501 - """Flavour - a model defined in Swagger - - :param flavour_id: The flavour_id of this Flavour. # noqa: E501 - :type flavour_id: FlavourId - :param cpu_arch_type: The cpu_arch_type of this Flavour. # noqa: E501 - :type cpu_arch_type: CPUArchType - :param supported_os_types: The supported_os_types of this Flavour. # noqa: E501 - :type supported_os_types: List[OSType] - :param num_cpu: The num_cpu of this Flavour. # noqa: E501 - :type num_cpu: int - :param memory_size: The memory_size of this Flavour. # noqa: E501 - :type memory_size: int - :param storage_size: The storage_size of this Flavour. # noqa: E501 - :type storage_size: int - :param gpu: The gpu of this Flavour. # noqa: E501 - :type gpu: List[GpuInfo] - :param fpga: The fpga of this Flavour. # noqa: E501 - :type fpga: int - :param vpu: The vpu of this Flavour. # noqa: E501 - :type vpu: int - :param hugepages: The hugepages of this Flavour. # noqa: E501 - :type hugepages: List[HugePage] - :param cpu_exclusivity: The cpu_exclusivity of this Flavour. # noqa: E501 - :type cpu_exclusivity: bool - """ - self.swagger_types = { - 'flavour_id': FlavourId, - 'cpu_arch_type': CPUArchType, - 'supported_os_types': List[OSType], - 'num_cpu': int, - 'memory_size': int, - 'storage_size': int, - 'gpu': List[GpuInfo], - 'fpga': int, - 'vpu': int, - 'hugepages': List[HugePage], - 'cpu_exclusivity': bool - } - - self.attribute_map = { - 'flavour_id': 'flavourId', - 'cpu_arch_type': 'cpuArchType', - 'supported_os_types': 'supportedOSTypes', - 'num_cpu': 'numCPU', - 'memory_size': 'memorySize', - 'storage_size': 'storageSize', - 'gpu': 'gpu', - 'fpga': 'fpga', - 'vpu': 'vpu', - 'hugepages': 'hugepages', - 'cpu_exclusivity': 'cpuExclusivity' - } - self._flavour_id = flavour_id - self._cpu_arch_type = cpu_arch_type - self._supported_os_types = supported_os_types - self._num_cpu = num_cpu - self._memory_size = memory_size - self._storage_size = storage_size - self._gpu = gpu - self._fpga = fpga - self._vpu = vpu - self._hugepages = hugepages - self._cpu_exclusivity = cpu_exclusivity - - @classmethod - def from_dict(cls, dikt) -> 'Flavour': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Flavour of this Flavour. # noqa: E501 - :rtype: Flavour - """ - return util.deserialize_model(dikt, cls) - - @property - def flavour_id(self) -> FlavourId: - """Gets the flavour_id of this Flavour. - - - :return: The flavour_id of this Flavour. - :rtype: FlavourId - """ - return self._flavour_id - - @flavour_id.setter - def flavour_id(self, flavour_id: FlavourId): - """Sets the flavour_id of this Flavour. - - - :param flavour_id: The flavour_id of this Flavour. - :type flavour_id: FlavourId - """ - if flavour_id is None: - raise ValueError("Invalid value for `flavour_id`, must not be `None`") # noqa: E501 - - self._flavour_id = flavour_id - - @property - def cpu_arch_type(self) -> CPUArchType: - """Gets the cpu_arch_type of this Flavour. - - - :return: The cpu_arch_type of this Flavour. - :rtype: CPUArchType - """ - return self._cpu_arch_type - - @cpu_arch_type.setter - def cpu_arch_type(self, cpu_arch_type: CPUArchType): - """Sets the cpu_arch_type of this Flavour. - - - :param cpu_arch_type: The cpu_arch_type of this Flavour. - :type cpu_arch_type: CPUArchType - """ - if cpu_arch_type is None: - raise ValueError("Invalid value for `cpu_arch_type`, must not be `None`") # noqa: E501 - - self._cpu_arch_type = cpu_arch_type - - @property - def supported_os_types(self) -> List[OSType]: - """Gets the supported_os_types of this Flavour. - - A list of operating systems which this flavour configuration can support e.g., RHEL Linux, Ubuntu 18.04 LTS, MS Windows 2012 R2. # noqa: E501 - - :return: The supported_os_types of this Flavour. - :rtype: List[OSType] - """ - return self._supported_os_types - - @supported_os_types.setter - def supported_os_types(self, supported_os_types: List[OSType]): - """Sets the supported_os_types of this Flavour. - - A list of operating systems which this flavour configuration can support e.g., RHEL Linux, Ubuntu 18.04 LTS, MS Windows 2012 R2. # noqa: E501 - - :param supported_os_types: The supported_os_types of this Flavour. - :type supported_os_types: List[OSType] - """ - if supported_os_types is None: - raise ValueError("Invalid value for `supported_os_types`, must not be `None`") # noqa: E501 - - self._supported_os_types = supported_os_types - - @property - def num_cpu(self) -> int: - """Gets the num_cpu of this Flavour. - - Number of available vCPUs # noqa: E501 - - :return: The num_cpu of this Flavour. - :rtype: int - """ - return self._num_cpu - - @num_cpu.setter - def num_cpu(self, num_cpu: int): - """Sets the num_cpu of this Flavour. - - Number of available vCPUs # noqa: E501 - - :param num_cpu: The num_cpu of this Flavour. - :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_size(self) -> int: - """Gets the memory_size of this Flavour. - - Amount of RAM in Mbytes # noqa: E501 - - :return: The memory_size of this Flavour. - :rtype: int - """ - return self._memory_size - - @memory_size.setter - def memory_size(self, memory_size: int): - """Sets the memory_size of this Flavour. - - Amount of RAM in Mbytes # noqa: E501 - - :param memory_size: The memory_size of this Flavour. - :type memory_size: int - """ - if memory_size is None: - raise ValueError("Invalid value for `memory_size`, must not be `None`") # noqa: E501 - - self._memory_size = memory_size - - @property - def storage_size(self) -> int: - """Gets the storage_size of this Flavour. - - Amount of disk storage in Gbytes # noqa: E501 - - :return: The storage_size of this Flavour. - :rtype: int - """ - return self._storage_size - - @storage_size.setter - def storage_size(self, storage_size: int): - """Sets the storage_size of this Flavour. - - Amount of disk storage in Gbytes # noqa: E501 - - :param storage_size: The storage_size of this Flavour. - :type storage_size: int - """ - if storage_size is None: - raise ValueError("Invalid value for `storage_size`, must not be `None`") # noqa: E501 - - self._storage_size = storage_size - - @property - def gpu(self) -> List[GpuInfo]: - """Gets the gpu of this Flavour. - - - :return: The gpu of this Flavour. - :rtype: List[GpuInfo] - """ - return self._gpu - - @gpu.setter - def gpu(self, gpu: List[GpuInfo]): - """Sets the gpu of this Flavour. - - - :param gpu: The gpu of this Flavour. - :type gpu: List[GpuInfo] - """ - - self._gpu = gpu - - @property - def fpga(self) -> int: - """Gets the fpga of this Flavour. - - Number of FPGAs # noqa: E501 - - :return: The fpga of this Flavour. - :rtype: int - """ - return self._fpga - - @fpga.setter - def fpga(self, fpga: int): - """Sets the fpga of this Flavour. - - Number of FPGAs # noqa: E501 - - :param fpga: The fpga of this Flavour. - :type fpga: int - """ - - self._fpga = fpga - - @property - def vpu(self) -> int: - """Gets the vpu of this Flavour. - - Number of Intel VPUs available # noqa: E501 - - :return: The vpu of this Flavour. - :rtype: int - """ - return self._vpu - - @vpu.setter - def vpu(self, vpu: int): - """Sets the vpu of this Flavour. - - Number of Intel VPUs available # noqa: E501 - - :param vpu: The vpu of this Flavour. - :type vpu: int - """ - - self._vpu = vpu - - @property - def hugepages(self) -> List[HugePage]: - """Gets the hugepages of this Flavour. - - - :return: The hugepages of this Flavour. - :rtype: List[HugePage] - """ - return self._hugepages - - @hugepages.setter - def hugepages(self, hugepages: List[HugePage]): - """Sets the hugepages of this Flavour. - - - :param hugepages: The hugepages of this Flavour. - :type hugepages: List[HugePage] - """ - - self._hugepages = hugepages - - @property - def cpu_exclusivity(self) -> bool: - """Gets the cpu_exclusivity of this Flavour. - - Support for exclusive CPUs # noqa: E501 - - :return: The cpu_exclusivity of this Flavour. - :rtype: bool - """ - return self._cpu_exclusivity - - @cpu_exclusivity.setter - def cpu_exclusivity(self, cpu_exclusivity: bool): - """Sets the cpu_exclusivity of this Flavour. - - Support for exclusive CPUs # noqa: E501 - - :param cpu_exclusivity: The cpu_exclusivity of this Flavour. - :type cpu_exclusivity: bool - """ - - self._cpu_exclusivity = cpu_exclusivity diff --git a/src/models/flavour_id.py b/src/models/flavour_id.py deleted file mode 100644 index aa7ee5bb9160880a93ba93d7a55f18500dc616e0..0000000000000000000000000000000000000000 --- a/src/models/flavour_id.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class FlavourId(Model): - def __init__(self): # noqa: E501 - """FlavourId - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'FlavourId': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The FlavourId of this FlavourId. # noqa: E501 - :rtype: FlavourId - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/fqdn.py b/src/models/fqdn.py deleted file mode 100644 index 8f24990720d51f78ddf97780eeb61c1757483f82..0000000000000000000000000000000000000000 --- a/src/models/fqdn.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Fqdn(Model): - 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/src/models/geo_location.py b/src/models/geo_location.py deleted file mode 100644 index 528d3feba56b1cb9fe36e237676d573883186317..0000000000000000000000000000000000000000 --- a/src/models/geo_location.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class GeoLocation(Model): - def __init__(self): # noqa: E501 - """GeoLocation - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'GeoLocation': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The GeoLocation of this GeoLocation. # noqa: E501 - :rtype: GeoLocation - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/gpu_info.py b/src/models/gpu_info.py deleted file mode 100644 index a19e772ee9d003f45fa29417f65256c10b621b9b..0000000000000000000000000000000000000000 --- a/src/models/gpu_info.py +++ /dev/null @@ -1,178 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class GpuInfo(Model): - def __init__(self, gpu_vendor_type: str=None, gpu_mode_name: str=None, gpu_memory: int=None, num_gpu: int=None): # noqa: E501 - """GpuInfo - a model defined in Swagger - - :param gpu_vendor_type: The gpu_vendor_type of this GpuInfo. # noqa: E501 - :type gpu_vendor_type: str - :param gpu_mode_name: The gpu_mode_name of this GpuInfo. # noqa: E501 - :type gpu_mode_name: str - :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_vendor_type': str, - 'gpu_mode_name': str, - 'gpu_memory': int, - 'num_gpu': int - } - - self.attribute_map = { - 'gpu_vendor_type': 'gpuVendorType', - 'gpu_mode_name': 'gpuModeName', - 'gpu_memory': 'gpuMemory', - 'num_gpu': 'numGPU' - } - self._gpu_vendor_type = gpu_vendor_type - self._gpu_mode_name = gpu_mode_name - 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_vendor_type(self) -> str: - """Gets the gpu_vendor_type of this GpuInfo. - - GPU vendor name e.g. NVIDIA, AMD etc. # noqa: E501 - - :return: The gpu_vendor_type of this GpuInfo. - :rtype: str - """ - return self._gpu_vendor_type - - @gpu_vendor_type.setter - def gpu_vendor_type(self, gpu_vendor_type: str): - """Sets the gpu_vendor_type of this GpuInfo. - - GPU vendor name e.g. NVIDIA, AMD etc. # noqa: E501 - - :param gpu_vendor_type: The gpu_vendor_type of this GpuInfo. - :type gpu_vendor_type: str - """ - if gpu_vendor_type != "": - allowed_values = ["GPU_PROVIDER_NVIDIA", "GPU_PROVIDER_AMD"] # noqa: E501 - if gpu_vendor_type not in allowed_values: - raise ValueError( - "Invalid value for `gpu_vendor_type` ({0}), must be one of {1}" - .format(gpu_vendor_type, allowed_values) - ) - - self._gpu_vendor_type = gpu_vendor_type - - @property - def gpu_mode_name(self) -> str: - """Gets the gpu_mode_name of this GpuInfo. - - Model name corresponding to vendorType may include info e.g. for NVIDIA, model name could be “Tesla M60”, “Tesla V100” etc. # noqa: E501 - - :return: The gpu_mode_name of this GpuInfo. - :rtype: str - """ - return self._gpu_mode_name - - @gpu_mode_name.setter - def gpu_mode_name(self, gpu_mode_name: str): - """Sets the gpu_mode_name of this GpuInfo. - - Model name corresponding to vendorType may include info e.g. for NVIDIA, model name could be “Tesla M60”, “Tesla V100” etc. # noqa: E501 - - :param gpu_mode_name: The gpu_mode_name of this GpuInfo. - :type gpu_mode_name: str - """ - if gpu_mode_name is None: - raise ValueError("Invalid value for `gpu_mode_name`, must not be `None`") # noqa: E501 - - self._gpu_mode_name = gpu_mode_name - - @property - def gpu_memory(self) -> int: - """Gets the gpu_memory of this GpuInfo. - - GPU memory in Mbytes # 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 Mbytes # 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 - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/huge_page.py b/src/models/huge_page.py deleted file mode 100644 index 3a1abfa8ba7b6190b01b3e366dbf0e90643fffde..0000000000000000000000000000000000000000 --- a/src/models/huge_page.py +++ /dev/null @@ -1,118 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class HugePage(Model): - def __init__(self, page_size: str=None, number: int=None): # noqa: E501 - """HugePage - a model defined in Swagger - - :param page_size: The page_size of this HugePage. # noqa: E501 - :type page_size: str - :param number: The number of this HugePage. # noqa: E501 - :type number: int - """ - self.swagger_types = { - 'page_size': str, - 'number': int - } - - self.attribute_map = { - 'page_size': 'pageSize', - 'number': 'number' - } - self._page_size = page_size - self._number = number - - @classmethod - def from_dict(cls, dikt) -> 'HugePage': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The HugePage of this HugePage. # noqa: E501 - :rtype: HugePage - """ - return util.deserialize_model(dikt, cls) - - @property - def page_size(self) -> str: - """Gets the page_size of this HugePage. - - Size of hugepage # noqa: E501 - - :return: The page_size of this HugePage. - :rtype: str - """ - return self._page_size - - @page_size.setter - def page_size(self, page_size: str): - """Sets the page_size of this HugePage. - - Size of hugepage # noqa: E501 - - :param page_size: The page_size of this HugePage. - :type page_size: str - """ - """ - allowed_values = ["2MB", "4MB", "1GB"] # noqa: E501 - if page_size not in allowed_values: - raise ValueError( - "Invalid value for `page_size` ({0}), must be one of {1}" - .format(page_size, allowed_values) - ) - """ - self._page_size = page_size - - @property - def number(self) -> int: - """Gets the number of this HugePage. - - Total number of huge pages # noqa: E501 - - :return: The number of this HugePage. - :rtype: int - """ - return self._number - - @number.setter - def number(self, number: int): - """Sets the number of this HugePage. - - Total number of huge pages # noqa: E501 - - :param number: The number of this HugePage. - :type number: int - """ - if number is None: - raise ValueError("Invalid value for `number`, must not be `None`") # noqa: E501 - - self._number = number - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/inline_response2001.py b/src/models/inline_response2001.py deleted file mode 100644 index 08132f2a04a11c5f87872379fc2192c01de59769..0000000000000000000000000000000000000000 --- a/src/models/inline_response2001.py +++ /dev/null @@ -1,204 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.fixed_network_ids import FixedNetworkIds # noqa: F401,E501 -from models.mobile_network_ids import MobileNetworkIds # noqa: F401,E501 -from models.service_endpoint import ServiceEndpoint # noqa: F401,E501 -from models.zone_details import ZoneDetails # noqa: F401,E501 -import util - - -class InlineResponse2001(Model): - def __init__(self, edge_discovery_service_end_point: ServiceEndpoint=None, lcm_service_end_point: ServiceEndpoint=None, allowed_mobile_network_ids: MobileNetworkIds=None, allowed_fixed_network_ids: FixedNetworkIds=None, offered_availability_zones: List[ZoneDetails]=None, platform_caps: List[str]=None): # noqa: E501 - """InlineResponse2001 - a model defined in Swagger - - :param edge_discovery_service_end_point: The edge_discovery_service_end_point of this InlineResponse2001. # noqa: E501 - :type edge_discovery_service_end_point: ServiceEndpoint - :param lcm_service_end_point: The lcm_service_end_point of this InlineResponse2001. # noqa: E501 - :type lcm_service_end_point: ServiceEndpoint - :param allowed_mobile_network_ids: The allowed_mobile_network_ids of this InlineResponse2001. # noqa: E501 - :type allowed_mobile_network_ids: MobileNetworkIds - :param allowed_fixed_network_ids: The allowed_fixed_network_ids of this InlineResponse2001. # noqa: E501 - :type allowed_fixed_network_ids: FixedNetworkIds - :param offered_availability_zones: The offered_availability_zones of this InlineResponse2001. # noqa: E501 - :type offered_availability_zones: List[ZoneDetails] - :param platform_caps: The platform_caps of this InlineResponse2001. # noqa: E501 - :type platform_caps: List[str] - """ - self.swagger_types = { - 'edge_discovery_service_end_point': ServiceEndpoint, - 'lcm_service_end_point': ServiceEndpoint, - 'allowed_mobile_network_ids': MobileNetworkIds, - 'allowed_fixed_network_ids': FixedNetworkIds, - 'offered_availability_zones': List[ZoneDetails], - 'platform_caps': List[str] - } - - self.attribute_map = { - 'edge_discovery_service_end_point': 'edgeDiscoveryServiceEndPoint', - 'lcm_service_end_point': 'lcmServiceEndPoint', - 'allowed_mobile_network_ids': 'allowedMobileNetworkIds', - 'allowed_fixed_network_ids': 'allowedFixedNetworkIds', - 'offered_availability_zones': 'offeredAvailabilityZones', - 'platform_caps': 'platformCaps' - } - self._edge_discovery_service_end_point = edge_discovery_service_end_point - self._lcm_service_end_point = lcm_service_end_point - self._allowed_mobile_network_ids = allowed_mobile_network_ids - self._allowed_fixed_network_ids = allowed_fixed_network_ids - self._offered_availability_zones = offered_availability_zones - self._platform_caps = platform_caps - - @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 edge_discovery_service_end_point(self) -> ServiceEndpoint: - """Gets the edge_discovery_service_end_point of this InlineResponse2001. - - - :return: The edge_discovery_service_end_point of this InlineResponse2001. - :rtype: ServiceEndpoint - """ - return self._edge_discovery_service_end_point - - @edge_discovery_service_end_point.setter - def edge_discovery_service_end_point(self, edge_discovery_service_end_point: ServiceEndpoint): - """Sets the edge_discovery_service_end_point of this InlineResponse2001. - - - :param edge_discovery_service_end_point: The edge_discovery_service_end_point of this InlineResponse2001. - :type edge_discovery_service_end_point: ServiceEndpoint - """ - self._edge_discovery_service_end_point = edge_discovery_service_end_point - - @property - def lcm_service_end_point(self) -> ServiceEndpoint: - """Gets the lcm_service_end_point of this InlineResponse2001. - - - :return: The lcm_service_end_point of this InlineResponse2001. - :rtype: ServiceEndpoint - """ - return self._lcm_service_end_point - - @lcm_service_end_point.setter - def lcm_service_end_point(self, lcm_service_end_point: ServiceEndpoint): - """Sets the lcm_service_end_point of this InlineResponse2001. - - - :param lcm_service_end_point: The lcm_service_end_point of this InlineResponse2001. - :type lcm_service_end_point: ServiceEndpoint - """ - self._lcm_service_end_point = lcm_service_end_point - - @property - def allowed_mobile_network_ids(self) -> MobileNetworkIds: - """Gets the allowed_mobile_network_ids of this InlineResponse2001. - - - :return: The allowed_mobile_network_ids of this InlineResponse2001. - :rtype: MobileNetworkIds - """ - return self._allowed_mobile_network_ids - - @allowed_mobile_network_ids.setter - def allowed_mobile_network_ids(self, allowed_mobile_network_ids: MobileNetworkIds): - """Sets the allowed_mobile_network_ids of this InlineResponse2001. - - - :param allowed_mobile_network_ids: The allowed_mobile_network_ids of this InlineResponse2001. - :type allowed_mobile_network_ids: MobileNetworkIds - """ - - self._allowed_mobile_network_ids = allowed_mobile_network_ids - - @property - def allowed_fixed_network_ids(self) -> FixedNetworkIds: - """Gets the allowed_fixed_network_ids of this InlineResponse2001. - - - :return: The allowed_fixed_network_ids of this InlineResponse2001. - :rtype: FixedNetworkIds - """ - return self._allowed_fixed_network_ids - - @allowed_fixed_network_ids.setter - def allowed_fixed_network_ids(self, allowed_fixed_network_ids: FixedNetworkIds): - """Sets the allowed_fixed_network_ids of this InlineResponse2001. - - - :param allowed_fixed_network_ids: The allowed_fixed_network_ids of this InlineResponse2001. - :type allowed_fixed_network_ids: FixedNetworkIds - """ - - self._allowed_fixed_network_ids = allowed_fixed_network_ids - - @property - def offered_availability_zones(self) -> List[ZoneDetails]: - """Gets the offered_availability_zones of this InlineResponse2001. - - - :return: The offered_availability_zones of this InlineResponse2001. - :rtype: List[ZoneDetails] - """ - return self._offered_availability_zones - - @offered_availability_zones.setter - def offered_availability_zones(self, offered_availability_zones: List[ZoneDetails]): - """Sets the offered_availability_zones of this InlineResponse2001. - - - :param offered_availability_zones: The offered_availability_zones of this InlineResponse2001. - :type offered_availability_zones: List[ZoneDetails] - """ - - self._offered_availability_zones = offered_availability_zones - - @property - def platform_caps(self) -> List[str]: - """Gets the platform_caps of this InlineResponse2001. - - - :return: The platform_caps of this InlineResponse2001. - :rtype: List[str] - """ - return self._platform_caps - - @platform_caps.setter - def platform_caps(self, platform_caps: List[str]): - """Sets the platform_caps of this InlineResponse2001. - - - :param platform_caps: The platform_caps of this InlineResponse2001. - :type platform_caps: List[str] - """ - - self._platform_caps = platform_caps diff --git a/src/models/inline_response2002.py b/src/models/inline_response2002.py deleted file mode 100644 index 963e1922dd8951dba8c794bc5cbe088ef6f6f4a1..0000000000000000000000000000000000000000 --- a/src/models/inline_response2002.py +++ /dev/null @@ -1,76 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.federation_context_id import FederationContextId # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2002(Model): - def __init__(self, federation_context_id: FederationContextId=None): # noqa: E501 - """InlineResponse2002 - a model defined in Swagger - - :param federation_context_id: The federation_context_id of this InlineResponse2002. # noqa: E501 - :type federation_context_id: FederationContextId - """ - self.swagger_types = { - 'federation_context_id': FederationContextId - } - - self.attribute_map = { - 'federation_context_id': 'federationContextId' - } - self._federation_context_id = federation_context_id - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2002': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_2 of this InlineResponse2002. # noqa: E501 - :rtype: InlineResponse2002 - """ - return util.deserialize_model(dikt, cls) - - @property - def federation_context_id(self) -> FederationContextId: - """Gets the federation_context_id of this InlineResponse2002. - - - :return: The federation_context_id of this InlineResponse2002. - :rtype: FederationContextId - """ - return self._federation_context_id - - @federation_context_id.setter - def federation_context_id(self, federation_context_id: FederationContextId): - """Sets the federation_context_id of this InlineResponse2002. - - - :param federation_context_id: The federation_context_id of this InlineResponse2002. - :type federation_context_id: FederationContextId - """ - if federation_context_id is None: - raise ValueError("Invalid value for `federation_context_id`, must not be `None`") # noqa: E501 - - self._federation_context_id = federation_context_id diff --git a/src/models/inline_response2005.py b/src/models/inline_response2005.py deleted file mode 100644 index 7ac0e1269498e45f4ff0d7320d3885bc621e9e5c..0000000000000000000000000000000000000000 --- a/src/models/inline_response2005.py +++ /dev/null @@ -1,382 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.artefact_id import ArtefactId # noqa: F401,E501 -from models.object_repo_location import ObjectRepoLocation # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2005(Model): - def __init__(self, artefact_id: ArtefactId=None, app_provider_id: AppProviderId=None, artefact_name: str=None, artefact_description: str=None, artefact_version_info: str=None, artefact_virt_type: str=None, artefact_file_name: str=None, artefact_file_format: str=None, artefact_descriptor_type: str=None, repo_type: str=None, artefact_repo_location: ObjectRepoLocation=None): # noqa: E501 - """InlineResponse2005 - a model defined in Swagger - - :param artefact_id: The artefact_id of this InlineResponse2005. # noqa: E501 - :type artefact_id: ArtefactId - :param app_provider_id: The app_provider_id of this InlineResponse2005. # noqa: E501 - :type app_provider_id: AppProviderId - :param artefact_name: The artefact_name of this InlineResponse2005. # noqa: E501 - :type artefact_name: str - :param artefact_description: The artefact_description of this InlineResponse2005. # noqa: E501 - :type artefact_description: str - :param artefact_version_info: The artefact_version_info of this InlineResponse2005. # noqa: E501 - :type artefact_version_info: str - :param artefact_virt_type: The artefact_virt_type of this InlineResponse2005. # noqa: E501 - :type artefact_virt_type: str - :param artefact_file_name: The artefact_file_name of this InlineResponse2005. # noqa: E501 - :type artefact_file_name: str - :param artefact_file_format: The artefact_file_format of this InlineResponse2005. # noqa: E501 - :type artefact_file_format: str - :param artefact_descriptor_type: The artefact_descriptor_type of this InlineResponse2005. # noqa: E501 - :type artefact_descriptor_type: str - :param repo_type: The repo_type of this InlineResponse2005. # noqa: E501 - :type repo_type: str - :param artefact_repo_location: The artefact_repo_location of this InlineResponse2005. # noqa: E501 - :type artefact_repo_location: ObjectRepoLocation - """ - self.swagger_types = { - 'artefact_id': ArtefactId, - 'app_provider_id': AppProviderId, - 'artefact_name': str, - 'artefact_description': str, - 'artefact_version_info': str, - 'artefact_virt_type': str, - 'artefact_file_name': str, - 'artefact_file_format': str, - 'artefact_descriptor_type': str, - 'repo_type': str, - 'artefact_repo_location': ObjectRepoLocation - } - - self.attribute_map = { - 'artefact_id': 'artefactId', - 'app_provider_id': 'appProviderId', - 'artefact_name': 'artefactName', - 'artefact_description': 'artefactDescription', - 'artefact_version_info': 'artefactVersionInfo', - 'artefact_virt_type': 'artefactVirtType', - 'artefact_file_name': 'artefactFileName', - 'artefact_file_format': 'artefactFileFormat', - 'artefact_descriptor_type': 'artefactDescriptorType', - 'repo_type': 'repoType', - 'artefact_repo_location': 'artefactRepoLocation' - } - self._artefact_id = artefact_id - self._app_provider_id = app_provider_id - self._artefact_name = artefact_name - self._artefact_description = artefact_description - self._artefact_version_info = artefact_version_info - self._artefact_virt_type = artefact_virt_type - self._artefact_file_name = artefact_file_name - self._artefact_file_format = artefact_file_format - self._artefact_descriptor_type = artefact_descriptor_type - self._repo_type = repo_type - self._artefact_repo_location = artefact_repo_location - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2005': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_5 of this InlineResponse2005. # noqa: E501 - :rtype: InlineResponse2005 - """ - return util.deserialize_model(dikt, cls) - - @property - def artefact_id(self) -> ArtefactId: - """Gets the artefact_id of this InlineResponse2005. - - - :return: The artefact_id of this InlineResponse2005. - :rtype: ArtefactId - """ - return self._artefact_id - - @artefact_id.setter - def artefact_id(self, artefact_id: ArtefactId): - """Sets the artefact_id of this InlineResponse2005. - - - :param artefact_id: The artefact_id of this InlineResponse2005. - :type artefact_id: ArtefactId - """ - if artefact_id is None: - raise ValueError("Invalid value for `artefact_id`, must not be `None`") # noqa: E501 - - self._artefact_id = artefact_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this InlineResponse2005. - - - :return: The app_provider_id of this InlineResponse2005. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this InlineResponse2005. - - - :param app_provider_id: The app_provider_id of this InlineResponse2005. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def artefact_name(self) -> str: - """Gets the artefact_name of this InlineResponse2005. - - Name of the artefact. # noqa: E501 - - :return: The artefact_name of this InlineResponse2005. - :rtype: str - """ - return self._artefact_name - - @artefact_name.setter - def artefact_name(self, artefact_name: str): - """Sets the artefact_name of this InlineResponse2005. - - Name of the artefact. # noqa: E501 - - :param artefact_name: The artefact_name of this InlineResponse2005. - :type artefact_name: str - """ - if artefact_name is None: - raise ValueError("Invalid value for `artefact_name`, must not be `None`") # noqa: E501 - - self._artefact_name = artefact_name - - @property - def artefact_description(self) -> str: - """Gets the artefact_description of this InlineResponse2005. - - Brief description of the artefact by the application provider # noqa: E501 - - :return: The artefact_description of this InlineResponse2005. - :rtype: str - """ - return self._artefact_description - - @artefact_description.setter - def artefact_description(self, artefact_description: str): - """Sets the artefact_description of this InlineResponse2005. - - Brief description of the artefact by the application provider # noqa: E501 - - :param artefact_description: The artefact_description of this InlineResponse2005. - :type artefact_description: str - """ - - self._artefact_description = artefact_description - - @property - def artefact_version_info(self) -> str: - """Gets the artefact_version_info of this InlineResponse2005. - - Artefact version information # noqa: E501 - - :return: The artefact_version_info of this InlineResponse2005. - :rtype: str - """ - return self._artefact_version_info - - @artefact_version_info.setter - def artefact_version_info(self, artefact_version_info: str): - """Sets the artefact_version_info of this InlineResponse2005. - - Artefact version information # noqa: E501 - - :param artefact_version_info: The artefact_version_info of this InlineResponse2005. - :type artefact_version_info: str - """ - if artefact_version_info is None: - raise ValueError("Invalid value for `artefact_version_info`, must not be `None`") # noqa: E501 - - self._artefact_version_info = artefact_version_info - - @property - def artefact_virt_type(self) -> str: - """Gets the artefact_virt_type of this InlineResponse2005. - - - :return: The artefact_virt_type of this InlineResponse2005. - :rtype: str - """ - return self._artefact_virt_type - - @artefact_virt_type.setter - def artefact_virt_type(self, artefact_virt_type: str): - """Sets the artefact_virt_type of this InlineResponse2005. - - - :param artefact_virt_type: The artefact_virt_type of this InlineResponse2005. - :type artefact_virt_type: str - """ - allowed_values = ["VM_TYPE", "CONTAINER_TYPE"] # noqa: E501 - if artefact_virt_type not in allowed_values: - raise ValueError( - "Invalid value for `artefact_virt_type` ({0}), must be one of {1}" - .format(artefact_virt_type, allowed_values) - ) - - self._artefact_virt_type = artefact_virt_type - - @property - def artefact_file_name(self) -> str: - """Gets the artefact_file_name of this InlineResponse2005. - - Name of the file. # noqa: E501 - - :return: The artefact_file_name of this InlineResponse2005. - :rtype: str - """ - return self._artefact_file_name - - @artefact_file_name.setter - def artefact_file_name(self, artefact_file_name: str): - """Sets the artefact_file_name of this InlineResponse2005. - - Name of the file. # noqa: E501 - - :param artefact_file_name: The artefact_file_name of this InlineResponse2005. - :type artefact_file_name: str - """ - - self._artefact_file_name = artefact_file_name - - @property - def artefact_file_format(self) -> str: - """Gets the artefact_file_format of this InlineResponse2005. - - Artefacts like Helm charts or Terraform scripts may need compressed format. # noqa: E501 - - :return: The artefact_file_format of this InlineResponse2005. - :rtype: str - """ - return self._artefact_file_format - - @artefact_file_format.setter - def artefact_file_format(self, artefact_file_format: str): - """Sets the artefact_file_format of this InlineResponse2005. - - Artefacts like Helm charts or Terraform scripts may need compressed format. # noqa: E501 - - :param artefact_file_format: The artefact_file_format of this InlineResponse2005. - :type artefact_file_format: str - """ - allowed_values = ["WINZIP", "TAR", "TEXT", "TARGZ"] # noqa: E501 - if artefact_file_format and artefact_file_format not in allowed_values: - raise ValueError( - "Invalid value for `artefact_file_format` ({0}), must be one of {1}" - .format(artefact_file_format, allowed_values) - ) - - self._artefact_file_format = artefact_file_format - - @property - def artefact_descriptor_type(self) -> str: - """Gets the artefact_descriptor_type of this InlineResponse2005. - - Type of descriptor present in the artefact. App provider can either define either a Helm chart or a Terraform script or container spec. # noqa: E501 - - :return: The artefact_descriptor_type of this InlineResponse2005. - :rtype: str - """ - return self._artefact_descriptor_type - - @artefact_descriptor_type.setter - def artefact_descriptor_type(self, artefact_descriptor_type: str): - """Sets the artefact_descriptor_type of this InlineResponse2005. - - Type of descriptor present in the artefact. App provider can either define either a Helm chart or a Terraform script or container spec. # noqa: E501 - - :param artefact_descriptor_type: The artefact_descriptor_type of this InlineResponse2005. - :type artefact_descriptor_type: str - """ - allowed_values = ["HELM", "TERRAFORM", "ANSIBLE", "SHELL", "COMPONENTSPEC"] # noqa: E501 - if artefact_descriptor_type not in allowed_values: - raise ValueError( - "Invalid value for `artefact_descriptor_type` ({0}), must be one of {1}" - .format(artefact_descriptor_type, allowed_values) - ) - - self._artefact_descriptor_type = artefact_descriptor_type - - @property - def repo_type(self) -> str: - """Gets the repo_type of this InlineResponse2005. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :return: The repo_type of this InlineResponse2005. - :rtype: str - """ - return self._repo_type - - @repo_type.setter - def repo_type(self, repo_type: str): - """Sets the repo_type of this InlineResponse2005. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :param repo_type: The repo_type of this InlineResponse2005. - :type repo_type: str - """ - allowed_values = ["PRIVATEREPO", "PUBLICREPO", "UPLOAD"] # noqa: E501 - if repo_type not in allowed_values: - raise ValueError( - "Invalid value for `repo_type` ({0}), must be one of {1}" - .format(repo_type, allowed_values) - ) - - self._repo_type = repo_type - - @property - def artefact_repo_location(self) -> ObjectRepoLocation: - """Gets the artefact_repo_location of this InlineResponse2005. - - - :return: The artefact_repo_location of this InlineResponse2005. - :rtype: ObjectRepoLocation - """ - return self._artefact_repo_location - - @artefact_repo_location.setter - def artefact_repo_location(self, artefact_repo_location: ObjectRepoLocation): - """Sets the artefact_repo_location of this InlineResponse2005. - - - :param artefact_repo_location: The artefact_repo_location of this InlineResponse2005. - :type artefact_repo_location: ObjectRepoLocation - """ - - self._artefact_repo_location = artefact_repo_location diff --git a/src/models/inline_response2006.py b/src/models/inline_response2006.py deleted file mode 100644 index b8741c168e83adfedf1e7713632808850c76badc..0000000000000000000000000000000000000000 --- a/src/models/inline_response2006.py +++ /dev/null @@ -1,369 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.cpu_arch_type import CPUArchType # noqa: F401,E501 -from models.file_id import FileId # noqa: F401,E501 -from models.object_repo_location import ObjectRepoLocation # noqa: F401,E501 -from models.os_type import OSType # noqa: F401,E501 -from models.virt_image_type import VirtImageType # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2006(Model): - def __init__(self, file_id: FileId=None, app_provider_id: AppProviderId=None, file_name: str=None, file_description: str=None, file_version_info: str=None, file_type: VirtImageType=None, checksum: str=None, img_os_type: OSType=None, img_ins_set_arch: CPUArchType=None, repo_type: str=None, file_repo_location: ObjectRepoLocation=None): # noqa: E501 - """InlineResponse2006 - a model defined in Swagger - - :param file_id: The file_id of this InlineResponse2006. # noqa: E501 - :type file_id: FileId - :param app_provider_id: The app_provider_id of this InlineResponse2006. # noqa: E501 - :type app_provider_id: AppProviderId - :param file_name: The file_name of this InlineResponse2006. # noqa: E501 - :type file_name: str - :param file_description: The file_description of this InlineResponse2006. # noqa: E501 - :type file_description: str - :param file_version_info: The file_version_info of this InlineResponse2006. # noqa: E501 - :type file_version_info: str - :param file_type: The file_type of this InlineResponse2006. # noqa: E501 - :type file_type: VirtImageType - :param checksum: The checksum of this InlineResponse2006. # noqa: E501 - :type checksum: str - :param img_os_type: The img_os_type of this InlineResponse2006. # noqa: E501 - :type img_os_type: OSType - :param img_ins_set_arch: The img_ins_set_arch of this InlineResponse2006. # noqa: E501 - :type img_ins_set_arch: CPUArchType - :param repo_type: The repo_type of this InlineResponse2006. # noqa: E501 - :type repo_type: str - :param file_repo_location: The file_repo_location of this InlineResponse2006. # noqa: E501 - :type file_repo_location: ObjectRepoLocation - """ - self.swagger_types = { - 'file_id': FileId, - 'app_provider_id': AppProviderId, - 'file_name': str, - 'file_description': str, - 'file_version_info': str, - 'file_type': VirtImageType, - 'checksum': str, - 'img_os_type': OSType, - 'img_ins_set_arch': CPUArchType, - 'repo_type': str, - 'file_repo_location': ObjectRepoLocation - } - - self.attribute_map = { - 'file_id': 'fileId', - 'app_provider_id': 'appProviderId', - 'file_name': 'fileName', - 'file_description': 'fileDescription', - 'file_version_info': 'fileVersionInfo', - 'file_type': 'fileType', - 'checksum': 'checksum', - 'img_os_type': 'imgOSType', - 'img_ins_set_arch': 'imgInsSetArch', - 'repo_type': 'repoType', - 'file_repo_location': 'fileRepoLocation' - } - self._file_id = file_id - self._app_provider_id = app_provider_id - self._file_name = file_name - self._file_description = file_description - self._file_version_info = file_version_info - self._file_type = file_type - self._checksum = checksum - self._img_os_type = img_os_type - self._img_ins_set_arch = img_ins_set_arch - self._repo_type = repo_type - self._file_repo_location = file_repo_location - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2006': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_6 of this InlineResponse2006. # noqa: E501 - :rtype: InlineResponse2006 - """ - return util.deserialize_model(dikt, cls) - - @property - def file_id(self) -> FileId: - """Gets the file_id of this InlineResponse2006. - - - :return: The file_id of this InlineResponse2006. - :rtype: FileId - """ - return self._file_id - - @file_id.setter - def file_id(self, file_id: FileId): - """Sets the file_id of this InlineResponse2006. - - - :param file_id: The file_id of this InlineResponse2006. - :type file_id: FileId - """ - if file_id is None: - raise ValueError("Invalid value for `file_id`, must not be `None`") # noqa: E501 - - self._file_id = file_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this InlineResponse2006. - - - :return: The app_provider_id of this InlineResponse2006. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this InlineResponse2006. - - - :param app_provider_id: The app_provider_id of this InlineResponse2006. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def file_name(self) -> str: - """Gets the file_name of this InlineResponse2006. - - Name of the image file. App provides specifies this name when image is uploaded on originating OP over NBI. # noqa: E501 - - :return: The file_name of this InlineResponse2006. - :rtype: str - """ - return self._file_name - - @file_name.setter - def file_name(self, file_name: str): - """Sets the file_name of this InlineResponse2006. - - Name of the image file. App provides specifies this name when image is uploaded on originating OP over NBI. # noqa: E501 - - :param file_name: The file_name of this InlineResponse2006. - :type file_name: str - """ - if file_name is None: - raise ValueError("Invalid value for `file_name`, must not be `None`") # noqa: E501 - - self._file_name = file_name - - @property - def file_description(self) -> str: - """Gets the file_description of this InlineResponse2006. - - Brief description about the image file. # noqa: E501 - - :return: The file_description of this InlineResponse2006. - :rtype: str - """ - return self._file_description - - @file_description.setter - def file_description(self, file_description: str): - """Sets the file_description of this InlineResponse2006. - - Brief description about the image file. # noqa: E501 - - :param file_description: The file_description of this InlineResponse2006. - :type file_description: str - """ - - self._file_description = file_description - - @property - def file_version_info(self) -> str: - """Gets the file_version_info of this InlineResponse2006. - - File version information # noqa: E501 - - :return: The file_version_info of this InlineResponse2006. - :rtype: str - """ - return self._file_version_info - - @file_version_info.setter - def file_version_info(self, file_version_info: str): - """Sets the file_version_info of this InlineResponse2006. - - File version information # noqa: E501 - - :param file_version_info: The file_version_info of this InlineResponse2006. - :type file_version_info: str - """ - if file_version_info is None: - raise ValueError("Invalid value for `file_version_info`, must not be `None`") # noqa: E501 - - self._file_version_info = file_version_info - - @property - def file_type(self) -> VirtImageType: - """Gets the file_type of this InlineResponse2006. - - - :return: The file_type of this InlineResponse2006. - :rtype: VirtImageType - """ - return self._file_type - - @file_type.setter - def file_type(self, file_type: VirtImageType): - """Sets the file_type of this InlineResponse2006. - - - :param file_type: The file_type of this InlineResponse2006. - :type file_type: VirtImageType - """ - if file_type is None: - raise ValueError("Invalid value for `file_type`, must not be `None`") # noqa: E501 - - self._file_type = file_type - - @property - def checksum(self) -> str: - """Gets the checksum of this InlineResponse2006. - - MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 - - :return: The checksum of this InlineResponse2006. - :rtype: str - """ - return self._checksum - - @checksum.setter - def checksum(self, checksum: str): - """Sets the checksum of this InlineResponse2006. - - MD5 checksum for VM and file-based images, sha256 digest for containers # noqa: E501 - - :param checksum: The checksum of this InlineResponse2006. - :type checksum: str - """ - - self._checksum = checksum - - @property - def img_os_type(self) -> OSType: - """Gets the img_os_type of this InlineResponse2006. - - - :return: The img_os_type of this InlineResponse2006. - :rtype: OSType - """ - return self._img_os_type - - @img_os_type.setter - def img_os_type(self, img_os_type: OSType): - """Sets the img_os_type of this InlineResponse2006. - - - :param img_os_type: The img_os_type of this InlineResponse2006. - :type img_os_type: OSType - """ - if img_os_type is None: - raise ValueError("Invalid value for `img_os_type`, must not be `None`") # noqa: E501 - - self._img_os_type = img_os_type - - @property - def img_ins_set_arch(self) -> CPUArchType: - """Gets the img_ins_set_arch of this InlineResponse2006. - - - :return: The img_ins_set_arch of this InlineResponse2006. - :rtype: CPUArchType - """ - return self._img_ins_set_arch - - @img_ins_set_arch.setter - def img_ins_set_arch(self, img_ins_set_arch: CPUArchType): - """Sets the img_ins_set_arch of this InlineResponse2006. - - - :param img_ins_set_arch: The img_ins_set_arch of this InlineResponse2006. - :type img_ins_set_arch: CPUArchType - """ - if img_ins_set_arch is None: - raise ValueError("Invalid value for `img_ins_set_arch`, must not be `None`") # noqa: E501 - - self._img_ins_set_arch = img_ins_set_arch - - @property - def repo_type(self) -> str: - """Gets the repo_type of this InlineResponse2006. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :return: The repo_type of this InlineResponse2006. - :rtype: str - """ - return self._repo_type - - @repo_type.setter - def repo_type(self, repo_type: str): - """Sets the repo_type of this InlineResponse2006. - - Artefact or file repository location. PUBLICREPO is used of public URLs like GitHub, Helm repo, docker registry etc., PRIVATEREPO is used for private repo managed by the application developer, UPLOAD is for the case when artefact/file is uploaded from MEC web portal. OP should pull the image from ‘repoUrl' immediately after receiving the request and then send back the response. In case the repoURL corresponds to a docker registry, use docker v2 http api to do the pull. # noqa: E501 - - :param repo_type: The repo_type of this InlineResponse2006. - :type repo_type: str - """ - allowed_values = ["PRIVATEREPO", "PUBLICREPO", "UPLOAD"] # noqa: E501 - if repo_type not in allowed_values: - raise ValueError( - "Invalid value for `repo_type` ({0}), must be one of {1}" - .format(repo_type, allowed_values) - ) - - self._repo_type = repo_type - - @property - def file_repo_location(self) -> ObjectRepoLocation: - """Gets the file_repo_location of this InlineResponse2006. - - - :return: The file_repo_location of this InlineResponse2006. - :rtype: ObjectRepoLocation - """ - return self._file_repo_location - - @file_repo_location.setter - def file_repo_location(self, file_repo_location: ObjectRepoLocation): - """Sets the file_repo_location of this InlineResponse2006. - - - :param file_repo_location: The file_repo_location of this InlineResponse2006. - :type file_repo_location: ObjectRepoLocation - """ - - self._file_repo_location = file_repo_location diff --git a/src/models/inline_response2007.py b/src/models/inline_response2007.py deleted file mode 100644 index 7677dcb00f68ac519de5ddb5fb1dbedd74d16915..0000000000000000000000000000000000000000 --- a/src/models/inline_response2007.py +++ /dev/null @@ -1,223 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.app_component_specs import AppComponentSpecs # noqa: F401,E501 -from models.app_identifier import AppIdentifier # noqa: F401,E501 -from models.app_meta_data import AppMetaData # noqa: F401,E501 -from models.app_provider_id import AppProviderId # noqa: F401,E501 -from models.app_qo_s_profile import AppQoSProfile # noqa: F401,E501 -from models.inline_response2007_app_deployment_zones import InlineResponse2007AppDeploymentZones # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2007(Model): - def __init__(self, app_id: AppIdentifier=None, app_provider_id: AppProviderId=None, app_deployment_zones: List[InlineResponse2007AppDeploymentZones]=None, app_meta_data: AppMetaData=None, app_qo_s_profile: AppQoSProfile=None, app_component_specs: AppComponentSpecs=None): # noqa: E501 - """InlineResponse2007 - a model defined in Swagger - - :param app_id: The app_id of this InlineResponse2007. # noqa: E501 - :type app_id: AppIdentifier - :param app_provider_id: The app_provider_id of this InlineResponse2007. # noqa: E501 - :type app_provider_id: AppProviderId - :param app_deployment_zones: The app_deployment_zones of this InlineResponse2007. # noqa: E501 - :type app_deployment_zones: List[InlineResponse2007AppDeploymentZones] - :param app_meta_data: The app_meta_data of this InlineResponse2007. # noqa: E501 - :type app_meta_data: AppMetaData - :param app_qo_s_profile: The app_qo_s_profile of this InlineResponse2007. # noqa: E501 - :type app_qo_s_profile: AppQoSProfile - :param app_component_specs: The app_component_specs of this InlineResponse2007. # noqa: E501 - :type app_component_specs: AppComponentSpecs - """ - self.swagger_types = { - 'app_id': AppIdentifier, - 'app_provider_id': AppProviderId, - 'app_deployment_zones': List[InlineResponse2007AppDeploymentZones], - 'app_meta_data': AppMetaData, - 'app_qo_s_profile': AppQoSProfile, - 'app_component_specs': AppComponentSpecs - } - - self.attribute_map = { - 'app_id': 'appId', - 'app_provider_id': 'appProviderId', - 'app_deployment_zones': 'appDeploymentZones', - 'app_meta_data': 'appMetaData', - 'app_qo_s_profile': 'appQoSProfile', - 'app_component_specs': 'appComponentSpecs' - } - self._app_id = app_id - self._app_provider_id = app_provider_id - self._app_deployment_zones = app_deployment_zones - self._app_meta_data = app_meta_data - self._app_qo_s_profile = app_qo_s_profile - self._app_component_specs = app_component_specs - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2007': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_7 of this InlineResponse2007. # noqa: E501 - :rtype: InlineResponse2007 - """ - return util.deserialize_model(dikt, cls) - - @property - def app_id(self) -> AppIdentifier: - """Gets the app_id of this InlineResponse2007. - - - :return: The app_id of this InlineResponse2007. - :rtype: AppIdentifier - """ - return self._app_id - - @app_id.setter - def app_id(self, app_id: AppIdentifier): - """Sets the app_id of this InlineResponse2007. - - - :param app_id: The app_id of this InlineResponse2007. - :type app_id: AppIdentifier - """ - if app_id is None: - raise ValueError("Invalid value for `app_id`, must not be `None`") # noqa: E501 - - self._app_id = app_id - - @property - def app_provider_id(self) -> AppProviderId: - """Gets the app_provider_id of this InlineResponse2007. - - - :return: The app_provider_id of this InlineResponse2007. - :rtype: AppProviderId - """ - return self._app_provider_id - - @app_provider_id.setter - def app_provider_id(self, app_provider_id: AppProviderId): - """Sets the app_provider_id of this InlineResponse2007. - - - :param app_provider_id: The app_provider_id of this InlineResponse2007. - :type app_provider_id: AppProviderId - """ - if app_provider_id is None: - raise ValueError("Invalid value for `app_provider_id`, must not be `None`") # noqa: E501 - - self._app_provider_id = app_provider_id - - @property - def app_deployment_zones(self) -> List[InlineResponse2007AppDeploymentZones]: - """Gets the app_deployment_zones of this InlineResponse2007. - - Details about partner OP zones where the application should be made available; This field when specified will instruct the OP to restrict application instantiation only on the listed zones. # noqa: E501 - - :return: The app_deployment_zones of this InlineResponse2007. - :rtype: List[InlineResponse2007AppDeploymentZones] - """ - return self._app_deployment_zones - - @app_deployment_zones.setter - def app_deployment_zones(self, app_deployment_zones: List[InlineResponse2007AppDeploymentZones]): - """Sets the app_deployment_zones of this InlineResponse2007. - - Details about partner OP zones where the application should be made available; This field when specified will instruct the OP to restrict application instantiation only on the listed zones. # noqa: E501 - - :param app_deployment_zones: The app_deployment_zones of this InlineResponse2007. - :type app_deployment_zones: List[InlineResponse2007AppDeploymentZones] - """ - if app_deployment_zones is None: - raise ValueError("Invalid value for `app_deployment_zones`, must not be `None`") # noqa: E501 - - self._app_deployment_zones = app_deployment_zones - - @property - def app_meta_data(self) -> AppMetaData: - """Gets the app_meta_data of this InlineResponse2007. - - - :return: The app_meta_data of this InlineResponse2007. - :rtype: AppMetaData - """ - return self._app_meta_data - - @app_meta_data.setter - def app_meta_data(self, app_meta_data: AppMetaData): - """Sets the app_meta_data of this InlineResponse2007. - - - :param app_meta_data: The app_meta_data of this InlineResponse2007. - :type app_meta_data: AppMetaData - """ - if app_meta_data is None: - raise ValueError("Invalid value for `app_meta_data`, must not be `None`") # noqa: E501 - - self._app_meta_data = app_meta_data - - @property - def app_qo_s_profile(self) -> AppQoSProfile: - """Gets the app_qo_s_profile of this InlineResponse2007. - - - :return: The app_qo_s_profile of this InlineResponse2007. - :rtype: AppQoSProfile - """ - return self._app_qo_s_profile - - @app_qo_s_profile.setter - def app_qo_s_profile(self, app_qo_s_profile: AppQoSProfile): - """Sets the app_qo_s_profile of this InlineResponse2007. - - - :param app_qo_s_profile: The app_qo_s_profile of this InlineResponse2007. - :type app_qo_s_profile: AppQoSProfile - """ - if app_qo_s_profile is None: - raise ValueError("Invalid value for `app_qo_s_profile`, must not be `None`") # noqa: E501 - - self._app_qo_s_profile = app_qo_s_profile - - @property - def app_component_specs(self) -> AppComponentSpecs: - """Gets the app_component_specs of this InlineResponse2007. - - - :return: The app_component_specs of this InlineResponse2007. - :rtype: AppComponentSpecs - """ - return self._app_component_specs - - @app_component_specs.setter - def app_component_specs(self, app_component_specs: AppComponentSpecs): - """Sets the app_component_specs of this InlineResponse2007. - - - :param app_component_specs: The app_component_specs of this InlineResponse2007. - :type app_component_specs: AppComponentSpecs - """ - if app_component_specs is None: - raise ValueError("Invalid value for `app_component_specs`, must not be `None`") # noqa: E501 - - self._app_component_specs = app_component_specs diff --git a/src/models/inline_response2007_app_deployment_zones.py b/src/models/inline_response2007_app_deployment_zones.py deleted file mode 100644 index 6d58c509e83264ccb03ee7bad7f7fa01b4775b33..0000000000000000000000000000000000000000 --- a/src/models/inline_response2007_app_deployment_zones.py +++ /dev/null @@ -1,105 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.country_code import CountryCode # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2007AppDeploymentZones(Model): - def __init__(self, country_code: CountryCode=None, zone_info: ZoneIdentifier=None): # noqa: E501 - """InlineResponse2007AppDeploymentZones - a model defined in Swagger - - :param country_code: The country_code of this InlineResponse2007AppDeploymentZones. # noqa: E501 - :type country_code: CountryCode - :param zone_info: The zone_info of this InlineResponse2007AppDeploymentZones. # noqa: E501 - :type zone_info: ZoneIdentifier - """ - self.swagger_types = { - 'country_code': CountryCode, - 'zone_info': ZoneIdentifier - } - - self.attribute_map = { - 'country_code': 'countryCode', - 'zone_info': 'zoneInfo' - } - self._country_code = country_code - self._zone_info = zone_info - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2007AppDeploymentZones': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_7_appDeploymentZones of this InlineResponse2007AppDeploymentZones. # noqa: E501 - :rtype: InlineResponse2007AppDeploymentZones - """ - return util.deserialize_model(dikt, cls) - - @property - def country_code(self) -> CountryCode: - """Gets the country_code of this InlineResponse2007AppDeploymentZones. - - - :return: The country_code of this InlineResponse2007AppDeploymentZones. - :rtype: CountryCode - """ - return self._country_code - - @country_code.setter - def country_code(self, country_code: CountryCode): - """Sets the country_code of this InlineResponse2007AppDeploymentZones. - - - :param country_code: The country_code of this InlineResponse2007AppDeploymentZones. - :type country_code: CountryCode - """ - if country_code is None: - raise ValueError("Invalid value for `country_code`, must not be `None`") # noqa: E501 - - self._country_code = country_code - - @property - def zone_info(self) -> ZoneIdentifier: - """Gets the zone_info of this InlineResponse2007AppDeploymentZones. - - - :return: The zone_info of this InlineResponse2007AppDeploymentZones. - :rtype: ZoneIdentifier - """ - return self._zone_info - - @zone_info.setter - def zone_info(self, zone_info: ZoneIdentifier): - """Sets the zone_info of this InlineResponse2007AppDeploymentZones. - - - :param zone_info: The zone_info of this InlineResponse2007AppDeploymentZones. - :type zone_info: ZoneIdentifier - """ - if zone_info is None: - raise ValueError("Invalid value for `zone_info`, must not be `None`") # noqa: E501 - - self._zone_info = zone_info diff --git a/src/models/inline_response2008.py b/src/models/inline_response2008.py deleted file mode 100644 index 643f6341efacc41712fe889c801ee9a0f6de4b50..0000000000000000000000000000000000000000 --- a/src/models/inline_response2008.py +++ /dev/null @@ -1,102 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.inline_response2008_accesspoint_info import InlineResponse2008AccesspointInfo # noqa: F401,E501 -from models.instance_state import InstanceState # noqa: F401,E501 -import util - - -class InlineResponse2008(Model): - def __init__(self, app_instance_state: InstanceState=None, accesspoint_info: List[InlineResponse2008AccesspointInfo]=None): # noqa: E501 - """InlineResponse2008 - a model defined in Swagger - - :param app_instance_state: The app_instance_state of this InlineResponse2008. # noqa: E501 - :type app_instance_state: InstanceState - :param accesspoint_info: The accesspoint_info of this InlineResponse2008. # noqa: E501 - :type accesspoint_info: List[InlineResponse2008AccesspointInfo] - """ - self.swagger_types = { - 'app_instance_state': InstanceState, - 'accesspoint_info': List[InlineResponse2008AccesspointInfo] - } - - self.attribute_map = { - 'app_instance_state': 'appInstanceState', - 'accesspoint_info': 'accesspointInfo' - } - self._app_instance_state = app_instance_state - self._accesspoint_info = accesspoint_info - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2008': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_8 of this InlineResponse2008. # noqa: E501 - :rtype: InlineResponse2008 - """ - return util.deserialize_model(dikt, cls) - - @property - def app_instance_state(self) -> InstanceState: - """Gets the app_instance_state of this InlineResponse2008. - - - :return: The app_instance_state of this InlineResponse2008. - :rtype: InstanceState - """ - return self._app_instance_state - - @app_instance_state.setter - def app_instance_state(self, app_instance_state: InstanceState): - """Sets the app_instance_state of this InlineResponse2008. - - - :param app_instance_state: The app_instance_state of this InlineResponse2008. - :type app_instance_state: InstanceState - """ - - self._app_instance_state = app_instance_state - - @property - def accesspoint_info(self) -> List[InlineResponse2008AccesspointInfo]: - """Gets the accesspoint_info of this InlineResponse2008. - - Information about the IP and Port exposed by the OP. Application clients shall use these access points to reach this application instance # noqa: E501 - - :return: The accesspoint_info of this InlineResponse2008. - :rtype: List[InlineResponse2008AccesspointInfo] - """ - return self._accesspoint_info - - @accesspoint_info.setter - def accesspoint_info(self, accesspoint_info: List[InlineResponse2008AccesspointInfo]): - """Sets the accesspoint_info of this InlineResponse2008. - - Information about the IP and Port exposed by the OP. Application clients shall use these access points to reach this application instance # noqa: E501 - - :param accesspoint_info: The accesspoint_info of this InlineResponse2008. - :type accesspoint_info: List[InlineResponse2008AccesspointInfo] - """ - - self._accesspoint_info = accesspoint_info diff --git a/src/models/inline_response2008_accesspoint_info.py b/src/models/inline_response2008_accesspoint_info.py deleted file mode 100644 index c936052d0c0caee944f814e42caa15b0b51ebc87..0000000000000000000000000000000000000000 --- a/src/models/inline_response2008_accesspoint_info.py +++ /dev/null @@ -1,106 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.service_endpoint import ServiceEndpoint # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2008AccesspointInfo(Model): - def __init__(self, interface_id: str=None, access_points: ServiceEndpoint=None): # noqa: E501 - """InlineResponse2008AccesspointInfo - a model defined in Swagger - - :param interface_id: The interface_id of this InlineResponse2008AccesspointInfo. # noqa: E501 - :type interface_id: str - :param access_points: The access_points of this InlineResponse2008AccesspointInfo. # noqa: E501 - :type access_points: ServiceEndpoint - """ - self.swagger_types = { - 'interface_id': str, - 'access_points': ServiceEndpoint - } - - 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) -> 'InlineResponse2008AccesspointInfo': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_8_accesspointInfo of this InlineResponse2008AccesspointInfo. # noqa: E501 - :rtype: InlineResponse2008AccesspointInfo - """ - return util.deserialize_model(dikt, cls) - - @property - def interface_id(self) -> str: - """Gets the interface_id of this InlineResponse2008AccesspointInfo. - - This is the interface identifier that app provider defines when application is onboarded. # noqa: E501 - - :return: The interface_id of this InlineResponse2008AccesspointInfo. - :rtype: str - """ - return self._interface_id - - @interface_id.setter - def interface_id(self, interface_id: str): - """Sets the interface_id of this InlineResponse2008AccesspointInfo. - - This is the interface identifier that app provider defines when application is onboarded. # noqa: E501 - - :param interface_id: The interface_id of this InlineResponse2008AccesspointInfo. - :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) -> ServiceEndpoint: - """Gets the access_points of this InlineResponse2008AccesspointInfo. - - - :return: The access_points of this InlineResponse2008AccesspointInfo. - :rtype: ServiceEndpoint - """ - return self._access_points - - @access_points.setter - def access_points(self, access_points: ServiceEndpoint): - """Sets the access_points of this InlineResponse2008AccesspointInfo. - - - :param access_points: The access_points of this InlineResponse2008AccesspointInfo. - :type access_points: ServiceEndpoint - """ - 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/src/models/inline_response2009.py b/src/models/inline_response2009.py deleted file mode 100644 index 84e4b0114b6cf1c947120762be91045b4647bce2..0000000000000000000000000000000000000000 --- a/src/models/inline_response2009.py +++ /dev/null @@ -1,105 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.federation_context_idapplicationlcmappapp_idapp_providerapp_provider_id_app_instance_info import FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse2009(Model): - def __init__(self, zone_id: ZoneIdentifier=None, app_instance_info: List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo]=None): # noqa: E501 - """InlineResponse2009 - a model defined in Swagger - - :param zone_id: The zone_id of this InlineResponse2009. # noqa: E501 - :type zone_id: ZoneIdentifier - :param app_instance_info: The app_instance_info of this InlineResponse2009. # noqa: E501 - :type app_instance_info: List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo] - """ - self.swagger_types = { - 'zone_id': ZoneIdentifier, - 'app_instance_info': List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo] - } - - self.attribute_map = { - 'zone_id': 'zoneId', - 'app_instance_info': 'appInstanceInfo' - } - self._zone_id = zone_id - self._app_instance_info = app_instance_info - - @classmethod - def from_dict(cls, dikt) -> 'InlineResponse2009': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The inline_response_200_9 of this InlineResponse2009. # noqa: E501 - :rtype: InlineResponse2009 - """ - return util.deserialize_model(dikt, cls) - - @property - def zone_id(self) -> ZoneIdentifier: - """Gets the zone_id of this InlineResponse2009. - - - :return: The zone_id of this InlineResponse2009. - :rtype: ZoneIdentifier - """ - return self._zone_id - - @zone_id.setter - def zone_id(self, zone_id: ZoneIdentifier): - """Sets the zone_id of this InlineResponse2009. - - - :param zone_id: The zone_id of this InlineResponse2009. - :type zone_id: ZoneIdentifier - """ - if zone_id is None: - raise ValueError("Invalid value for `zone_id`, must not be `None`") # noqa: E501 - - self._zone_id = zone_id - - @property - def app_instance_info(self) -> List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo]: - """Gets the app_instance_info of this InlineResponse2009. - - - :return: The app_instance_info of this InlineResponse2009. - :rtype: List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo] - """ - return self._app_instance_info - - @app_instance_info.setter - def app_instance_info(self, app_instance_info: List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo]): - """Sets the app_instance_info of this InlineResponse2009. - - - :param app_instance_info: The app_instance_info of this InlineResponse2009. - :type app_instance_info: List[FederationContextIdapplicationlcmappappIdappProviderappProviderIdAppInstanceInfo] - """ - if app_instance_info is None: - raise ValueError("Invalid value for `app_instance_info`, must not be `None`") # noqa: E501 - - self._app_instance_info = app_instance_info diff --git a/src/models/inline_response202.py b/src/models/inline_response202.py deleted file mode 100644 index 8864255478fbb2235149fae6ad92fb332551c51e..0000000000000000000000000000000000000000 --- a/src/models/inline_response202.py +++ /dev/null @@ -1,105 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.instance_identifier import InstanceIdentifier # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class InlineResponse202(Model): - def __init__(self, zone_id: ZoneIdentifier=None, app_inst_identifier: InstanceIdentifier=None): # noqa: E501 - """InlineResponse202 - a model defined in Swagger - - :param zone_id: The zone_id of this InlineResponse202. # noqa: E501 - :type zone_id: ZoneIdentifier - :param app_inst_identifier: The app_inst_identifier of this InlineResponse202. # noqa: E501 - :type app_inst_identifier: InstanceIdentifier - """ - self.swagger_types = { - 'zone_id': ZoneIdentifier, - 'app_inst_identifier': InstanceIdentifier - } - - self.attribute_map = { - 'zone_id': 'zoneId', - 'app_inst_identifier': 'appInstIdentifier' - } - self._zone_id = zone_id - self._app_inst_identifier = app_inst_identifier - - @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 zone_id(self) -> ZoneIdentifier: - """Gets the zone_id of this InlineResponse202. - - - :return: The zone_id of this InlineResponse202. - :rtype: ZoneIdentifier - """ - return self._zone_id - - @zone_id.setter - def zone_id(self, zone_id: ZoneIdentifier): - """Sets the zone_id of this InlineResponse202. - - - :param zone_id: The zone_id of this InlineResponse202. - :type zone_id: ZoneIdentifier - """ - if zone_id is None: - raise ValueError("Invalid value for `zone_id`, must not be `None`") # noqa: E501 - - self._zone_id = zone_id - - @property - def app_inst_identifier(self) -> InstanceIdentifier: - """Gets the app_inst_identifier of this InlineResponse202. - - - :return: The app_inst_identifier of this InlineResponse202. - :rtype: InstanceIdentifier - """ - return self._app_inst_identifier - - @app_inst_identifier.setter - def app_inst_identifier(self, app_inst_identifier: InstanceIdentifier): - """Sets the app_inst_identifier of this InlineResponse202. - - - :param app_inst_identifier: The app_inst_identifier of this InlineResponse202. - :type app_inst_identifier: InstanceIdentifier - """ - if app_inst_identifier is None: - raise ValueError("Invalid value for `app_inst_identifier`, must not be `None`") # noqa: E501 - - self._app_inst_identifier = app_inst_identifier diff --git a/src/models/instance_identifier.py b/src/models/instance_identifier.py deleted file mode 100644 index 7982b17ec7675ac9498da62045ff2a296430eca3..0000000000000000000000000000000000000000 --- a/src/models/instance_identifier.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class InstanceIdentifier(Model): - def __init__(self): # noqa: E501 - """InstanceIdentifier - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'InstanceIdentifier': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The InstanceIdentifier of this InstanceIdentifier. # noqa: E501 - :rtype: InstanceIdentifier - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/instance_state.py b/src/models/instance_state.py deleted file mode 100644 index f88322ccdd360e0f504ad1df3422c61bebd96d7b..0000000000000000000000000000000000000000 --- a/src/models/instance_state.py +++ /dev/null @@ -1,54 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class InstanceState(Model): - """ - allowed enum values - """ - PENDING = "PENDING" - READY = "READY" - FAILED = "FAILED" - TERMINATING = "TERMINATING" - - def __init__(self): # noqa: E501 - """InstanceState - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'InstanceState': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The InstanceState of this InstanceState. # noqa: E501 - :rtype: InstanceState - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/interface_details.py b/src/models/interface_details.py deleted file mode 100644 index 11aab88c9782c3d08e50151fd80ce5139c0e754b..0000000000000000000000000000000000000000 --- a/src/models/interface_details.py +++ /dev/null @@ -1,238 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import re # noqa: F401,E501 -import util - - -class InterfaceDetails(Model): - def __init__(self, interface_id: str=None, comm_protocol: str=None, comm_port: int=None, visibility_type: str=None, network: str=None, interface_name: str=None): # noqa: E501 - """InterfaceDetails - a model defined in Swagger - - :param interface_id: The interface_id of this InterfaceDetails. # noqa: E501 - :type interface_id: str - :param comm_protocol: The comm_protocol of this InterfaceDetails. # noqa: E501 - :type comm_protocol: str - :param comm_port: The comm_port of this InterfaceDetails. # noqa: E501 - :type comm_port: int - :param visibility_type: The visibility_type of this InterfaceDetails. # noqa: E501 - :type visibility_type: str - :param network: The network of this InterfaceDetails. # noqa: E501 - :type network: str - :param interface_name: The interface_name of this InterfaceDetails. # noqa: E501 - :type interface_name: str - """ - self.swagger_types = { - 'interface_id': str, - 'comm_protocol': str, - 'comm_port': int, - 'visibility_type': str, - 'network': str, - 'interface_name': str - } - - self.attribute_map = { - 'interface_id': 'interfaceId', - 'comm_protocol': 'commProtocol', - 'comm_port': 'commPort', - 'visibility_type': 'visibilityType', - 'network': 'network', - 'interface_name': 'InterfaceName' - } - self._interface_id = interface_id - self._comm_protocol = comm_protocol - self._comm_port = comm_port - self._visibility_type = visibility_type - self._network = network - self._interface_name = interface_name - - @classmethod - def from_dict(cls, dikt) -> 'InterfaceDetails': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The InterfaceDetails of this InterfaceDetails. # noqa: E501 - :rtype: InterfaceDetails - """ - return util.deserialize_model(dikt, cls) - - @property - def interface_id(self) -> str: - """Gets the interface_id of this InterfaceDetails. - - Each Port and corresponding traffic protocol exposed by the component is identified by a name. Application client on user device requires this to uniquely identify the interface. # noqa: E501 - - :return: The interface_id of this InterfaceDetails. - :rtype: str - """ - return self._interface_id - - @interface_id.setter - def interface_id(self, interface_id: str): - """Sets the interface_id of this InterfaceDetails. - - Each Port and corresponding traffic protocol exposed by the component is identified by a name. Application client on user device requires this to uniquely identify the interface. # noqa: E501 - - :param interface_id: The interface_id of this InterfaceDetails. - :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 comm_protocol(self) -> str: - """Gets the comm_protocol of this InterfaceDetails. - - Defines the IP transport communication protocol i.e., TCP, UDP or HTTP # noqa: E501 - - :return: The comm_protocol of this InterfaceDetails. - :rtype: str - """ - return self._comm_protocol - - @comm_protocol.setter - def comm_protocol(self, comm_protocol: str): - """Sets the comm_protocol of this InterfaceDetails. - - Defines the IP transport communication protocol i.e., TCP, UDP or HTTP # noqa: E501 - - :param comm_protocol: The comm_protocol of this InterfaceDetails. - :type comm_protocol: str - """ - allowed_values = ["TCP", "UDP", "HTTP_HTTPS"] # noqa: E501 - if comm_protocol not in allowed_values: - raise ValueError( - "Invalid value for `comm_protocol` ({0}), must be one of {1}" - .format(comm_protocol, allowed_values) - ) - - self._comm_protocol = comm_protocol - - @property - def comm_port(self) -> int: - """Gets the comm_port of this InterfaceDetails. - - Port number exposed by the component. OP may generate a dynamic port towards the UCs corresponding to this internal port and forward the client traffic from dynamic port to container Port. # noqa: E501 - - :return: The comm_port of this InterfaceDetails. - :rtype: int - """ - return self._comm_port - - @comm_port.setter - def comm_port(self, comm_port: int): - """Sets the comm_port of this InterfaceDetails. - - Port number exposed by the component. OP may generate a dynamic port towards the UCs corresponding to this internal port and forward the client traffic from dynamic port to container Port. # noqa: E501 - - :param comm_port: The comm_port of this InterfaceDetails. - :type comm_port: int - """ - if comm_port is None: - raise ValueError("Invalid value for `comm_port`, must not be `None`") # noqa: E501 - - self._comm_port = comm_port - - @property - def visibility_type(self) -> str: - """Gets the visibility_type of this InterfaceDetails. - - 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 internal container Port # noqa: E501 - - :return: The visibility_type of this InterfaceDetails. - :rtype: str - """ - return self._visibility_type - - @visibility_type.setter - def visibility_type(self, visibility_type: str): - """Sets the visibility_type of this InterfaceDetails. - - 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 internal container Port # noqa: E501 - - :param visibility_type: The visibility_type of this InterfaceDetails. - :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 - - @property - def network(self) -> str: - """Gets the network of this InterfaceDetails. - - Name of the network. In case the application has to be associated with more than 1 network then app provider must define the name of the network on which this interface has to be exposed. This parameter is required only if the port has to be exposed on a specific network other than default. # noqa: E501 - - :return: The network of this InterfaceDetails. - :rtype: str - """ - return self._network - - @network.setter - def network(self, network: str): - """Sets the network of this InterfaceDetails. - - Name of the network. In case the application has to be associated with more than 1 network then app provider must define the name of the network on which this interface has to be exposed. This parameter is required only if the port has to be exposed on a specific network other than default. # noqa: E501 - - :param network: The network of this InterfaceDetails. - :type network: str - """ - - self._network = network - - @property - def interface_name(self) -> str: - """Gets the interface_name of this InterfaceDetails. - - Interface Name. Required only if application has to be attached to a network other than default. # noqa: E501 - - :return: The interface_name of this InterfaceDetails. - :rtype: str - """ - return self._interface_name - - @interface_name.setter - def interface_name(self, interface_name: str): - """Sets the interface_name of this InterfaceDetails. - - Interface Name. Required only if application has to be attached to a network other than default. # noqa: E501 - - :param interface_name: The interface_name of this InterfaceDetails. - :type interface_name: str - """ - - self._interface_name = interface_name - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/invalid_param.py b/src/models/invalid_param.py deleted file mode 100644 index 7fd6cbe4f9d12221e12a62062b7a97c0cde27629..0000000000000000000000000000000000000000 --- a/src/models/invalid_param.py +++ /dev/null @@ -1,100 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class InvalidParam(Model): - def __init__(self, param: str=None, reason: str=None): # noqa: E501 - """InvalidParam - a model defined in Swagger - - :param param: The param of this InvalidParam. # noqa: E501 - :type param: str - :param reason: The reason of this InvalidParam. # noqa: E501 - :type reason: str - """ - self.swagger_types = { - 'param': str, - 'reason': str - } - - self.attribute_map = { - 'param': 'param', - 'reason': 'reason' - } - self._param = param - self._reason = reason - - @classmethod - def from_dict(cls, dikt) -> 'InvalidParam': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The InvalidParam of this InvalidParam. # noqa: E501 - :rtype: InvalidParam - """ - return util.deserialize_model(dikt, cls) - - @property - def param(self) -> str: - """Gets the param of this InvalidParam. - - - :return: The param of this InvalidParam. - :rtype: str - """ - return self._param - - @param.setter - def param(self, param: str): - """Sets the param of this InvalidParam. - - - :param param: The param of this InvalidParam. - :type param: str - """ - if param is None: - raise ValueError("Invalid value for `param`, must not be `None`") # noqa: E501 - - self._param = param - - @property - def reason(self) -> str: - """Gets the reason of this InvalidParam. - - - :return: The reason of this InvalidParam. - :rtype: str - """ - return self._reason - - @reason.setter - def reason(self, reason: str): - """Sets the reason of this InvalidParam. - - - :param reason: The reason of this InvalidParam. - :type reason: str - """ - - self._reason = reason diff --git a/src/models/ipv4_addr.py b/src/models/ipv4_addr.py deleted file mode 100644 index 494039f296e303bd72448b67244ca452415451aa..0000000000000000000000000000000000000000 --- a/src/models/ipv4_addr.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Ipv4Addr(Model): - 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/src/models/ipv6_addr.py b/src/models/ipv6_addr.py deleted file mode 100644 index ce281c61aad933f605270aa815d2029e109eca2c..0000000000000000000000000000000000000000 --- a/src/models/ipv6_addr.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Ipv6Addr(Model): - 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/src/models/mcc.py b/src/models/mcc.py deleted file mode 100644 index e5676fc3865e8f8f2ff5b5c766aa62a4aeef4fe3..0000000000000000000000000000000000000000 --- a/src/models/mcc.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Mcc(Model): - def __init__(self): # noqa: E501 - """Mcc - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'Mcc': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Mcc of this Mcc. # noqa: E501 - :rtype: Mcc - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/mnc.py b/src/models/mnc.py deleted file mode 100644 index 5e4f1f335a3cacb54ba31c7a9cc52001d4943ce2..0000000000000000000000000000000000000000 --- a/src/models/mnc.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Mnc(Model): - def __init__(self): # noqa: E501 - """Mnc - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'Mnc': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Mnc of this Mnc. # noqa: E501 - :rtype: Mnc - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/mobile_network_ids.py b/src/models/mobile_network_ids.py deleted file mode 100644 index 3df33f9cf7f32fc33977f566506901e43b300389..0000000000000000000000000000000000000000 --- a/src/models/mobile_network_ids.py +++ /dev/null @@ -1,108 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.mcc import Mcc # noqa: F401,E501 -from models.mnc import Mnc # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class MobileNetworkIds(Model): - def __init__(self, mcc: Mcc=None, mncs: List[Mnc]=None): # noqa: E501 - """MobileNetworkIds - a model defined in Swagger - - :param mcc: The mcc of this MobileNetworkIds. # noqa: E501 - :type mcc: Mcc - :param mncs: The mncs of this MobileNetworkIds. # noqa: E501 - :type mncs: List[Mnc] - """ - self.swagger_types = { - 'mcc': Mcc, - 'mncs': List[Mnc] - } - - self.attribute_map = { - 'mcc': 'mcc', - 'mncs': 'mncs' - } - self._mcc = mcc - self._mncs = mncs - - @classmethod - def from_dict(cls, dikt) -> 'MobileNetworkIds': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The MobileNetworkIds of this MobileNetworkIds. # noqa: E501 - :rtype: MobileNetworkIds - """ - return util.deserialize_model(dikt, cls) - - @property - def mcc(self) -> Mcc: - """Gets the mcc of this MobileNetworkIds. - - - :return: The mcc of this MobileNetworkIds. - :rtype: Mcc - """ - return self._mcc - - @mcc.setter - def mcc(self, mcc: Mcc): - """Sets the mcc of this MobileNetworkIds. - - - :param mcc: The mcc of this MobileNetworkIds. - :type mcc: Mcc - """ - - self._mcc = mcc - - @property - def mncs(self) -> List[Mnc]: - """Gets the mncs of this MobileNetworkIds. - - - :return: The mncs of this MobileNetworkIds. - :rtype: List[Mnc] - """ - return self._mncs - - @mncs.setter - def mncs(self, mncs: List[Mnc]): - """Sets the mncs of this MobileNetworkIds. - - - :param mncs: The mncs of this MobileNetworkIds. - :type mncs: List[Mnc] - """ - - self._mncs = mncs - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/mongo_document.py b/src/models/mongo_document.py deleted file mode 100644 index 64d1c1a2fc7a33f7765c3dc1835a853f970f83fa..0000000000000000000000000000000000000000 --- a/src/models/mongo_document.py +++ /dev/null @@ -1,319 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from mongoengine import (Document, DateTimeField, ReferenceField, StringField, ListField, IntField, - FloatField, BooleanField) - - -##################### -# Operator Platform # -##################### -class OriginatingOperatorPlatform(Document): - orig_op_federation_id = StringField() - orig_op_country_code = StringField() - orig_op_mobile_network_codes_mcc = StringField() - orig_op_mobile_network_codes_mncs = ListField(StringField()) - orig_op_fixed_network_codes = ListField(StringField()) - initial_date = DateTimeField() - partner_status_link = StringField() - partner_callback_credentials_token_url = StringField() - partner_callback_credentials_client_id = StringField() - partner_callback_credentials_client_secret = StringField() - partner_bearer_token = StringField(required=True) - - -class OriginatingOperatorPlatformUpdate(Document): - object_type = StringField() - operation_type = StringField() - modification_date = DateTimeField() - add_mobile_network_ids_mcc = StringField() - add_mobile_network_ids_mncs = ListField(StringField()) - remove_mobile_network_ids_mcc = StringField() - remove_mobile_network_ids_mncs = ListField(StringField()) - add_fixed_network_ids = ListField(StringField()) - remove_fixed_network_ids = ListField(StringField()) - federation_context_id = ReferenceField(OriginatingOperatorPlatform) - - -class OriginatingOperatorPlatformOriginatingOP(Document): - orig_op_federation_id = StringField() - orig_op_country_code = StringField() - orig_op_mobile_network_codes_mcc = StringField() - orig_op_mobile_network_codes_mncs = ListField(StringField()) - orig_op_fixed_network_codes = ListField(StringField()) - initial_date = DateTimeField() - partner_status_link = StringField() - partner_callback_credentials_token_url = StringField() - partner_callback_credentials_client_id = StringField() - partner_callback_credentials_client_secret = StringField() - partner_bearer_token = StringField(required=True) - partner_federation_id = StringField() - - -class OriginatingOperatorPlatformUpdateOriginatingOP(Document): - object_type = StringField() - operation_type = StringField() - modification_date = DateTimeField() - add_mobile_network_ids_mcc = StringField() - add_mobile_network_ids_mncs = ListField(StringField()) - remove_mobile_network_ids_mcc = StringField() - remove_mobile_network_ids_mncs = ListField(StringField()) - add_fixed_network_ids = ListField(StringField()) - remove_fixed_network_ids = ListField(StringField()) - federation_context_id = ReferenceField(OriginatingOperatorPlatformOriginatingOP) - partner_federation_id = StringField() - - -###################### -# Availability Zones # -###################### -class OriginatingZoneInfo(Document): - orig_zi_federation_context_id = StringField() - orig_zi_acceptedAvailabilityZones = ListField(StringField()) - orig_zi_availZoneNotifLink = StringField() - - -class OriginatingZoneInfoOriginatingOP(Document): - orig_zi_federation_context_id = StringField() - orig_zi_acceptedAvailabilityZones = ListField(StringField()) - orig_zi_availZoneNotifLink = StringField() - partner_federation_id = StringField() - - -####################### -# Artefact Management # -####################### -class ExposedInterfaces(Document): - orig_ei_interface_id = StringField() - orig_ei_comm_protocol = StringField() - orig_ei_comm_port = IntField() - orig_ei_visibility_type = StringField() - orig_ei_network = StringField() - orig_ei_interface_name = StringField() - - -class Gpu(Document): - orig_g_gpu_vendor_type = StringField() - orig_g_gpu_mode_name = StringField() - orig_g_gpu_memory = IntField() - orig_g_num_gpu = IntField() - - -class HugePages(Document): - orig_h_page_size = StringField() - orig_h_number = IntField() - - -class CompEnvParams(Document): - orig_cep_env_var_name = StringField() - orig_cep_env_value_type = StringField() - orig_cep_env_var_value = StringField() - orig_cep_env_var_src = StringField() - - -class PersistentVolumes(Document): - orig_pv_volume_size = StringField() - orig_pv_volume_mounth_path = StringField() - orig_pv_volume_name = StringField() - orig_pv_ephemeral_type = BooleanField() - orig_pv_access_mode = StringField() - orig_pv_sharing_policy = StringField() - - -class ComponentSpec(Document): - orig_ce_component_name = StringField() - orig_ce_component_spec_images = ListField(StringField()) - orig_ce_component_spec_num_of_instances = IntField() - orig_ce_component_spec_restart_policy = StringField() - orig_ce_component_spec_command_line_params_command = ListField(StringField()) - orig_ce_component_spec_command_line_params_command_args = ListField(StringField()) - orig_ce_component_spec_exposed_interfaces = ListField(ReferenceField(ExposedInterfaces)) - orig_ce_component_spec_compute_resource_profile_cpuarchtype = StringField() - orig_ce_component_spec_compute_resource_profile_numcpu_whole = StringField() - orig_ce_component_spec_compute_resource_profile_numcpu_decimal = FloatField() - orig_ce_component_spec_compute_resource_profile_numcpu_millivcpu = StringField() - orig_ce_component_spec_compute_resource_profile_memory = IntField() - orig_ce_component_spec_compute_resource_profile_diskstorage = IntField() - orig_ce_component_spec_compute_resource_profile_gpu = ListField(ReferenceField(Gpu)) - orig_ce_component_spec_compute_resource_profile_vpu = IntField() - orig_ce_component_spec_compute_resource_profile_fpga = IntField() - orig_ce_component_spec_compute_resource_profile_hugepages = ListField(ReferenceField(HugePages)) - orig_ce_component_spec_compute_resource_profile_cpuexclusivity = BooleanField() - orig_ce_component_spec_comp_env_params = ListField(ReferenceField(CompEnvParams)) - orig_ce_component_spec_deployment_config_config_type = StringField() - orig_ce_component_spec_deployment_config_contents = StringField() - orig_ce_component_spec_persistent_volumes = ListField(ReferenceField(PersistentVolumes)) - - -class OriginatingArtefactManagement(Document): - orig_am_federation_context_id = StringField() - orig_am_artefact_id = StringField() - orig_am_app_provider_id = StringField() - orig_am_artefact_name = StringField() - orig_am_artefact_version_info = StringField() - orig_am_artefact_description = StringField() - orig_am_artefact_virt_type = StringField() - orig_am_artefact_filename = StringField() - orig_am_artefact_file_format = StringField() - orig_am_artefact_descriptor_type = StringField() - orig_am_repo_type = StringField() - orig_am_artefact_repo_location_repo_url = StringField() - orig_am_artefact_repo_location_user_name = StringField() - orig_am_artefact_repo_location_password = StringField() - orig_am_artefact_repo_location_token = StringField() - orig_am_artefact_file = StringField() - orig_am_component_spec = StringField() - #orig_am_component_spec = ListField(ReferenceField(ComponentSpec)) - - -class OriginatingArtefactManagementOriginatingOP(Document): - orig_am_federation_context_id = StringField() - orig_am_artefact_id = StringField() - orig_am_app_provider_id = StringField() - orig_am_artefact_name = StringField() - orig_am_artefact_version_info = StringField() - orig_am_artefact_description = StringField() - orig_am_artefact_virt_type = StringField() - orig_am_artefact_filename = StringField() - orig_am_artefact_file_format = StringField() - orig_am_artefact_descriptor_type = StringField() - orig_am_repo_type = StringField() - orig_am_artefact_repo_location_repo_url = StringField() - orig_am_artefact_repo_location_user_name = StringField() - orig_am_artefact_repo_location_password = StringField() - orig_am_artefact_repo_location_token = StringField() - orig_am_artefact_file = StringField() - orig_am_component_spec = StringField() - partner_federation_id = StringField() - - -class OriginatingArtefactFileManagement(Document): - orig_af_federation_context_id = StringField() - orig_af_file_id = StringField() - orig_af_app_provider_id = StringField() - orig_af_file_name = StringField() - orig_af_file_description = StringField() - orig_af_file_version_info = StringField() - orig_af_file_type = StringField() - orig_af_checksum = StringField() - orig_af_img_os_type_architecture = StringField() - orig_af_img_os_type_distribution = StringField() - orig_af_img_os_type_version = StringField() - orig_af_img_os_type_license = StringField() - orig_af_img_ins_set_arch = StringField() - orig_af_repo_type = StringField() - orig_af_file_repo_location_repo_url = StringField() - orig_af_file_repo_location_user_name = StringField() - orig_af_file_repo_location_password = StringField() - orig_af_file_repo_location_token = StringField() - orig_af_file = StringField() - - -##################################### -# Application Onboarding Management # -##################################### -class OriginatingApplicationOnboardingManagement(Document): - orig_ao_federation_context_id = StringField() - orig_ao_app_id = StringField() - orig_ao_app_provider_id = StringField() - orig_ao_app_deployment_zones = ListField(StringField()) - orig_ao_app_meta_data_app_name = StringField() - orig_ao_app_meta_data_version = StringField() - orig_ao_app_meta_data_app_description = StringField() - orig_ao_app_meta_data_mobility_support = BooleanField() - orig_ao_app_meta_data_access_token = StringField() - orig_ao_app_meta_data_category = StringField() - orig_ao_app_qos_profile_latency_constraints = StringField() - orig_ao_app_qos_profile_bandwidth_required = IntField() - orig_ao_app_qos_profile_multi_user_clients = StringField() - orig_ao_app_qos_profile_no_of_users_per_app_inst = IntField() - orig_ao_app_qos_profile_app_provisioning = BooleanField() - orig_ao_app_component_specs = StringField() - orig_ao_app_status_callback_link = StringField() - - -class OriginatingApplicationOnboardingManagementUpdate(Document): - app_qos_profile_latency_constraints = StringField() - app_qos_profile_bandwidth_required = IntField() - app_qos_profile_multi_user_clients = StringField() - app_qos_profile_no_of_users_per_app_inst = IntField() - app_qos_profile_app_provisioning = BooleanField() - app_qos_profile_mobility_support = BooleanField() - app_component_specs = StringField() - federation_context_app_id = ReferenceField(OriginatingApplicationOnboardingManagement) - - -class OriginatingApplicationOnboardingManagementOriginatingOP(Document): - orig_ao_federation_context_id = StringField() - orig_ao_app_id = StringField() - orig_ao_app_provider_id = StringField() - orig_ao_app_deployment_zones = ListField(StringField()) - orig_ao_app_meta_data_app_name = StringField() - orig_ao_app_meta_data_version = StringField() - orig_ao_app_meta_data_app_description = StringField() - orig_ao_app_meta_data_mobility_support = BooleanField() - orig_ao_app_meta_data_access_token = StringField() - orig_ao_app_meta_data_category = StringField() - orig_ao_app_qos_profile_latency_constraints = StringField() - orig_ao_app_qos_profile_bandwidth_required = IntField() - orig_ao_app_qos_profile_multi_user_clients = StringField() - orig_ao_app_qos_profile_no_of_users_per_app_inst = IntField() - orig_ao_app_qos_profile_app_provisioning = BooleanField() - orig_ao_app_component_specs = StringField() - orig_ao_app_status_callback_link = StringField() - partner_federation_id = StringField() - - -class OriginatingApplicationOnboardingManagementUpdateOriginatingOP(Document): - app_qos_profile_latency_constraints = StringField() - app_qos_profile_bandwidth_required = IntField() - app_qos_profile_multi_user_clients = StringField() - app_qos_profile_no_of_users_per_app_inst = IntField() - app_qos_profile_app_provisioning = BooleanField() - app_qos_profile_mobility_support = BooleanField() - app_component_specs = StringField() - federation_context_app_id = ReferenceField(OriginatingApplicationOnboardingManagementOriginatingOP) - partner_federation_id = StringField() - - -##################################### -# Application Deployment Management # -##################################### -class OriginatingApplicationDeploymentManagement(Document): - orig_ad_federation_context_id = StringField() - orig_ad_instance_id = StringField() - orig_ad_app_id = StringField() - orig_ad_app_version = StringField() - orig_ad_app_provider_id = StringField() - orig_ad_zone_info_zone_id = StringField() - orig_ad_zone_info_flavour_id = StringField() - orig_ad_zone_info_resource_consumption = StringField() - orig_ad_zone_info_res_pool = StringField() - orig_ad_app_inst_callback_link = StringField() - - -class OriginatingApplicationDeploymentManagementOriginatingOP(Document): - orig_ad_federation_context_id = StringField() - orig_ad_instance_id = StringField() - orig_ad_app_id = StringField() - orig_ad_app_version = StringField() - orig_ad_app_provider_id = StringField() - orig_ad_zone_info_zone_id = StringField() - orig_ad_zone_info_flavour_id = StringField() - orig_ad_zone_info_resource_consumption = StringField() - orig_ad_zone_info_res_pool = StringField() - orig_ad_app_inst_callback_link = StringField() - partner_federation_id = StringField() diff --git a/src/models/object_repo_location.py b/src/models/object_repo_location.py deleted file mode 100644 index 89f5c6ef404748df430790cf256d190d5aa7fc0e..0000000000000000000000000000000000000000 --- a/src/models/object_repo_location.py +++ /dev/null @@ -1,164 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.uri import Uri # noqa: F401,E501 -import util - - -class ObjectRepoLocation(Model): - def __init__(self, repo_url: Uri=None, user_name: str=None, password: str=None, token: str=None): # noqa: E501 - """ObjectRepoLocation - a model defined in Swagger - - :param repo_url: The repo_url of this ObjectRepoLocation. # noqa: E501 - :type repo_url: Uri - :param user_name: The user_name of this ObjectRepoLocation. # noqa: E501 - :type user_name: str - :param password: The password of this ObjectRepoLocation. # noqa: E501 - :type password: str - :param token: The token of this ObjectRepoLocation. # noqa: E501 - :type token: str - """ - self.swagger_types = { - 'repo_url': Uri, - 'user_name': str, - 'password': str, - 'token': str - } - - self.attribute_map = { - 'repo_url': 'repoURL', - 'user_name': 'userName', - 'password': 'password', - 'token': 'token' - } - self._repo_url = repo_url - self._user_name = user_name - self._password = password - self._token = token - - @classmethod - def from_dict(cls, dikt) -> 'ObjectRepoLocation': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ObjectRepoLocation of this ObjectRepoLocation. # noqa: E501 - :rtype: ObjectRepoLocation - """ - return util.deserialize_model(dikt, cls) - - @property - def repo_url(self) -> Uri: - """Gets the repo_url of this ObjectRepoLocation. - - - :return: The repo_url of this ObjectRepoLocation. - :rtype: Uri - """ - return self._repo_url - - @repo_url.setter - def repo_url(self, repo_url: Uri): - """Sets the repo_url of this ObjectRepoLocation. - - - :param repo_url: The repo_url of this ObjectRepoLocation. - :type repo_url: Uri - """ - - self._repo_url = repo_url - - @property - def user_name(self) -> str: - """Gets the user_name of this ObjectRepoLocation. - - Username to access the repository # noqa: E501 - - :return: The user_name of this ObjectRepoLocation. - :rtype: str - """ - return self._user_name - - @user_name.setter - def user_name(self, user_name: str): - """Sets the user_name of this ObjectRepoLocation. - - Username to access the repository # noqa: E501 - - :param user_name: The user_name of this ObjectRepoLocation. - :type user_name: str - """ - - self._user_name = user_name - - @property - def password(self) -> str: - """Gets the password of this ObjectRepoLocation. - - Password to access the repository # noqa: E501 - - :return: The password of this ObjectRepoLocation. - :rtype: str - """ - return self._password - - @password.setter - def password(self, password: str): - """Sets the password of this ObjectRepoLocation. - - Password to access the repository # noqa: E501 - - :param password: The password of this ObjectRepoLocation. - :type password: str - """ - - self._password = password - - @property - def token(self) -> str: - """Gets the token of this ObjectRepoLocation. - - Authorization token to access the repository # noqa: E501 - - :return: The token of this ObjectRepoLocation. - :rtype: str - """ - return self._token - - @token.setter - def token(self, token: str): - """Sets the token of this ObjectRepoLocation. - - Authorization token to access the repository # noqa: E501 - - :param token: The token of this ObjectRepoLocation. - :type token: str - """ - - self._token = token - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/os_type.py b/src/models/os_type.py deleted file mode 100644 index f065996c98060e00099849e331d1eb5f1fac95e3..0000000000000000000000000000000000000000 --- a/src/models/os_type.py +++ /dev/null @@ -1,174 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class OSType(Model): - def __init__(self, architecture: str=None, distribution: str=None, version: str=None, license: str=None): # noqa: E501 - """OSType - a model defined in Swagger - - :param architecture: The architecture of this OSType. # noqa: E501 - :type architecture: str - :param distribution: The distribution of this OSType. # noqa: E501 - :type distribution: str - :param version: The version of this OSType. # noqa: E501 - :type version: str - :param license: The license of this OSType. # noqa: E501 - :type license: str - """ - self.swagger_types = { - 'architecture': str, - 'distribution': str, - 'version': str, - 'license': str - } - - self.attribute_map = { - 'architecture': 'architecture', - 'distribution': 'distribution', - 'version': 'version', - 'license': 'license' - } - self._architecture = architecture - self._distribution = distribution - self._version = version - self._license = license - - @classmethod - def from_dict(cls, dikt) -> 'OSType': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The OSType of this OSType. # noqa: E501 - :rtype: OSType - """ - return util.deserialize_model(dikt, cls) - - @property - def architecture(self) -> str: - """Gets the architecture of this OSType. - - - :return: The architecture of this OSType. - :rtype: str - """ - return self._architecture - - @architecture.setter - def architecture(self, architecture: str): - """Sets the architecture of this OSType. - - - :param architecture: The architecture of this OSType. - :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 distribution(self) -> str: - """Gets the distribution of this OSType. - - - :return: The distribution of this OSType. - :rtype: str - """ - return self._distribution - - @distribution.setter - def distribution(self, distribution: str): - """Sets the distribution of this OSType. - - - :param distribution: The distribution of this OSType. - :type distribution: str - """ - allowed_values = ["RHEL", "UBUNTU", "COREOS", "FEDORA", "WINDOWS", "OTHER"] # noqa: E501 - if distribution not in allowed_values: - raise ValueError( - "Invalid value for `distribution` ({0}), must be one of {1}" - .format(distribution, allowed_values) - ) - - self._distribution = distribution - - @property - def version(self) -> str: - """Gets the version of this OSType. - - - :return: The version of this OSType. - :rtype: str - """ - return self._version - - @version.setter - def version(self, version: str): - """Sets the version of this OSType. - - - :param version: The version of this OSType. - :type version: str - """ - allowed_values = ["OS_VERSION_UBUNTU_2204_LTS", "OS_VERSION_RHEL_8", "OS_VERSION_RHEL_7", "OS_VERSION_DEBIAN_11", "OS_VERSION_COREOS_STABLE", "OS_MS_WINDOWS_2012_R2", "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 OSType. - - - :return: The license of this OSType. - :rtype: str - """ - return self._license - - @license.setter - def license(self, license: str): - """Sets the license of this OSType. - - - :param license: The license of this OSType. - :type license: str - """ - allowed_values = ["OS_LICENSE_TYPE_FREE", "OS_LICENSE_TYPE_ON_DEMAND", "NOT_SPECIFIED"] # 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/src/models/persistent_volume_details.py b/src/models/persistent_volume_details.py deleted file mode 100644 index ffccb5da3c8c9ad0ce790a67e9bc898b3af929a2..0000000000000000000000000000000000000000 --- a/src/models/persistent_volume_details.py +++ /dev/null @@ -1,243 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class PersistentVolumeDetails(Model): - def __init__(self, volume_size: str=None, volume_mount_path: str=None, volume_name: str=None, ephemeral_type: bool=False, access_mode: str='RW', sharing_policy: str='EXCLUSIVE'): # noqa: E501 - """PersistentVolumeDetails - a model defined in Swagger - - :param volume_size: The volume_size of this PersistentVolumeDetails. # noqa: E501 - :type volume_size: str - :param volume_mount_path: The volume_mount_path of this PersistentVolumeDetails. # noqa: E501 - :type volume_mount_path: str - :param volume_name: The volume_name of this PersistentVolumeDetails. # noqa: E501 - :type volume_name: str - :param ephemeral_type: The ephemeral_type of this PersistentVolumeDetails. # noqa: E501 - :type ephemeral_type: bool - :param access_mode: The access_mode of this PersistentVolumeDetails. # noqa: E501 - :type access_mode: str - :param sharing_policy: The sharing_policy of this PersistentVolumeDetails. # noqa: E501 - :type sharing_policy: str - """ - self.swagger_types = { - 'volume_size': str, - 'volume_mount_path': str, - 'volume_name': str, - 'ephemeral_type': bool, - 'access_mode': str, - 'sharing_policy': str - } - - self.attribute_map = { - 'volume_size': 'volumeSize', - 'volume_mount_path': 'volumeMountPath', - 'volume_name': 'volumeName', - 'ephemeral_type': 'ephemeralType', - 'access_mode': 'accessMode', - 'sharing_policy': 'sharingPolicy' - } - self._volume_size = volume_size - self._volume_mount_path = volume_mount_path - self._volume_name = volume_name - self._ephemeral_type = ephemeral_type - self._access_mode = access_mode - self._sharing_policy = sharing_policy - - @classmethod - def from_dict(cls, dikt) -> 'PersistentVolumeDetails': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The PersistentVolumeDetails of this PersistentVolumeDetails. # noqa: E501 - :rtype: PersistentVolumeDetails - """ - return util.deserialize_model(dikt, cls) - - @property - def volume_size(self) -> str: - """Gets the volume_size of this PersistentVolumeDetails. - - size of the volume given by user (10GB, 20GB, 50 GB or 100GB) # noqa: E501 - - :return: The volume_size of this PersistentVolumeDetails. - :rtype: str - """ - return self._volume_size - - @volume_size.setter - def volume_size(self, volume_size: str): - """Sets the volume_size of this PersistentVolumeDetails. - - size of the volume given by user (10GB, 20GB, 50 GB or 100GB) # noqa: E501 - - :param volume_size: The volume_size of this PersistentVolumeDetails. - :type volume_size: str - """ - allowed_values = ["10Gi", "20Gi", "50Gi", "100Gi"] # noqa: E501 - if volume_size not in allowed_values: - raise ValueError( - "Invalid value for `volume_size` ({0}), must be one of {1}" - .format(volume_size, allowed_values) - ) - - self._volume_size = volume_size - - @property - def volume_mount_path(self) -> str: - """Gets the volume_mount_path of this PersistentVolumeDetails. - - Defines the mount path of the volume # noqa: E501 - - :return: The volume_mount_path of this PersistentVolumeDetails. - :rtype: str - """ - return self._volume_mount_path - - @volume_mount_path.setter - def volume_mount_path(self, volume_mount_path: str): - """Sets the volume_mount_path of this PersistentVolumeDetails. - - Defines the mount path of the volume # noqa: E501 - - :param volume_mount_path: The volume_mount_path of this PersistentVolumeDetails. - :type volume_mount_path: str - """ - if volume_mount_path is None: - raise ValueError("Invalid value for `volume_mount_path`, must not be `None`") # noqa: E501 - - self._volume_mount_path = volume_mount_path - - @property - def volume_name(self) -> str: - """Gets the volume_name of this PersistentVolumeDetails. - - Human readable name for the volume # noqa: E501 - - :return: The volume_name of this PersistentVolumeDetails. - :rtype: str - """ - return self._volume_name - - @volume_name.setter - def volume_name(self, volume_name: str): - """Sets the volume_name of this PersistentVolumeDetails. - - Human readable name for the volume # noqa: E501 - - :param volume_name: The volume_name of this PersistentVolumeDetails. - :type volume_name: str - """ - if volume_name is None: - raise ValueError("Invalid value for `volume_name`, must not be `None`") # noqa: E501 - - self._volume_name = volume_name - - @property - def ephemeral_type(self) -> bool: - """Gets the ephemeral_type of this PersistentVolumeDetails. - - It indicates the ephemeral storage on the node and contents are not preserved if containers restarts # noqa: E501 - - :return: The ephemeral_type of this PersistentVolumeDetails. - :rtype: bool - """ - return self._ephemeral_type - - @ephemeral_type.setter - def ephemeral_type(self, ephemeral_type: bool): - """Sets the ephemeral_type of this PersistentVolumeDetails. - - It indicates the ephemeral storage on the node and contents are not preserved if containers restarts # noqa: E501 - - :param ephemeral_type: The ephemeral_type of this PersistentVolumeDetails. - :type ephemeral_type: bool - """ - - self._ephemeral_type = ephemeral_type - - @property - def access_mode(self) -> str: - """Gets the access_mode of this PersistentVolumeDetails. - - Values are RW (read/write) and RO (read-only)l # noqa: E501 - - :return: The access_mode of this PersistentVolumeDetails. - :rtype: str - """ - return self._access_mode - - @access_mode.setter - def access_mode(self, access_mode: str): - """Sets the access_mode of this PersistentVolumeDetails. - - Values are RW (read/write) and RO (read-only)l # noqa: E501 - - :param access_mode: The access_mode of this PersistentVolumeDetails. - :type access_mode: str - """ - allowed_values = ["RW", "RO"] # noqa: E501 - if access_mode not in allowed_values: - raise ValueError( - "Invalid value for `access_mode` ({0}), must be one of {1}" - .format(access_mode, allowed_values) - ) - - self._access_mode = access_mode - - @property - def sharing_policy(self) -> str: - """Gets the sharing_policy of this PersistentVolumeDetails. - - Exclusive or Shared. If shared, then in case of multiple containers same volume will be shared across the containers. # noqa: E501 - - :return: The sharing_policy of this PersistentVolumeDetails. - :rtype: str - """ - return self._sharing_policy - - @sharing_policy.setter - def sharing_policy(self, sharing_policy: str): - """Sets the sharing_policy of this PersistentVolumeDetails. - - Exclusive or Shared. If shared, then in case of multiple containers same volume will be shared across the containers. # noqa: E501 - - :param sharing_policy: The sharing_policy of this PersistentVolumeDetails. - :type sharing_policy: str - """ - allowed_values = ["EXCLUSIVE", "SHARED"] # noqa: E501 - if sharing_policy not in allowed_values: - raise ValueError( - "Invalid value for `sharing_policy` ({0}), must be one of {1}" - .format(sharing_policy, allowed_values) - ) - - self._sharing_policy = sharing_policy - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/port.py b/src/models/port.py deleted file mode 100644 index 4e0507843ad9236f35be160ccf18c88bdea4158b..0000000000000000000000000000000000000000 --- a/src/models/port.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Port(Model): - 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/src/models/problem_details.py b/src/models/problem_details.py deleted file mode 100644 index f86517d8a693eba4a8ba90ba3d44239bbff0803e..0000000000000000000000000000000000000000 --- a/src/models/problem_details.py +++ /dev/null @@ -1,151 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.invalid_param import InvalidParam # noqa: F401,E501 -import util - - -class ProblemDetails(Model): - def __init__(self, title: str=None, detail: str=None, cause: str=None, invalid_params: List[InvalidParam]=None): # noqa: E501 - """ProblemDetails - a model defined in Swagger - - :param title: The title of this ProblemDetails. # noqa: E501 - :type title: str - :param detail: The detail of this ProblemDetails. # noqa: E501 - :type detail: str - :param cause: The cause of this ProblemDetails. # noqa: E501 - :type cause: str - :param invalid_params: The invalid_params of this ProblemDetails. # noqa: E501 - :type invalid_params: List[InvalidParam] - """ - self.swagger_types = { - 'title': str, - 'detail': str, - 'cause': str, - 'invalid_params': List[InvalidParam] - } - - self.attribute_map = { - 'title': 'title', - 'detail': 'detail', - 'cause': 'cause', - 'invalid_params': 'invalidParams' - } - self._title = title - self._detail = detail - self._cause = cause - self._invalid_params = invalid_params - - @classmethod - def from_dict(cls, dikt) -> 'ProblemDetails': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ProblemDetails of this ProblemDetails. # noqa: E501 - :rtype: ProblemDetails - """ - return util.deserialize_model(dikt, cls) - - @property - def title(self) -> str: - """Gets the title of this ProblemDetails. - - - :return: The title of this ProblemDetails. - :rtype: str - """ - return self._title - - @title.setter - def title(self, title: str): - """Sets the title of this ProblemDetails. - - - :param title: The title of this ProblemDetails. - :type title: str - """ - - self._title = title - - @property - def detail(self) -> str: - """Gets the detail of this ProblemDetails. - - - :return: The detail of this ProblemDetails. - :rtype: str - """ - return self._detail - - @detail.setter - def detail(self, detail: str): - """Sets the detail of this ProblemDetails. - - - :param detail: The detail of this ProblemDetails. - :type detail: str - """ - - self._detail = detail - - @property - def cause(self) -> str: - """Gets the cause of this ProblemDetails. - - - :return: The cause of this ProblemDetails. - :rtype: str - """ - return self._cause - - @cause.setter - def cause(self, cause: str): - """Sets the cause of this ProblemDetails. - - - :param cause: The cause of this ProblemDetails. - :type cause: str - """ - - self._cause = cause - - @property - def invalid_params(self) -> List[InvalidParam]: - """Gets the invalid_params of this ProblemDetails. - - - :return: The invalid_params of this ProblemDetails. - :rtype: List[InvalidParam] - """ - return self._invalid_params - - @invalid_params.setter - def invalid_params(self, invalid_params: List[InvalidParam]): - """Sets the invalid_params of this ProblemDetails. - - - :param invalid_params: The invalid_params of this ProblemDetails. - :type invalid_params: List[InvalidParam] - """ - - self._invalid_params = invalid_params diff --git a/src/models/service_endpoint.py b/src/models/service_endpoint.py deleted file mode 100644 index b0198cd6601d08a1fe6ed86fda0c866f6d8634cb..0000000000000000000000000000000000000000 --- a/src/models/service_endpoint.py +++ /dev/null @@ -1,156 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.fqdn import Fqdn # noqa: F401,E501 -from models.ipv4_addr import Ipv4Addr # noqa: F401,E501 -from models.ipv6_addr import Ipv6Addr # noqa: F401,E501 -from models.port import Port # noqa: F401,E501 -import util - - -class ServiceEndpoint(Model): - def __init__(self, port: Port=None, fqdn: Fqdn=None, ipv4_addresses: List[Ipv4Addr]=None, ipv6_addresses: List[Ipv6Addr]=None): # noqa: E501 - """ServiceEndpoint - a model defined in Swagger - - :param port: The port of this ServiceEndpoint. # noqa: E501 - :type port: Port - :param fqdn: The fqdn of this ServiceEndpoint. # noqa: E501 - :type fqdn: Fqdn - :param ipv4_addresses: The ipv4_addresses of this ServiceEndpoint. # noqa: E501 - :type ipv4_addresses: List[Ipv4Addr] - :param ipv6_addresses: The ipv6_addresses of this ServiceEndpoint. # 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) -> 'ServiceEndpoint': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ServiceEndpoint of this ServiceEndpoint. # noqa: E501 - :rtype: ServiceEndpoint - """ - return util.deserialize_model(dikt, cls) - - @property - def port(self) -> Port: - """Gets the port of this ServiceEndpoint. - - - :return: The port of this ServiceEndpoint. - :rtype: Port - """ - return self._port - - @port.setter - def port(self, port: Port): - """Sets the port of this ServiceEndpoint. - - - :param port: The port of this ServiceEndpoint. - :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 ServiceEndpoint. - - - :return: The fqdn of this ServiceEndpoint. - :rtype: Fqdn - """ - return self._fqdn - - @fqdn.setter - def fqdn(self, fqdn: Fqdn): - """Sets the fqdn of this ServiceEndpoint. - - - :param fqdn: The fqdn of this ServiceEndpoint. - :type fqdn: Fqdn - """ - - self._fqdn = fqdn - - @property - def ipv4_addresses(self) -> List[Ipv4Addr]: - """Gets the ipv4_addresses of this ServiceEndpoint. - - - :return: The ipv4_addresses of this ServiceEndpoint. - :rtype: List[Ipv4Addr] - """ - return self._ipv4_addresses - - @ipv4_addresses.setter - def ipv4_addresses(self, ipv4_addresses: List[Ipv4Addr]): - """Sets the ipv4_addresses of this ServiceEndpoint. - - - :param ipv4_addresses: The ipv4_addresses of this ServiceEndpoint. - :type ipv4_addresses: List[Ipv4Addr] - """ - - self._ipv4_addresses = ipv4_addresses - - @property - def ipv6_addresses(self) -> List[Ipv6Addr]: - """Gets the ipv6_addresses of this ServiceEndpoint. - - - :return: The ipv6_addresses of this ServiceEndpoint. - :rtype: List[Ipv6Addr] - """ - return self._ipv6_addresses - - @ipv6_addresses.setter - def ipv6_addresses(self, ipv6_addresses: List[Ipv6Addr]): - """Sets the ipv6_addresses of this ServiceEndpoint. - - - :param ipv6_addresses: The ipv6_addresses of this ServiceEndpoint. - :type ipv6_addresses: List[Ipv6Addr] - """ - - self._ipv6_addresses = ipv6_addresses diff --git a/src/models/uri.py b/src/models/uri.py deleted file mode 100644 index 622eb3e1b453a6afd6053f2c5fc349123fe4050b..0000000000000000000000000000000000000000 --- a/src/models/uri.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Uri(Model): - 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/src/models/vcpu.py b/src/models/vcpu.py deleted file mode 100644 index 3d5341d543f30e225b95f41264e7e45287aabeeb..0000000000000000000000000000000000000000 --- a/src/models/vcpu.py +++ /dev/null @@ -1,53 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Vcpu(Model): - def __init__(self): # noqa: E501 - """Vcpu - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'Vcpu': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Vcpu of this Vcpu. # noqa: E501 - :rtype: Vcpu - """ - return util.deserialize_model(dikt, cls) - - def to_gsma_input(self): - return { - gsma_key: getattr(self, attr) - for attr, gsma_key in self.attribute_map.items() - if getattr(self, attr, None) is not None - } diff --git a/src/models/version.py b/src/models/version.py deleted file mode 100644 index ff824112cf413dc8f3eda30176e359631491543c..0000000000000000000000000000000000000000 --- a/src/models/version.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class Version(Model): - def __init__(self): # noqa: E501 - """Version - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'Version': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Version of this Version. # noqa: E501 - :rtype: Version - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/virt_image_type.py b/src/models/virt_image_type.py deleted file mode 100644 index 157bef2f88bd8bd4b8eea7f79a04720619855625..0000000000000000000000000000000000000000 --- a/src/models/virt_image_type.py +++ /dev/null @@ -1,53 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class VirtImageType(Model): - """ - allowed enum values - """ - QCOW2 = "QCOW2" - DOCKER = "DOCKER" - OVA = "OVA" - - def __init__(self): # noqa: E501 - """VirtImageType - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'VirtImageType': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The VirtImageType of this VirtImageType. # noqa: E501 - :rtype: VirtImageType - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/zone_details.py b/src/models/zone_details.py deleted file mode 100644 index e97a93ed777efbb8718549dd2685093bc830693a..0000000000000000000000000000000000000000 --- a/src/models/zone_details.py +++ /dev/null @@ -1,135 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.geo_location import GeoLocation # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ZoneDetails(Model): - def __init__(self, zone_id: ZoneIdentifier=None, geolocation: GeoLocation=None, geography_details: str=None): # noqa: E501 - """ZoneDetails - a model defined in Swagger - - :param zone_id: The zone_id of this ZoneDetails. # noqa: E501 - :type zone_id: ZoneIdentifier - :param geolocation: The geolocation of this ZoneDetails. # noqa: E501 - :type geolocation: GeoLocation - :param geography_details: The geography_details of this ZoneDetails. # noqa: E501 - :type geography_details: str - """ - self.swagger_types = { - 'zone_id': ZoneIdentifier, - 'geolocation': GeoLocation, - 'geography_details': str - } - - self.attribute_map = { - 'zone_id': 'zoneId', - 'geolocation': 'geolocation', - 'geography_details': 'geographyDetails' - } - self._zone_id = zone_id - self._geolocation = geolocation - self._geography_details = geography_details - - @classmethod - def from_dict(cls, dikt) -> 'ZoneDetails': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneDetails of this ZoneDetails. # noqa: E501 - :rtype: ZoneDetails - """ - return util.deserialize_model(dikt, cls) - - @property - def zone_id(self) -> ZoneIdentifier: - """Gets the zone_id of this ZoneDetails. - - - :return: The zone_id of this ZoneDetails. - :rtype: ZoneIdentifier - """ - return self._zone_id - - @zone_id.setter - def zone_id(self, zone_id: ZoneIdentifier): - """Sets the zone_id of this ZoneDetails. - - - :param zone_id: The zone_id of this ZoneDetails. - :type zone_id: ZoneIdentifier - """ - if zone_id is None: - raise ValueError("Invalid value for `zone_id`, must not be `None`") # noqa: E501 - - self._zone_id = zone_id - - @property - def geolocation(self) -> GeoLocation: - """Gets the geolocation of this ZoneDetails. - - - :return: The geolocation of this ZoneDetails. - :rtype: GeoLocation - """ - return self._geolocation - - @geolocation.setter - def geolocation(self, geolocation: GeoLocation): - """Sets the geolocation of this ZoneDetails. - - - :param geolocation: The geolocation of this ZoneDetails. - :type geolocation: GeoLocation - """ - if geolocation is None: - raise ValueError("Invalid value for `geolocation`, must not be `None`") # noqa: E501 - - self._geolocation = geolocation - - @property - def geography_details(self) -> str: - """Gets the geography_details of this ZoneDetails. - - Details about cities or state covered by the edge. Details about the type of locality for eg rural, urban, industrial etc. This information is defined in human readable form. # noqa: E501 - - :return: The geography_details of this ZoneDetails. - :rtype: str - """ - return self._geography_details - - @geography_details.setter - def geography_details(self, geography_details: str): - """Sets the geography_details of this ZoneDetails. - - Details about cities or state covered by the edge. Details about the type of locality for eg rural, urban, industrial etc. This information is defined in human readable form. # noqa: E501 - - :param geography_details: The geography_details of this ZoneDetails. - :type geography_details: str - """ - if geography_details is None: - raise ValueError("Invalid value for `geography_details`, must not be `None`") # noqa: E501 - - self._geography_details = geography_details diff --git a/src/models/zone_identifier.py b/src/models/zone_identifier.py deleted file mode 100644 index 9eabd9fbb373f44d4abf4fc6bd444526861bd3c9..0000000000000000000000000000000000000000 --- a/src/models/zone_identifier.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ZoneIdentifier(Model): - def __init__(self): # noqa: E501 - """ZoneIdentifier - a model defined in Swagger - - """ - self.swagger_types = { - } - - self.attribute_map = { - } - - @classmethod - def from_dict(cls, dikt) -> 'ZoneIdentifier': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneIdentifier of this ZoneIdentifier. # noqa: E501 - :rtype: ZoneIdentifier - """ - return util.deserialize_model(dikt, cls) diff --git a/src/models/zone_registered_data.py b/src/models/zone_registered_data.py deleted file mode 100644 index 69b82f08e1b50f125b10d1beafdc9b272f06feab..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data.py +++ /dev/null @@ -1,220 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.compute_resource_info import ComputeResourceInfo # noqa: F401,E501 -from models.flavour import Flavour # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -from models.zone_registered_data_network_resources import ZoneRegisteredDataNetworkResources # noqa: F401,E501 -from models.zone_registered_data_zone_service_level_objs_info import ZoneRegisteredDataZoneServiceLevelObjsInfo # noqa: F401,E501 -import re # noqa: F401,E501 -import util - - -class ZoneRegisteredData(Model): - def __init__(self, zone_id: ZoneIdentifier=None, reserved_compute_resources: List[ComputeResourceInfo]=None, compute_resource_quota_limits: List[ComputeResourceInfo]=None, flavours_supported: List[Flavour]=None, network_resources: ZoneRegisteredDataNetworkResources=None, zone_service_level_objs_info: ZoneRegisteredDataZoneServiceLevelObjsInfo=None): # noqa: E501 - """ZoneRegisteredData - a model defined in Swagger - - :param zone_id: The zone_id of this ZoneRegisteredData. # noqa: E501 - :type zone_id: ZoneIdentifier - :param reserved_compute_resources: The reserved_compute_resources of this ZoneRegisteredData. # noqa: E501 - :type reserved_compute_resources: List[ComputeResourceInfo] - :param compute_resource_quota_limits: The compute_resource_quota_limits of this ZoneRegisteredData. # noqa: E501 - :type compute_resource_quota_limits: List[ComputeResourceInfo] - :param flavours_supported: The flavours_supported of this ZoneRegisteredData. # noqa: E501 - :type flavours_supported: List[Flavour] - :param network_resources: The network_resources of this ZoneRegisteredData. # noqa: E501 - :type network_resources: ZoneRegisteredDataNetworkResources - :param zone_service_level_objs_info: The zone_service_level_objs_info of this ZoneRegisteredData. # noqa: E501 - :type zone_service_level_objs_info: ZoneRegisteredDataZoneServiceLevelObjsInfo - """ - self.swagger_types = { - 'zone_id': ZoneIdentifier, - 'reserved_compute_resources': List[ComputeResourceInfo], - 'compute_resource_quota_limits': List[ComputeResourceInfo], - 'flavours_supported': List[Flavour], - 'network_resources': ZoneRegisteredDataNetworkResources, - 'zone_service_level_objs_info': ZoneRegisteredDataZoneServiceLevelObjsInfo - } - - self.attribute_map = { - 'zone_id': 'zoneId', - 'reserved_compute_resources': 'reservedComputeResources', - 'compute_resource_quota_limits': 'computeResourceQuotaLimits', - 'flavours_supported': 'flavoursSupported', - 'network_resources': 'networkResources', - 'zone_service_level_objs_info': 'zoneServiceLevelObjsInfo' - } - self._zone_id = zone_id - self._reserved_compute_resources = reserved_compute_resources - self._compute_resource_quota_limits = compute_resource_quota_limits - self._flavours_supported = flavours_supported - self._network_resources = network_resources - self._zone_service_level_objs_info = zone_service_level_objs_info - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData of this ZoneRegisteredData. # noqa: E501 - :rtype: ZoneRegisteredData - """ - return util.deserialize_model(dikt, cls) - - @property - def zone_id(self) -> ZoneIdentifier: - """Gets the zone_id of this ZoneRegisteredData. - - - :return: The zone_id of this ZoneRegisteredData. - :rtype: ZoneIdentifier - """ - return self._zone_id - - @zone_id.setter - def zone_id(self, zone_id: ZoneIdentifier): - """Sets the zone_id of this ZoneRegisteredData. - - - :param zone_id: The zone_id of this ZoneRegisteredData. - :type zone_id: ZoneIdentifier - """ - if zone_id is None: - raise ValueError("Invalid value for `zone_id`, must not be `None`") # noqa: E501 - - self._zone_id = zone_id - - @property - def reserved_compute_resources(self) -> List[ComputeResourceInfo]: - """Gets the reserved_compute_resources of this ZoneRegisteredData. - - Resources exclusively reserved for the originator OP. # noqa: E501 - - :return: The reserved_compute_resources of this ZoneRegisteredData. - :rtype: List[ComputeResourceInfo] - """ - return self._reserved_compute_resources - - @reserved_compute_resources.setter - def reserved_compute_resources(self, reserved_compute_resources: List[ComputeResourceInfo]): - """Sets the reserved_compute_resources of this ZoneRegisteredData. - - Resources exclusively reserved for the originator OP. # noqa: E501 - - :param reserved_compute_resources: The reserved_compute_resources of this ZoneRegisteredData. - :type reserved_compute_resources: List[ComputeResourceInfo] - """ - if reserved_compute_resources is None: - raise ValueError("Invalid value for `reserved_compute_resources`, must not be `None`") # noqa: E501 - - self._reserved_compute_resources = reserved_compute_resources - - @property - def compute_resource_quota_limits(self) -> List[ComputeResourceInfo]: - """Gets the compute_resource_quota_limits of this ZoneRegisteredData. - - Max quota on resources partner OP allows over reserved resources. # noqa: E501 - - :return: The compute_resource_quota_limits of this ZoneRegisteredData. - :rtype: List[ComputeResourceInfo] - """ - return self._compute_resource_quota_limits - - @compute_resource_quota_limits.setter - def compute_resource_quota_limits(self, compute_resource_quota_limits: List[ComputeResourceInfo]): - """Sets the compute_resource_quota_limits of this ZoneRegisteredData. - - Max quota on resources partner OP allows over reserved resources. # noqa: E501 - - :param compute_resource_quota_limits: The compute_resource_quota_limits of this ZoneRegisteredData. - :type compute_resource_quota_limits: List[ComputeResourceInfo] - """ - if compute_resource_quota_limits is None: - raise ValueError("Invalid value for `compute_resource_quota_limits`, must not be `None`") # noqa: E501 - - self._compute_resource_quota_limits = compute_resource_quota_limits - - @property - def flavours_supported(self) -> List[Flavour]: - """Gets the flavours_supported of this ZoneRegisteredData. - - - :return: The flavours_supported of this ZoneRegisteredData. - :rtype: List[Flavour] - """ - return self._flavours_supported - - @flavours_supported.setter - def flavours_supported(self, flavours_supported: List[Flavour]): - """Sets the flavours_supported of this ZoneRegisteredData. - - - :param flavours_supported: The flavours_supported of this ZoneRegisteredData. - :type flavours_supported: List[Flavour] - """ - if flavours_supported is None: - raise ValueError("Invalid value for `flavours_supported`, must not be `None`") # noqa: E501 - - self._flavours_supported = flavours_supported - - @property - def network_resources(self) -> ZoneRegisteredDataNetworkResources: - """Gets the network_resources of this ZoneRegisteredData. - - - :return: The network_resources of this ZoneRegisteredData. - :rtype: ZoneRegisteredDataNetworkResources - """ - return self._network_resources - - @network_resources.setter - def network_resources(self, network_resources: ZoneRegisteredDataNetworkResources): - """Sets the network_resources of this ZoneRegisteredData. - - - :param network_resources: The network_resources of this ZoneRegisteredData. - :type network_resources: ZoneRegisteredDataNetworkResources - """ - - self._network_resources = network_resources - - @property - def zone_service_level_objs_info(self) -> ZoneRegisteredDataZoneServiceLevelObjsInfo: - """Gets the zone_service_level_objs_info of this ZoneRegisteredData. - - - :return: The zone_service_level_objs_info of this ZoneRegisteredData. - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfo - """ - return self._zone_service_level_objs_info - - @zone_service_level_objs_info.setter - def zone_service_level_objs_info(self, zone_service_level_objs_info: ZoneRegisteredDataZoneServiceLevelObjsInfo): - """Sets the zone_service_level_objs_info of this ZoneRegisteredData. - - - :param zone_service_level_objs_info: The zone_service_level_objs_info of this ZoneRegisteredData. - :type zone_service_level_objs_info: ZoneRegisteredDataZoneServiceLevelObjsInfo - """ - - self._zone_service_level_objs_info = zone_service_level_objs_info diff --git a/src/models/zone_registered_data_network_resources.py b/src/models/zone_registered_data_network_resources.py deleted file mode 100644 index e544beb21cd12383c0b3c35e2eb2ea04880bbec2..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data_network_resources.py +++ /dev/null @@ -1,166 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ZoneRegisteredDataNetworkResources(Model): - def __init__(self, egress_band_width: int=None, dedicated_nic: int=None, support_sriov: bool=None, support_dpdk: bool=None): # noqa: E501 - """ZoneRegisteredDataNetworkResources - a model defined in Swagger - - :param egress_band_width: The egress_band_width of this ZoneRegisteredDataNetworkResources. # noqa: E501 - :type egress_band_width: int - :param dedicated_nic: The dedicated_nic of this ZoneRegisteredDataNetworkResources. # noqa: E501 - :type dedicated_nic: int - :param support_sriov: The support_sriov of this ZoneRegisteredDataNetworkResources. # noqa: E501 - :type support_sriov: bool - :param support_dpdk: The support_dpdk of this ZoneRegisteredDataNetworkResources. # noqa: E501 - :type support_dpdk: bool - """ - self.swagger_types = { - 'egress_band_width': int, - 'dedicated_nic': int, - 'support_sriov': bool, - 'support_dpdk': bool - } - - self.attribute_map = { - 'egress_band_width': 'egressBandWidth', - 'dedicated_nic': 'dedicatedNIC', - 'support_sriov': 'supportSriov', - 'support_dpdk': 'supportDPDK' - } - self._egress_band_width = egress_band_width - self._dedicated_nic = dedicated_nic - self._support_sriov = support_sriov - self._support_dpdk = support_dpdk - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredDataNetworkResources': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData_networkResources of this ZoneRegisteredDataNetworkResources. # noqa: E501 - :rtype: ZoneRegisteredDataNetworkResources - """ - return util.deserialize_model(dikt, cls) - - @property - def egress_band_width(self) -> int: - """Gets the egress_band_width of this ZoneRegisteredDataNetworkResources. - - Max dl throughput that this edge can offer. It is defined in Mbps. # noqa: E501 - - :return: The egress_band_width of this ZoneRegisteredDataNetworkResources. - :rtype: int - """ - return self._egress_band_width - - @egress_band_width.setter - def egress_band_width(self, egress_band_width: int): - """Sets the egress_band_width of this ZoneRegisteredDataNetworkResources. - - Max dl throughput that this edge can offer. It is defined in Mbps. # noqa: E501 - - :param egress_band_width: The egress_band_width of this ZoneRegisteredDataNetworkResources. - :type egress_band_width: int - """ - if egress_band_width is None: - raise ValueError("Invalid value for `egress_band_width`, must not be `None`") # noqa: E501 - - self._egress_band_width = egress_band_width - - @property - def dedicated_nic(self) -> int: - """Gets the dedicated_nic of this ZoneRegisteredDataNetworkResources. - - Number of network interface cards which can be dedicatedly assigned to application pods on isolated networks. This includes virtual as well physical NICs # noqa: E501 - - :return: The dedicated_nic of this ZoneRegisteredDataNetworkResources. - :rtype: int - """ - return self._dedicated_nic - - @dedicated_nic.setter - def dedicated_nic(self, dedicated_nic: int): - """Sets the dedicated_nic of this ZoneRegisteredDataNetworkResources. - - Number of network interface cards which can be dedicatedly assigned to application pods on isolated networks. This includes virtual as well physical NICs # noqa: E501 - - :param dedicated_nic: The dedicated_nic of this ZoneRegisteredDataNetworkResources. - :type dedicated_nic: int - """ - if dedicated_nic is None: - raise ValueError("Invalid value for `dedicated_nic`, must not be `None`") # noqa: E501 - - self._dedicated_nic = dedicated_nic - - @property - def support_sriov(self) -> bool: - """Gets the support_sriov of this ZoneRegisteredDataNetworkResources. - - If this zone support SRIOV networks or not # noqa: E501 - - :return: The support_sriov of this ZoneRegisteredDataNetworkResources. - :rtype: bool - """ - return self._support_sriov - - @support_sriov.setter - def support_sriov(self, support_sriov: bool): - """Sets the support_sriov of this ZoneRegisteredDataNetworkResources. - - If this zone support SRIOV networks or not # noqa: E501 - - :param support_sriov: The support_sriov of this ZoneRegisteredDataNetworkResources. - :type support_sriov: bool - """ - if support_sriov is None: - raise ValueError("Invalid value for `support_sriov`, must not be `None`") # noqa: E501 - - self._support_sriov = support_sriov - - @property - def support_dpdk(self) -> bool: - """Gets the support_dpdk of this ZoneRegisteredDataNetworkResources. - - If this zone supports DPDK based networking. # noqa: E501 - - :return: The support_dpdk of this ZoneRegisteredDataNetworkResources. - :rtype: bool - """ - return self._support_dpdk - - @support_dpdk.setter - def support_dpdk(self, support_dpdk: bool): - """Sets the support_dpdk of this ZoneRegisteredDataNetworkResources. - - If this zone supports DPDK based networking. # noqa: E501 - - :param support_dpdk: The support_dpdk of this ZoneRegisteredDataNetworkResources. - :type support_dpdk: bool - """ - if support_dpdk is None: - raise ValueError("Invalid value for `support_dpdk`, must not be `None`") # noqa: E501 - - self._support_dpdk = support_dpdk diff --git a/src/models/zone_registered_data_zone_service_level_objs_info.py b/src/models/zone_registered_data_zone_service_level_objs_info.py deleted file mode 100644 index d1b8851c4c0bb3ea40fa5687022b007c5465b4ff..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data_zone_service_level_objs_info.py +++ /dev/null @@ -1,133 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.zone_registered_data_zone_service_level_objs_info_jitter_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges # noqa: F401,E501 -from models.zone_registered_data_zone_service_level_objs_info_latency_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges # noqa: F401,E501 -from models.zone_registered_data_zone_service_level_objs_info_throughput_ranges import ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges # noqa: F401,E501 -import util - - -class ZoneRegisteredDataZoneServiceLevelObjsInfo(Model): - def __init__(self, latency_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges=None, jitter_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges=None, throughput_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges=None): # noqa: E501 - """ZoneRegisteredDataZoneServiceLevelObjsInfo - a model defined in Swagger - - :param latency_ranges: The latency_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. # noqa: E501 - :type latency_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges - :param jitter_ranges: The jitter_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. # noqa: E501 - :type jitter_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges - :param throughput_ranges: The throughput_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. # noqa: E501 - :type throughput_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - """ - self.swagger_types = { - 'latency_ranges': ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges, - 'jitter_ranges': ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges, - 'throughput_ranges': ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - } - - self.attribute_map = { - 'latency_ranges': 'latencyRanges', - 'jitter_ranges': 'jitterRanges', - 'throughput_ranges': 'throughputRanges' - } - self._latency_ranges = latency_ranges - self._jitter_ranges = jitter_ranges - self._throughput_ranges = throughput_ranges - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredDataZoneServiceLevelObjsInfo': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData_zoneServiceLevelObjsInfo of this ZoneRegisteredDataZoneServiceLevelObjsInfo. # noqa: E501 - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfo - """ - return util.deserialize_model(dikt, cls) - - @property - def latency_ranges(self) -> ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges: - """Gets the latency_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :return: The latency_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges - """ - return self._latency_ranges - - @latency_ranges.setter - def latency_ranges(self, latency_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges): - """Sets the latency_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :param latency_ranges: The latency_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :type latency_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges - """ - if latency_ranges is None: - raise ValueError("Invalid value for `latency_ranges`, must not be `None`") # noqa: E501 - - self._latency_ranges = latency_ranges - - @property - def jitter_ranges(self) -> ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges: - """Gets the jitter_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :return: The jitter_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges - """ - return self._jitter_ranges - - @jitter_ranges.setter - def jitter_ranges(self, jitter_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges): - """Sets the jitter_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :param jitter_ranges: The jitter_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :type jitter_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges - """ - if jitter_ranges is None: - raise ValueError("Invalid value for `jitter_ranges`, must not be `None`") # noqa: E501 - - self._jitter_ranges = jitter_ranges - - @property - def throughput_ranges(self) -> ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges: - """Gets the throughput_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :return: The throughput_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - """ - return self._throughput_ranges - - @throughput_ranges.setter - def throughput_ranges(self, throughput_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges): - """Sets the throughput_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - - - :param throughput_ranges: The throughput_ranges of this ZoneRegisteredDataZoneServiceLevelObjsInfo. - :type throughput_ranges: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - """ - if throughput_ranges is None: - raise ValueError("Invalid value for `throughput_ranges`, must not be `None`") # noqa: E501 - - self._throughput_ranges = throughput_ranges diff --git a/src/models/zone_registered_data_zone_service_level_objs_info_jitter_ranges.py b/src/models/zone_registered_data_zone_service_level_objs_info_jitter_ranges.py deleted file mode 100644 index 977bf2e309b62cba236404ff453fd95be638c969..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data_zone_service_level_objs_info_jitter_ranges.py +++ /dev/null @@ -1,100 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges(Model): - def __init__(self, min_jitter: int=None, max_jitter: int=None): # noqa: E501 - """ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges - a model defined in Swagger - - :param min_jitter: The min_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. # noqa: E501 - :type min_jitter: int - :param max_jitter: The max_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. # noqa: E501 - :type max_jitter: int - """ - self.swagger_types = { - 'min_jitter': int, - 'max_jitter': int - } - - self.attribute_map = { - 'min_jitter': 'minJitter', - 'max_jitter': 'maxJitter' - } - self._min_jitter = min_jitter - self._max_jitter = max_jitter - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData_zoneServiceLevelObjsInfo_jitterRanges of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. # noqa: E501 - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges - """ - return util.deserialize_model(dikt, cls) - - @property - def min_jitter(self) -> int: - """Gets the min_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - - - :return: The min_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - :rtype: int - """ - return self._min_jitter - - @min_jitter.setter - def min_jitter(self, min_jitter: int): - """Sets the min_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - - - :param min_jitter: The min_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - :type min_jitter: int - """ - - self._min_jitter = min_jitter - - @property - def max_jitter(self) -> int: - """Gets the max_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - - The maximum limit of network jitter between UC and Edge App in milli seconds. # noqa: E501 - - :return: The max_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - :rtype: int - """ - return self._max_jitter - - @max_jitter.setter - def max_jitter(self, max_jitter: int): - """Sets the max_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - - The maximum limit of network jitter between UC and Edge App in milli seconds. # noqa: E501 - - :param max_jitter: The max_jitter of this ZoneRegisteredDataZoneServiceLevelObjsInfoJitterRanges. - :type max_jitter: int - """ - - self._max_jitter = max_jitter diff --git a/src/models/zone_registered_data_zone_service_level_objs_info_latency_ranges.py b/src/models/zone_registered_data_zone_service_level_objs_info_latency_ranges.py deleted file mode 100644 index 807879280b921e06abb7d8fbf82f1c0c8fef77f6..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data_zone_service_level_objs_info_latency_ranges.py +++ /dev/null @@ -1,102 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges(Model): - def __init__(self, min_latency: int=None, max_latency: int=None): # noqa: E501 - """ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges - a model defined in Swagger - - :param min_latency: The min_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. # noqa: E501 - :type min_latency: int - :param max_latency: The max_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. # noqa: E501 - :type max_latency: int - """ - self.swagger_types = { - 'min_latency': int, - 'max_latency': int - } - - self.attribute_map = { - 'min_latency': 'minLatency', - 'max_latency': 'maxLatency' - } - self._min_latency = min_latency - self._max_latency = max_latency - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData_zoneServiceLevelObjsInfo_latencyRanges of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. # noqa: E501 - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges - """ - return util.deserialize_model(dikt, cls) - - @property - def min_latency(self) -> int: - """Gets the min_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - - The time for data/packet to reach from UC to edge application. It represent mínimum latency in milli seconds that may exist between UCs and edge apps in this zone but it can be higher in actual. # noqa: E501 - - :return: The min_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - :rtype: int - """ - return self._min_latency - - @min_latency.setter - def min_latency(self, min_latency: int): - """Sets the min_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - - The time for data/packet to reach from UC to edge application. It represent mínimum latency in milli seconds that may exist between UCs and edge apps in this zone but it can be higher in actual. # noqa: E501 - - :param min_latency: The min_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - :type min_latency: int - """ - - self._min_latency = min_latency - - @property - def max_latency(self) -> int: - """Gets the max_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - - The maximum limit of latency between UC and Edge App in milli seconds. # noqa: E501 - - :return: The max_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - :rtype: int - """ - return self._max_latency - - @max_latency.setter - def max_latency(self, max_latency: int): - """Sets the max_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - - The maximum limit of latency between UC and Edge App in milli seconds. # noqa: E501 - - :param max_latency: The max_latency of this ZoneRegisteredDataZoneServiceLevelObjsInfoLatencyRanges. - :type max_latency: int - """ - - self._max_latency = max_latency diff --git a/src/models/zone_registered_data_zone_service_level_objs_info_throughput_ranges.py b/src/models/zone_registered_data_zone_service_level_objs_info_throughput_ranges.py deleted file mode 100644 index ad1a15e7e039dfd091a052c78b703dab15e72377..0000000000000000000000000000000000000000 --- a/src/models/zone_registered_data_zone_service_level_objs_info_throughput_ranges.py +++ /dev/null @@ -1,102 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -import util - - -class ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges(Model): - def __init__(self, min_throughput: int=None, max_throughput: int=None): # noqa: E501 - """ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - a model defined in Swagger - - :param min_throughput: The min_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. # noqa: E501 - :type min_throughput: int - :param max_throughput: The max_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. # noqa: E501 - :type max_throughput: int - """ - self.swagger_types = { - 'min_throughput': int, - 'max_throughput': int - } - - self.attribute_map = { - 'min_throughput': 'minThroughput', - 'max_throughput': 'maxThroughput' - } - self._min_throughput = min_throughput - self._max_throughput = max_throughput - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegisteredData_zoneServiceLevelObjsInfo_throughputRanges of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. # noqa: E501 - :rtype: ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges - """ - return util.deserialize_model(dikt, cls) - - @property - def min_throughput(self) -> int: - """Gets the min_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - - The minimum limit of network throughput between UC and Edge App in Mega bits per seconds (Mbps). # noqa: E501 - - :return: The min_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - :rtype: int - """ - return self._min_throughput - - @min_throughput.setter - def min_throughput(self, min_throughput: int): - """Sets the min_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - - The minimum limit of network throughput between UC and Edge App in Mega bits per seconds (Mbps). # noqa: E501 - - :param min_throughput: The min_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - :type min_throughput: int - """ - - self._min_throughput = min_throughput - - @property - def max_throughput(self) -> int: - """Gets the max_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - - The maximum limit of network throughput between UC and Edge App in Mega bits per seconds (Mbps). # noqa: E501 - - :return: The max_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - :rtype: int - """ - return self._max_throughput - - @max_throughput.setter - def max_throughput(self, max_throughput: int): - """Sets the max_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - - The maximum limit of network throughput between UC and Edge App in Mega bits per seconds (Mbps). # noqa: E501 - - :param max_throughput: The max_throughput of this ZoneRegisteredDataZoneServiceLevelObjsInfoThroughputRanges. - :type max_throughput: int - """ - - self._max_throughput = max_throughput diff --git a/src/models/zone_registration_request_data.py b/src/models/zone_registration_request_data.py deleted file mode 100644 index d0e7386dea5e6832d3485fdfa1b535f22b3b1709..0000000000000000000000000000000000000000 --- a/src/models/zone_registration_request_data.py +++ /dev/null @@ -1,120 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.uri import Uri # noqa: F401,E501 -from models.zone_identifier import ZoneIdentifier # noqa: F401,E501 -import util - - -class ZoneRegistrationRequestData(Model): - def __init__(self, accepted_availability_zones: List[ZoneIdentifier]=None, avail_zone_notif_link: Uri=None): # noqa: E501 - """ZoneRegistrationRequestData - a model defined in Swagger - - :param accepted_availability_zones: The accepted_availability_zones of this ZoneRegistrationRequestData. # noqa: E501 - :type accepted_availability_zones: List[ZoneIdentifier] - :param avail_zone_notif_link: The avail_zone_notif_link of this ZoneRegistrationRequestData. # noqa: E501 - :type avail_zone_notif_link: Uri - """ - self.swagger_types = { - 'accepted_availability_zones': List[ZoneIdentifier], - 'avail_zone_notif_link': Uri - } - - self.attribute_map = { - 'accepted_availability_zones': 'acceptedAvailabilityZones', - 'avail_zone_notif_link': 'availZoneNotifLink' - } - self._accepted_availability_zones = accepted_availability_zones - self._avail_zone_notif_link = avail_zone_notif_link - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegistrationRequestData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegistrationRequestData of this ZoneRegistrationRequestData. # noqa: E501 - :rtype: ZoneRegistrationRequestData - """ - return util.deserialize_model(dikt, cls) - - @property - def accepted_availability_zones(self) -> List[ZoneIdentifier]: - """Gets the accepted_availability_zones of this ZoneRegistrationRequestData. - - - :return: The accepted_availability_zones of this ZoneRegistrationRequestData. - :rtype: List[ZoneIdentifier] - """ - return self._accepted_availability_zones - - @accepted_availability_zones.setter - def accepted_availability_zones(self, accepted_availability_zones: List[ZoneIdentifier]): - """Sets the accepted_availability_zones of this ZoneRegistrationRequestData. - - - :param accepted_availability_zones: The accepted_availability_zones of this ZoneRegistrationRequestData. - :type accepted_availability_zones: List[ZoneIdentifier] - """ - if accepted_availability_zones is None: - raise ValueError("Invalid value for `accepted_availability_zones`, must not be `None`") # noqa: E501 - - self._accepted_availability_zones = accepted_availability_zones - - @property - def avail_zone_notif_link(self) -> Uri: - """Gets the avail_zone_notif_link of this ZoneRegistrationRequestData. - - - :return: The avail_zone_notif_link of this ZoneRegistrationRequestData. - :rtype: Uri - """ - return self._avail_zone_notif_link - - @avail_zone_notif_link.setter - def avail_zone_notif_link(self, avail_zone_notif_link: Uri): - """Sets the avail_zone_notif_link of this ZoneRegistrationRequestData. - - - :param avail_zone_notif_link: The avail_zone_notif_link of this ZoneRegistrationRequestData. - :type avail_zone_notif_link: Uri - """ - if avail_zone_notif_link is None: - raise ValueError("Invalid value for `avail_zone_notif_link`, must not be `None`") # noqa: E501 - - self._avail_zone_notif_link = avail_zone_notif_link - - def to_gsma_input(self): - result = {} - for attr, gsma_key in self.attribute_map.items(): - value = getattr(self, attr, None) - if value is None: - continue - if hasattr(value, "to_gsma_input"): - result[gsma_key] = value.to_gsma_input() - elif isinstance(value, list) and value and hasattr(value[0], "to_gsma_input"): - result[gsma_key] = [v.to_gsma_input() for v in value] - elif isinstance(value, (datetime, date)): - result[gsma_key] = value.isoformat() - else: - result[gsma_key] = value - return result diff --git a/src/models/zone_registration_response_data.py b/src/models/zone_registration_response_data.py deleted file mode 100644 index 4207950e537cb8ab300f9b52ada0a742d082ffa5..0000000000000000000000000000000000000000 --- a/src/models/zone_registration_response_data.py +++ /dev/null @@ -1,75 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -from datetime import date, datetime # noqa: F401 - -from typing import List, Dict # noqa: F401 - -from models.base_model_ import Model -from models.zone_registered_data import ZoneRegisteredData # noqa: F401,E501 -import util - - -class ZoneRegistrationResponseData(Model): - def __init__(self, accepted_zone_resource_info: List[ZoneRegisteredData]=None): # noqa: E501 - """ZoneRegistrationResponseData - a model defined in Swagger - - :param accepted_zone_resource_info: The accepted_zone_resource_info of this ZoneRegistrationResponseData. # noqa: E501 - :type accepted_zone_resource_info: List[ZoneRegisteredData] - """ - self.swagger_types = { - 'accepted_zone_resource_info': List[ZoneRegisteredData] - } - - self.attribute_map = { - 'accepted_zone_resource_info': 'acceptedZoneResourceInfo' - } - self._accepted_zone_resource_info = accepted_zone_resource_info - - @classmethod - def from_dict(cls, dikt) -> 'ZoneRegistrationResponseData': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The ZoneRegistrationResponseData of this ZoneRegistrationResponseData. # noqa: E501 - :rtype: ZoneRegistrationResponseData - """ - return util.deserialize_model(dikt, cls) - - @property - def accepted_zone_resource_info(self) -> List[ZoneRegisteredData]: - """Gets the accepted_zone_resource_info of this ZoneRegistrationResponseData. - - - :return: The accepted_zone_resource_info of this ZoneRegistrationResponseData. - :rtype: List[ZoneRegisteredData] - """ - return self._accepted_zone_resource_info - - @accepted_zone_resource_info.setter - def accepted_zone_resource_info(self, accepted_zone_resource_info: List[ZoneRegisteredData]): - """Sets the accepted_zone_resource_info of this ZoneRegistrationResponseData. - - - :param accepted_zone_resource_info: The accepted_zone_resource_info of this ZoneRegistrationResponseData. - :type accepted_zone_resource_info: List[ZoneRegisteredData] - """ - if accepted_zone_resource_info is None: - raise ValueError("Invalid value for `accepted_zone_resource_info`, must not be `None`") # noqa: E501 - - self._accepted_zone_resource_info = accepted_zone_resource_info diff --git a/src/static/css/swagger-ui.css b/src/static/css/swagger-ui.css deleted file mode 100644 index 8732e4942a88bbfcf3967fd4301c477780c644e3..0000000000000000000000000000000000000000 --- a/src/static/css/swagger-ui.css +++ /dev/null @@ -1,4 +0,0 @@ -.swagger-ui{ - /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif;color:#3b4151}.swagger-ui html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{background-color:transparent;-webkit-text-decoration-skip:objects}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui template{display:none}.swagger-ui [hidden]{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) repeat 0 0}.swagger-ui .debug-grid-8-solid{background:#fff url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) repeat 0 0}.swagger-ui .debug-grid-16-solid{background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) repeat 0 0}.swagger-ui .border-box,.swagger-ui a,.swagger-ui article,.swagger-ui body,.swagger-ui code,.swagger-ui dd,.swagger-ui div,.swagger-ui dl,.swagger-ui dt,.swagger-ui fieldset,.swagger-ui footer,.swagger-ui form,.swagger-ui h1,.swagger-ui h2,.swagger-ui h3,.swagger-ui h4,.swagger-ui h5,.swagger-ui h6,.swagger-ui header,.swagger-ui html,.swagger-ui input[type=email],.swagger-ui input[type=number],.swagger-ui input[type=password],.swagger-ui input[type=tel],.swagger-ui input[type=text],.swagger-ui input[type=url],.swagger-ui legend,.swagger-ui li,.swagger-ui main,.swagger-ui ol,.swagger-ui p,.swagger-ui pre,.swagger-ui section,.swagger-ui table,.swagger-ui td,.swagger-ui textarea,.swagger-ui th,.swagger-ui tr,.swagger-ui ul{box-sizing:border-box}.swagger-ui .aspect-ratio{height:0;position:relative}.swagger-ui .aspect-ratio--16x9{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1{padding-bottom:100%}.swagger-ui .aspect-ratio--object{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}@media screen and (min-width:30em){.swagger-ui .aspect-ratio-ns{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-ns{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-ns{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-ns{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-ns{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-ns{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-ns{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-ns{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-ns{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-ns{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-ns{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-ns{padding-bottom:100%}.swagger-ui .aspect-ratio--object-ns{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .aspect-ratio-m{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-m{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-m{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-m{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-m{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-m{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-m{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-m{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-m{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-m{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-m{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-m{padding-bottom:100%}.swagger-ui .aspect-ratio--object-m{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:60em){.swagger-ui .aspect-ratio-l{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-l{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-l{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-l{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-l{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-l{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-l{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-l{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-l{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-l{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-l{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-l{padding-bottom:100%}.swagger-ui .aspect-ratio--object-l{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}.swagger-ui img{max-width:100%}.swagger-ui .cover{background-size:cover!important}.swagger-ui .contain{background-size:contain!important}@media screen and (min-width:30em){.swagger-ui .cover-ns{background-size:cover!important}.swagger-ui .contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cover-m{background-size:cover!important}.swagger-ui .contain-m{background-size:contain!important}}@media screen and (min-width:60em){.swagger-ui .cover-l{background-size:cover!important}.swagger-ui .contain-l{background-size:contain!important}}.swagger-ui .bg-center{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left{background-repeat:no-repeat;background-position:0}@media screen and (min-width:30em){.swagger-ui .bg-center-ns{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-ns{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-ns{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-ns{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-ns{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bg-center-m{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-m{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-m{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-m{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-m{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:60em){.swagger-ui .bg-center-l{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-l{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-l{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-l{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-l{background-repeat:no-repeat;background-position:0}}.swagger-ui .outline{outline:1px solid}.swagger-ui .outline-transparent{outline:1px solid transparent}.swagger-ui .outline-0{outline:0}@media screen and (min-width:30em){.swagger-ui .outline-ns{outline:1px solid}.swagger-ui .outline-transparent-ns{outline:1px solid transparent}.swagger-ui .outline-0-ns{outline:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .outline-m{outline:1px solid}.swagger-ui .outline-transparent-m{outline:1px solid transparent}.swagger-ui .outline-0-m{outline:0}}@media screen and (min-width:60em){.swagger-ui .outline-l{outline:1px solid}.swagger-ui .outline-transparent-l{outline:1px solid transparent}.swagger-ui .outline-0-l{outline:0}}.swagger-ui .ba{border-style:solid;border-width:1px}.swagger-ui .bt{border-top-style:solid;border-top-width:1px}.swagger-ui .br{border-right-style:solid;border-right-width:1px}.swagger-ui .bb{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl{border-left-style:solid;border-left-width:1px}.swagger-ui .bn{border-style:none;border-width:0}@media screen and (min-width:30em){.swagger-ui .ba-ns{border-style:solid;border-width:1px}.swagger-ui .bt-ns{border-top-style:solid;border-top-width:1px}.swagger-ui .br-ns{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-ns{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-ns{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ba-m{border-style:solid;border-width:1px}.swagger-ui .bt-m{border-top-style:solid;border-top-width:1px}.swagger-ui .br-m{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-m{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-m{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.swagger-ui .ba-l{border-style:solid;border-width:1px}.swagger-ui .bt-l{border-top-style:solid;border-top-width:1px}.swagger-ui .br-l{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-l{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-l{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-l{border-style:none;border-width:0}}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#111}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#555}.swagger-ui .b--gray{border-color:#777}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#aaa}.swagger-ui .b--moon-gray{border-color:#ccc}.swagger-ui .b--light-gray{border-color:#eee}.swagger-ui .b--near-white{border-color:#f4f4f4}.swagger-ui .b--white{border-color:#fff}.swagger-ui .b--white-90{border-color:hsla(0,0%,100%,.9)}.swagger-ui .b--white-80{border-color:hsla(0,0%,100%,.8)}.swagger-ui .b--white-70{border-color:hsla(0,0%,100%,.7)}.swagger-ui .b--white-60{border-color:hsla(0,0%,100%,.6)}.swagger-ui .b--white-50{border-color:hsla(0,0%,100%,.5)}.swagger-ui .b--white-40{border-color:hsla(0,0%,100%,.4)}.swagger-ui .b--white-30{border-color:hsla(0,0%,100%,.3)}.swagger-ui .b--white-20{border-color:hsla(0,0%,100%,.2)}.swagger-ui .b--white-10{border-color:hsla(0,0%,100%,.1)}.swagger-ui .b--white-05{border-color:hsla(0,0%,100%,.05)}.swagger-ui .b--white-025{border-color:hsla(0,0%,100%,.025)}.swagger-ui .b--white-0125{border-color:hsla(0,0%,100%,.0125)}.swagger-ui .b--black-90{border-color:rgba(0,0,0,.9)}.swagger-ui .b--black-80{border-color:rgba(0,0,0,.8)}.swagger-ui .b--black-70{border-color:rgba(0,0,0,.7)}.swagger-ui .b--black-60{border-color:rgba(0,0,0,.6)}.swagger-ui .b--black-50{border-color:rgba(0,0,0,.5)}.swagger-ui .b--black-40{border-color:rgba(0,0,0,.4)}.swagger-ui .b--black-30{border-color:rgba(0,0,0,.3)}.swagger-ui .b--black-20{border-color:rgba(0,0,0,.2)}.swagger-ui .b--black-10{border-color:rgba(0,0,0,.1)}.swagger-ui .b--black-05{border-color:rgba(0,0,0,.05)}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.025)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.0125)}.swagger-ui .b--dark-red{border-color:#e7040f}.swagger-ui .b--red{border-color:#ff4136}.swagger-ui .b--light-red{border-color:#ff725c}.swagger-ui .b--orange{border-color:#ff6300}.swagger-ui .b--gold{border-color:#ffb700}.swagger-ui .b--yellow{border-color:gold}.swagger-ui .b--light-yellow{border-color:#fbf1a9}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#a463f2}.swagger-ui .b--dark-pink{border-color:#d5008f}.swagger-ui .b--hot-pink{border-color:#ff41b4}.swagger-ui .b--pink{border-color:#ff80cc}.swagger-ui .b--light-pink{border-color:#ffa3d7}.swagger-ui .b--dark-green{border-color:#137752}.swagger-ui .b--green{border-color:#19a974}.swagger-ui .b--light-green{border-color:#9eebcf}.swagger-ui .b--navy{border-color:#001b44}.swagger-ui .b--dark-blue{border-color:#00449e}.swagger-ui .b--blue{border-color:#357edd}.swagger-ui .b--light-blue{border-color:#96ccff}.swagger-ui .b--lightest-blue{border-color:#cdecff}.swagger-ui .b--washed-blue{border-color:#f6fffe}.swagger-ui .b--washed-green{border-color:#e8fdf5}.swagger-ui .b--washed-yellow{border-color:#fffceb}.swagger-ui .b--washed-red{border-color:#ffdfdf}.swagger-ui .b--transparent{border-color:transparent}.swagger-ui .b--inherit{border-color:inherit}.swagger-ui .br0{border-radius:0}.swagger-ui .br1{border-radius:.125rem}.swagger-ui .br2{border-radius:.25rem}.swagger-ui .br3{border-radius:.5rem}.swagger-ui .br4{border-radius:1rem}.swagger-ui .br-100{border-radius:100%}.swagger-ui .br-pill{border-radius:9999px}.swagger-ui .br--bottom{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left{border-top-right-radius:0;border-bottom-right-radius:0}@media screen and (min-width:30em){.swagger-ui .br0-ns{border-radius:0}.swagger-ui .br1-ns{border-radius:.125rem}.swagger-ui .br2-ns{border-radius:.25rem}.swagger-ui .br3-ns{border-radius:.5rem}.swagger-ui .br4-ns{border-radius:1rem}.swagger-ui .br-100-ns{border-radius:100%}.swagger-ui .br-pill-ns{border-radius:9999px}.swagger-ui .br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-ns{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .br0-m{border-radius:0}.swagger-ui .br1-m{border-radius:.125rem}.swagger-ui .br2-m{border-radius:.25rem}.swagger-ui .br3-m{border-radius:.5rem}.swagger-ui .br4-m{border-radius:1rem}.swagger-ui .br-100-m{border-radius:100%}.swagger-ui .br-pill-m{border-radius:9999px}.swagger-ui .br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-m{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:60em){.swagger-ui .br0-l{border-radius:0}.swagger-ui .br1-l{border-radius:.125rem}.swagger-ui .br2-l{border-radius:.25rem}.swagger-ui .br3-l{border-radius:.5rem}.swagger-ui .br4-l{border-radius:1rem}.swagger-ui .br-100-l{border-radius:100%}.swagger-ui .br-pill-l{border-radius:9999px}.swagger-ui .br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-l{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}}.swagger-ui .b--dotted{border-style:dotted}.swagger-ui .b--dashed{border-style:dashed}.swagger-ui .b--solid{border-style:solid}.swagger-ui .b--none{border-style:none}@media screen and (min-width:30em){.swagger-ui .b--dotted-ns{border-style:dotted}.swagger-ui .b--dashed-ns{border-style:dashed}.swagger-ui .b--solid-ns{border-style:solid}.swagger-ui .b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .b--dotted-m{border-style:dotted}.swagger-ui .b--dashed-m{border-style:dashed}.swagger-ui .b--solid-m{border-style:solid}.swagger-ui .b--none-m{border-style:none}}@media screen and (min-width:60em){.swagger-ui .b--dotted-l{border-style:dotted}.swagger-ui .b--dashed-l{border-style:dashed}.swagger-ui .b--solid-l{border-style:solid}.swagger-ui .b--none-l{border-style:none}}.swagger-ui .bw0{border-width:0}.swagger-ui .bw1{border-width:.125rem}.swagger-ui .bw2{border-width:.25rem}.swagger-ui .bw3{border-width:.5rem}.swagger-ui .bw4{border-width:1rem}.swagger-ui .bw5{border-width:2rem}.swagger-ui .bt-0{border-top-width:0}.swagger-ui .br-0{border-right-width:0}.swagger-ui .bb-0{border-bottom-width:0}.swagger-ui .bl-0{border-left-width:0}@media screen and (min-width:30em){.swagger-ui .bw0-ns{border-width:0}.swagger-ui .bw1-ns{border-width:.125rem}.swagger-ui .bw2-ns{border-width:.25rem}.swagger-ui .bw3-ns{border-width:.5rem}.swagger-ui .bw4-ns{border-width:1rem}.swagger-ui .bw5-ns{border-width:2rem}.swagger-ui .bt-0-ns{border-top-width:0}.swagger-ui .br-0-ns{border-right-width:0}.swagger-ui .bb-0-ns{border-bottom-width:0}.swagger-ui .bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bw0-m{border-width:0}.swagger-ui .bw1-m{border-width:.125rem}.swagger-ui .bw2-m{border-width:.25rem}.swagger-ui .bw3-m{border-width:.5rem}.swagger-ui .bw4-m{border-width:1rem}.swagger-ui .bw5-m{border-width:2rem}.swagger-ui .bt-0-m{border-top-width:0}.swagger-ui .br-0-m{border-right-width:0}.swagger-ui .bb-0-m{border-bottom-width:0}.swagger-ui .bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.swagger-ui .bw0-l{border-width:0}.swagger-ui .bw1-l{border-width:.125rem}.swagger-ui .bw2-l{border-width:.25rem}.swagger-ui .bw3-l{border-width:.5rem}.swagger-ui .bw4-l{border-width:1rem}.swagger-ui .bw5-l{border-width:2rem}.swagger-ui .bt-0-l{border-top-width:0}.swagger-ui .br-0-l{border-right-width:0}.swagger-ui .bb-0-l{border-bottom-width:0}.swagger-ui .bl-0-l{border-left-width:0}}.swagger-ui .shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.swagger-ui .pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.swagger-ui .top-0{top:0}.swagger-ui .right-0{right:0}.swagger-ui .bottom-0{bottom:0}.swagger-ui .left-0{left:0}.swagger-ui .top-1{top:1rem}.swagger-ui .right-1{right:1rem}.swagger-ui .bottom-1{bottom:1rem}.swagger-ui .left-1{left:1rem}.swagger-ui .top-2{top:2rem}.swagger-ui .right-2{right:2rem}.swagger-ui .bottom-2{bottom:2rem}.swagger-ui .left-2{left:2rem}.swagger-ui .top--1{top:-1rem}.swagger-ui .right--1{right:-1rem}.swagger-ui .bottom--1{bottom:-1rem}.swagger-ui .left--1{left:-1rem}.swagger-ui .top--2{top:-2rem}.swagger-ui .right--2{right:-2rem}.swagger-ui .bottom--2{bottom:-2rem}.swagger-ui .left--2{left:-2rem}.swagger-ui .absolute--fill{top:0;right:0;bottom:0;left:0}@media screen and (min-width:30em){.swagger-ui .top-0-ns{top:0}.swagger-ui .left-0-ns{left:0}.swagger-ui .right-0-ns{right:0}.swagger-ui .bottom-0-ns{bottom:0}.swagger-ui .top-1-ns{top:1rem}.swagger-ui .left-1-ns{left:1rem}.swagger-ui .right-1-ns{right:1rem}.swagger-ui .bottom-1-ns{bottom:1rem}.swagger-ui .top-2-ns{top:2rem}.swagger-ui .left-2-ns{left:2rem}.swagger-ui .right-2-ns{right:2rem}.swagger-ui .bottom-2-ns{bottom:2rem}.swagger-ui .top--1-ns{top:-1rem}.swagger-ui .right--1-ns{right:-1rem}.swagger-ui .bottom--1-ns{bottom:-1rem}.swagger-ui .left--1-ns{left:-1rem}.swagger-ui .top--2-ns{top:-2rem}.swagger-ui .right--2-ns{right:-2rem}.swagger-ui .bottom--2-ns{bottom:-2rem}.swagger-ui .left--2-ns{left:-2rem}.swagger-ui .absolute--fill-ns{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .top-0-m{top:0}.swagger-ui .left-0-m{left:0}.swagger-ui .right-0-m{right:0}.swagger-ui .bottom-0-m{bottom:0}.swagger-ui .top-1-m{top:1rem}.swagger-ui .left-1-m{left:1rem}.swagger-ui .right-1-m{right:1rem}.swagger-ui .bottom-1-m{bottom:1rem}.swagger-ui .top-2-m{top:2rem}.swagger-ui .left-2-m{left:2rem}.swagger-ui .right-2-m{right:2rem}.swagger-ui .bottom-2-m{bottom:2rem}.swagger-ui .top--1-m{top:-1rem}.swagger-ui .right--1-m{right:-1rem}.swagger-ui .bottom--1-m{bottom:-1rem}.swagger-ui .left--1-m{left:-1rem}.swagger-ui .top--2-m{top:-2rem}.swagger-ui .right--2-m{right:-2rem}.swagger-ui .bottom--2-m{bottom:-2rem}.swagger-ui .left--2-m{left:-2rem}.swagger-ui .absolute--fill-m{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:60em){.swagger-ui .top-0-l{top:0}.swagger-ui .left-0-l{left:0}.swagger-ui .right-0-l{right:0}.swagger-ui .bottom-0-l{bottom:0}.swagger-ui .top-1-l{top:1rem}.swagger-ui .left-1-l{left:1rem}.swagger-ui .right-1-l{right:1rem}.swagger-ui .bottom-1-l{bottom:1rem}.swagger-ui .top-2-l{top:2rem}.swagger-ui .left-2-l{left:2rem}.swagger-ui .right-2-l{right:2rem}.swagger-ui .bottom-2-l{bottom:2rem}.swagger-ui .top--1-l{top:-1rem}.swagger-ui .right--1-l{right:-1rem}.swagger-ui .bottom--1-l{bottom:-1rem}.swagger-ui .left--1-l{left:-1rem}.swagger-ui .top--2-l{top:-2rem}.swagger-ui .right--2-l{right:-2rem}.swagger-ui .bottom--2-l{bottom:-2rem}.swagger-ui .left--2-l{left:-2rem}.swagger-ui .absolute--fill-l{top:0;right:0;bottom:0;left:0}}.swagger-ui .cf:after,.swagger-ui .cf:before{content:" ";display:table}.swagger-ui .cf:after{clear:both}.swagger-ui .cf{*zoom:1}.swagger-ui .cl{clear:left}.swagger-ui .cr{clear:right}.swagger-ui .cb{clear:both}.swagger-ui .cn{clear:none}@media screen and (min-width:30em){.swagger-ui .cl-ns{clear:left}.swagger-ui .cr-ns{clear:right}.swagger-ui .cb-ns{clear:both}.swagger-ui .cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cl-m{clear:left}.swagger-ui .cr-m{clear:right}.swagger-ui .cb-m{clear:both}.swagger-ui .cn-m{clear:none}}@media screen and (min-width:60em){.swagger-ui .cl-l{clear:left}.swagger-ui .cr-l{clear:right}.swagger-ui .cb-l{clear:both}.swagger-ui .cn-l{clear:none}}.swagger-ui .flex{display:flex}.swagger-ui .inline-flex{display:inline-flex}.swagger-ui .flex-auto{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none{flex:none}.swagger-ui .flex-column{flex-direction:column}.swagger-ui .flex-row{flex-direction:row}.swagger-ui .flex-wrap{flex-wrap:wrap}.swagger-ui .flex-nowrap{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse{flex-direction:column-reverse}.swagger-ui .flex-row-reverse{flex-direction:row-reverse}.swagger-ui .items-start{align-items:flex-start}.swagger-ui .items-end{align-items:flex-end}.swagger-ui .items-center{align-items:center}.swagger-ui .items-baseline{align-items:baseline}.swagger-ui .items-stretch{align-items:stretch}.swagger-ui .self-start{align-self:flex-start}.swagger-ui .self-end{align-self:flex-end}.swagger-ui .self-center{align-self:center}.swagger-ui .self-baseline{align-self:baseline}.swagger-ui .self-stretch{align-self:stretch}.swagger-ui .justify-start{justify-content:flex-start}.swagger-ui .justify-end{justify-content:flex-end}.swagger-ui .justify-center{justify-content:center}.swagger-ui .justify-between{justify-content:space-between}.swagger-ui .justify-around{justify-content:space-around}.swagger-ui .content-start{align-content:flex-start}.swagger-ui .content-end{align-content:flex-end}.swagger-ui .content-center{align-content:center}.swagger-ui .content-between{align-content:space-between}.swagger-ui .content-around{align-content:space-around}.swagger-ui .content-stretch{align-content:stretch}.swagger-ui .order-0{order:0}.swagger-ui .order-1{order:1}.swagger-ui .order-2{order:2}.swagger-ui .order-3{order:3}.swagger-ui .order-4{order:4}.swagger-ui .order-5{order:5}.swagger-ui .order-6{order:6}.swagger-ui .order-7{order:7}.swagger-ui .order-8{order:8}.swagger-ui .order-last{order:99999}.swagger-ui .flex-grow-0{flex-grow:0}.swagger-ui .flex-grow-1{flex-grow:1}.swagger-ui .flex-shrink-0{flex-shrink:0}.swagger-ui .flex-shrink-1{flex-shrink:1}@media screen and (min-width:30em){.swagger-ui .flex-ns{display:flex}.swagger-ui .inline-flex-ns{display:inline-flex}.swagger-ui .flex-auto-ns{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-ns{flex:none}.swagger-ui .flex-column-ns{flex-direction:column}.swagger-ui .flex-row-ns{flex-direction:row}.swagger-ui .flex-wrap-ns{flex-wrap:wrap}.swagger-ui .flex-nowrap-ns{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-ns{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-ns{flex-direction:row-reverse}.swagger-ui .items-start-ns{align-items:flex-start}.swagger-ui .items-end-ns{align-items:flex-end}.swagger-ui .items-center-ns{align-items:center}.swagger-ui .items-baseline-ns{align-items:baseline}.swagger-ui .items-stretch-ns{align-items:stretch}.swagger-ui .self-start-ns{align-self:flex-start}.swagger-ui .self-end-ns{align-self:flex-end}.swagger-ui .self-center-ns{align-self:center}.swagger-ui .self-baseline-ns{align-self:baseline}.swagger-ui .self-stretch-ns{align-self:stretch}.swagger-ui .justify-start-ns{justify-content:flex-start}.swagger-ui .justify-end-ns{justify-content:flex-end}.swagger-ui .justify-center-ns{justify-content:center}.swagger-ui .justify-between-ns{justify-content:space-between}.swagger-ui .justify-around-ns{justify-content:space-around}.swagger-ui .content-start-ns{align-content:flex-start}.swagger-ui .content-end-ns{align-content:flex-end}.swagger-ui .content-center-ns{align-content:center}.swagger-ui .content-between-ns{align-content:space-between}.swagger-ui .content-around-ns{align-content:space-around}.swagger-ui .content-stretch-ns{align-content:stretch}.swagger-ui .order-0-ns{order:0}.swagger-ui .order-1-ns{order:1}.swagger-ui .order-2-ns{order:2}.swagger-ui .order-3-ns{order:3}.swagger-ui .order-4-ns{order:4}.swagger-ui .order-5-ns{order:5}.swagger-ui .order-6-ns{order:6}.swagger-ui .order-7-ns{order:7}.swagger-ui .order-8-ns{order:8}.swagger-ui .order-last-ns{order:99999}.swagger-ui .flex-grow-0-ns{flex-grow:0}.swagger-ui .flex-grow-1-ns{flex-grow:1}.swagger-ui .flex-shrink-0-ns{flex-shrink:0}.swagger-ui .flex-shrink-1-ns{flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .flex-m{display:flex}.swagger-ui .inline-flex-m{display:inline-flex}.swagger-ui .flex-auto-m{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-m{flex:none}.swagger-ui .flex-column-m{flex-direction:column}.swagger-ui .flex-row-m{flex-direction:row}.swagger-ui .flex-wrap-m{flex-wrap:wrap}.swagger-ui .flex-nowrap-m{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-m{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-m{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-m{flex-direction:row-reverse}.swagger-ui .items-start-m{align-items:flex-start}.swagger-ui .items-end-m{align-items:flex-end}.swagger-ui .items-center-m{align-items:center}.swagger-ui .items-baseline-m{align-items:baseline}.swagger-ui .items-stretch-m{align-items:stretch}.swagger-ui .self-start-m{align-self:flex-start}.swagger-ui .self-end-m{align-self:flex-end}.swagger-ui .self-center-m{align-self:center}.swagger-ui .self-baseline-m{align-self:baseline}.swagger-ui .self-stretch-m{align-self:stretch}.swagger-ui .justify-start-m{justify-content:flex-start}.swagger-ui .justify-end-m{justify-content:flex-end}.swagger-ui .justify-center-m{justify-content:center}.swagger-ui .justify-between-m{justify-content:space-between}.swagger-ui .justify-around-m{justify-content:space-around}.swagger-ui .content-start-m{align-content:flex-start}.swagger-ui .content-end-m{align-content:flex-end}.swagger-ui .content-center-m{align-content:center}.swagger-ui .content-between-m{align-content:space-between}.swagger-ui .content-around-m{align-content:space-around}.swagger-ui .content-stretch-m{align-content:stretch}.swagger-ui .order-0-m{order:0}.swagger-ui .order-1-m{order:1}.swagger-ui .order-2-m{order:2}.swagger-ui .order-3-m{order:3}.swagger-ui .order-4-m{order:4}.swagger-ui .order-5-m{order:5}.swagger-ui .order-6-m{order:6}.swagger-ui .order-7-m{order:7}.swagger-ui .order-8-m{order:8}.swagger-ui .order-last-m{order:99999}.swagger-ui .flex-grow-0-m{flex-grow:0}.swagger-ui .flex-grow-1-m{flex-grow:1}.swagger-ui .flex-shrink-0-m{flex-shrink:0}.swagger-ui .flex-shrink-1-m{flex-shrink:1}}@media screen and (min-width:60em){.swagger-ui .flex-l{display:flex}.swagger-ui .inline-flex-l{display:inline-flex}.swagger-ui .flex-auto-l{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-l{flex:none}.swagger-ui .flex-column-l{flex-direction:column}.swagger-ui .flex-row-l{flex-direction:row}.swagger-ui .flex-wrap-l{flex-wrap:wrap}.swagger-ui .flex-nowrap-l{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-l{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-l{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-l{flex-direction:row-reverse}.swagger-ui .items-start-l{align-items:flex-start}.swagger-ui .items-end-l{align-items:flex-end}.swagger-ui .items-center-l{align-items:center}.swagger-ui .items-baseline-l{align-items:baseline}.swagger-ui .items-stretch-l{align-items:stretch}.swagger-ui .self-start-l{align-self:flex-start}.swagger-ui .self-end-l{align-self:flex-end}.swagger-ui .self-center-l{align-self:center}.swagger-ui .self-baseline-l{align-self:baseline}.swagger-ui .self-stretch-l{align-self:stretch}.swagger-ui .justify-start-l{justify-content:flex-start}.swagger-ui .justify-end-l{justify-content:flex-end}.swagger-ui .justify-center-l{justify-content:center}.swagger-ui .justify-between-l{justify-content:space-between}.swagger-ui .justify-around-l{justify-content:space-around}.swagger-ui .content-start-l{align-content:flex-start}.swagger-ui .content-end-l{align-content:flex-end}.swagger-ui .content-center-l{align-content:center}.swagger-ui .content-between-l{align-content:space-between}.swagger-ui .content-around-l{align-content:space-around}.swagger-ui .content-stretch-l{align-content:stretch}.swagger-ui .order-0-l{order:0}.swagger-ui .order-1-l{order:1}.swagger-ui .order-2-l{order:2}.swagger-ui .order-3-l{order:3}.swagger-ui .order-4-l{order:4}.swagger-ui .order-5-l{order:5}.swagger-ui .order-6-l{order:6}.swagger-ui .order-7-l{order:7}.swagger-ui .order-8-l{order:8}.swagger-ui .order-last-l{order:99999}.swagger-ui .flex-grow-0-l{flex-grow:0}.swagger-ui .flex-grow-1-l{flex-grow:1}.swagger-ui .flex-shrink-0-l{flex-shrink:0}.swagger-ui .flex-shrink-1-l{flex-shrink:1}}.swagger-ui .dn{display:none}.swagger-ui .di{display:inline}.swagger-ui .db{display:block}.swagger-ui .dib{display:inline-block}.swagger-ui .dit{display:inline-table}.swagger-ui .dt{display:table}.swagger-ui .dtc{display:table-cell}.swagger-ui .dt-row{display:table-row}.swagger-ui .dt-row-group{display:table-row-group}.swagger-ui .dt-column{display:table-column}.swagger-ui .dt-column-group{display:table-column-group}.swagger-ui .dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.swagger-ui .dn-ns{display:none}.swagger-ui .di-ns{display:inline}.swagger-ui .db-ns{display:block}.swagger-ui .dib-ns{display:inline-block}.swagger-ui .dit-ns{display:inline-table}.swagger-ui .dt-ns{display:table}.swagger-ui .dtc-ns{display:table-cell}.swagger-ui .dt-row-ns{display:table-row}.swagger-ui .dt-row-group-ns{display:table-row-group}.swagger-ui .dt-column-ns{display:table-column}.swagger-ui .dt-column-group-ns{display:table-column-group}.swagger-ui .dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .dn-m{display:none}.swagger-ui .di-m{display:inline}.swagger-ui .db-m{display:block}.swagger-ui .dib-m{display:inline-block}.swagger-ui .dit-m{display:inline-table}.swagger-ui .dt-m{display:table}.swagger-ui .dtc-m{display:table-cell}.swagger-ui .dt-row-m{display:table-row}.swagger-ui .dt-row-group-m{display:table-row-group}.swagger-ui .dt-column-m{display:table-column}.swagger-ui .dt-column-group-m{display:table-column-group}.swagger-ui .dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.swagger-ui .dn-l{display:none}.swagger-ui .di-l{display:inline}.swagger-ui .db-l{display:block}.swagger-ui .dib-l{display:inline-block}.swagger-ui .dit-l{display:inline-table}.swagger-ui .dt-l{display:table}.swagger-ui .dtc-l{display:table-cell}.swagger-ui .dt-row-l{display:table-row}.swagger-ui .dt-row-group-l{display:table-row-group}.swagger-ui .dt-column-l{display:table-column}.swagger-ui .dt-column-group-l{display:table-column-group}.swagger-ui .dt--fixed-l{table-layout:fixed;width:100%}}.swagger-ui .fl{float:left;_display:inline}.swagger-ui .fr{float:right;_display:inline}.swagger-ui .fn{float:none}@media screen and (min-width:30em){.swagger-ui .fl-ns{float:left;_display:inline}.swagger-ui .fr-ns{float:right;_display:inline}.swagger-ui .fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .fl-m{float:left;_display:inline}.swagger-ui .fr-m{float:right;_display:inline}.swagger-ui .fn-m{float:none}}@media screen and (min-width:60em){.swagger-ui .fl-l{float:left;_display:inline}.swagger-ui .fr-l{float:right;_display:inline}.swagger-ui .fn-l{float:none}}.swagger-ui .sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.swagger-ui .serif{font-family:georgia,serif}.swagger-ui .system-sans-serif{font-family:sans-serif}.swagger-ui .system-serif{font-family:serif}.swagger-ui .code,.swagger-ui code{font-family:Consolas,monaco,monospace}.swagger-ui .courier{font-family:Courier Next,courier,monospace}.swagger-ui .helvetica{font-family:helvetica neue,helvetica,sans-serif}.swagger-ui .avenir{font-family:avenir next,avenir,sans-serif}.swagger-ui .athelas{font-family:athelas,georgia,serif}.swagger-ui .georgia{font-family:georgia,serif}.swagger-ui .times{font-family:times,serif}.swagger-ui .bodoni{font-family:Bodoni MT,serif}.swagger-ui .calisto{font-family:Calisto MT,serif}.swagger-ui .garamond{font-family:garamond,serif}.swagger-ui .baskerville{font-family:baskerville,serif}.swagger-ui .i{font-style:italic}.swagger-ui .fs-normal{font-style:normal}@media screen and (min-width:30em){.swagger-ui .i-ns{font-style:italic}.swagger-ui .fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .i-m{font-style:italic}.swagger-ui .fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.swagger-ui .i-l{font-style:italic}.swagger-ui .fs-normal-l{font-style:normal}}.swagger-ui .normal{font-weight:400}.swagger-ui .b{font-weight:700}.swagger-ui .fw1{font-weight:100}.swagger-ui .fw2{font-weight:200}.swagger-ui .fw3{font-weight:300}.swagger-ui .fw4{font-weight:400}.swagger-ui .fw5{font-weight:500}.swagger-ui .fw6{font-weight:600}.swagger-ui .fw7{font-weight:700}.swagger-ui .fw8{font-weight:800}.swagger-ui .fw9{font-weight:900}@media screen and (min-width:30em){.swagger-ui .normal-ns{font-weight:400}.swagger-ui .b-ns{font-weight:700}.swagger-ui .fw1-ns{font-weight:100}.swagger-ui .fw2-ns{font-weight:200}.swagger-ui .fw3-ns{font-weight:300}.swagger-ui .fw4-ns{font-weight:400}.swagger-ui .fw5-ns{font-weight:500}.swagger-ui .fw6-ns{font-weight:600}.swagger-ui .fw7-ns{font-weight:700}.swagger-ui .fw8-ns{font-weight:800}.swagger-ui .fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .normal-m{font-weight:400}.swagger-ui .b-m{font-weight:700}.swagger-ui .fw1-m{font-weight:100}.swagger-ui .fw2-m{font-weight:200}.swagger-ui .fw3-m{font-weight:300}.swagger-ui .fw4-m{font-weight:400}.swagger-ui .fw5-m{font-weight:500}.swagger-ui .fw6-m{font-weight:600}.swagger-ui .fw7-m{font-weight:700}.swagger-ui .fw8-m{font-weight:800}.swagger-ui .fw9-m{font-weight:900}}@media screen and (min-width:60em){.swagger-ui .normal-l{font-weight:400}.swagger-ui .b-l{font-weight:700}.swagger-ui .fw1-l{font-weight:100}.swagger-ui .fw2-l{font-weight:200}.swagger-ui .fw3-l{font-weight:300}.swagger-ui .fw4-l{font-weight:400}.swagger-ui .fw5-l{font-weight:500}.swagger-ui .fw6-l{font-weight:600}.swagger-ui .fw7-l{font-weight:700}.swagger-ui .fw8-l{font-weight:800}.swagger-ui .fw9-l{font-weight:900}}.swagger-ui .input-reset{-webkit-appearance:none;-moz-appearance:none}.swagger-ui .button-reset::-moz-focus-inner,.swagger-ui .input-reset::-moz-focus-inner{border:0;padding:0}.swagger-ui .h1{height:1rem}.swagger-ui .h2{height:2rem}.swagger-ui .h3{height:4rem}.swagger-ui .h4{height:8rem}.swagger-ui .h5{height:16rem}.swagger-ui .h-25{height:25%}.swagger-ui .h-50{height:50%}.swagger-ui .h-75{height:75%}.swagger-ui .h-100{height:100%}.swagger-ui .min-h-100{min-height:100%}.swagger-ui .vh-25{height:25vh}.swagger-ui .vh-50{height:50vh}.swagger-ui .vh-75{height:75vh}.swagger-ui .vh-100{height:100vh}.swagger-ui .min-vh-100{min-height:100vh}.swagger-ui .h-auto{height:auto}.swagger-ui .h-inherit{height:inherit}@media screen and (min-width:30em){.swagger-ui .h1-ns{height:1rem}.swagger-ui .h2-ns{height:2rem}.swagger-ui .h3-ns{height:4rem}.swagger-ui .h4-ns{height:8rem}.swagger-ui .h5-ns{height:16rem}.swagger-ui .h-25-ns{height:25%}.swagger-ui .h-50-ns{height:50%}.swagger-ui .h-75-ns{height:75%}.swagger-ui .h-100-ns{height:100%}.swagger-ui .min-h-100-ns{min-height:100%}.swagger-ui .vh-25-ns{height:25vh}.swagger-ui .vh-50-ns{height:50vh}.swagger-ui .vh-75-ns{height:75vh}.swagger-ui .vh-100-ns{height:100vh}.swagger-ui .min-vh-100-ns{min-height:100vh}.swagger-ui .h-auto-ns{height:auto}.swagger-ui .h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .h1-m{height:1rem}.swagger-ui .h2-m{height:2rem}.swagger-ui .h3-m{height:4rem}.swagger-ui .h4-m{height:8rem}.swagger-ui .h5-m{height:16rem}.swagger-ui .h-25-m{height:25%}.swagger-ui .h-50-m{height:50%}.swagger-ui .h-75-m{height:75%}.swagger-ui .h-100-m{height:100%}.swagger-ui .min-h-100-m{min-height:100%}.swagger-ui .vh-25-m{height:25vh}.swagger-ui .vh-50-m{height:50vh}.swagger-ui .vh-75-m{height:75vh}.swagger-ui .vh-100-m{height:100vh}.swagger-ui .min-vh-100-m{min-height:100vh}.swagger-ui .h-auto-m{height:auto}.swagger-ui .h-inherit-m{height:inherit}}@media screen and (min-width:60em){.swagger-ui .h1-l{height:1rem}.swagger-ui .h2-l{height:2rem}.swagger-ui .h3-l{height:4rem}.swagger-ui .h4-l{height:8rem}.swagger-ui .h5-l{height:16rem}.swagger-ui .h-25-l{height:25%}.swagger-ui .h-50-l{height:50%}.swagger-ui .h-75-l{height:75%}.swagger-ui .h-100-l{height:100%}.swagger-ui .min-h-100-l{min-height:100%}.swagger-ui .vh-25-l{height:25vh}.swagger-ui .vh-50-l{height:50vh}.swagger-ui .vh-75-l{height:75vh}.swagger-ui .vh-100-l{height:100vh}.swagger-ui .min-vh-100-l{min-height:100vh}.swagger-ui .h-auto-l{height:auto}.swagger-ui .h-inherit-l{height:inherit}}.swagger-ui .tracked{letter-spacing:.1em}.swagger-ui .tracked-tight{letter-spacing:-.05em}.swagger-ui .tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.swagger-ui .tracked-ns{letter-spacing:.1em}.swagger-ui .tracked-tight-ns{letter-spacing:-.05em}.swagger-ui .tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tracked-m{letter-spacing:.1em}.swagger-ui .tracked-tight-m{letter-spacing:-.05em}.swagger-ui .tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.swagger-ui .tracked-l{letter-spacing:.1em}.swagger-ui .tracked-tight-l{letter-spacing:-.05em}.swagger-ui .tracked-mega-l{letter-spacing:.25em}}.swagger-ui .lh-solid{line-height:1}.swagger-ui .lh-title{line-height:1.25}.swagger-ui .lh-copy{line-height:1.5}@media screen and (min-width:30em){.swagger-ui .lh-solid-ns{line-height:1}.swagger-ui .lh-title-ns{line-height:1.25}.swagger-ui .lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .lh-solid-m{line-height:1}.swagger-ui .lh-title-m{line-height:1.25}.swagger-ui .lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.swagger-ui .lh-solid-l{line-height:1}.swagger-ui .lh-title-l{line-height:1.25}.swagger-ui .lh-copy-l{line-height:1.5}}.swagger-ui .link{text-decoration:none}.swagger-ui .link,.swagger-ui .link:link,.swagger-ui .link:visited{transition:color .15s ease-in}.swagger-ui .link:hover{transition:color .15s ease-in}.swagger-ui .link:active{transition:color .15s ease-in}.swagger-ui .link:focus{transition:color .15s ease-in;outline:1px dotted currentColor}.swagger-ui .list{list-style-type:none}.swagger-ui .mw-100{max-width:100%}.swagger-ui .mw1{max-width:1rem}.swagger-ui .mw2{max-width:2rem}.swagger-ui .mw3{max-width:4rem}.swagger-ui .mw4{max-width:8rem}.swagger-ui .mw5{max-width:16rem}.swagger-ui .mw6{max-width:32rem}.swagger-ui .mw7{max-width:48rem}.swagger-ui .mw8{max-width:64rem}.swagger-ui .mw9{max-width:96rem}.swagger-ui .mw-none{max-width:none}@media screen and (min-width:30em){.swagger-ui .mw-100-ns{max-width:100%}.swagger-ui .mw1-ns{max-width:1rem}.swagger-ui .mw2-ns{max-width:2rem}.swagger-ui .mw3-ns{max-width:4rem}.swagger-ui .mw4-ns{max-width:8rem}.swagger-ui .mw5-ns{max-width:16rem}.swagger-ui .mw6-ns{max-width:32rem}.swagger-ui .mw7-ns{max-width:48rem}.swagger-ui .mw8-ns{max-width:64rem}.swagger-ui .mw9-ns{max-width:96rem}.swagger-ui .mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .mw-100-m{max-width:100%}.swagger-ui .mw1-m{max-width:1rem}.swagger-ui .mw2-m{max-width:2rem}.swagger-ui .mw3-m{max-width:4rem}.swagger-ui .mw4-m{max-width:8rem}.swagger-ui .mw5-m{max-width:16rem}.swagger-ui .mw6-m{max-width:32rem}.swagger-ui .mw7-m{max-width:48rem}.swagger-ui .mw8-m{max-width:64rem}.swagger-ui .mw9-m{max-width:96rem}.swagger-ui .mw-none-m{max-width:none}}@media screen and (min-width:60em){.swagger-ui .mw-100-l{max-width:100%}.swagger-ui .mw1-l{max-width:1rem}.swagger-ui .mw2-l{max-width:2rem}.swagger-ui .mw3-l{max-width:4rem}.swagger-ui .mw4-l{max-width:8rem}.swagger-ui .mw5-l{max-width:16rem}.swagger-ui .mw6-l{max-width:32rem}.swagger-ui .mw7-l{max-width:48rem}.swagger-ui .mw8-l{max-width:64rem}.swagger-ui .mw9-l{max-width:96rem}.swagger-ui .mw-none-l{max-width:none}}.swagger-ui .w1{width:1rem}.swagger-ui .w2{width:2rem}.swagger-ui .w3{width:4rem}.swagger-ui .w4{width:8rem}.swagger-ui .w5{width:16rem}.swagger-ui .w-10{width:10%}.swagger-ui .w-20{width:20%}.swagger-ui .w-25{width:25%}.swagger-ui .w-30{width:30%}.swagger-ui .w-33{width:33%}.swagger-ui .w-34{width:34%}.swagger-ui .w-40{width:40%}.swagger-ui .w-50{width:50%}.swagger-ui .w-60{width:60%}.swagger-ui .w-70{width:70%}.swagger-ui .w-75{width:75%}.swagger-ui .w-80{width:80%}.swagger-ui .w-90{width:90%}.swagger-ui .w-100{width:100%}.swagger-ui .w-third{width:33.33333%}.swagger-ui .w-two-thirds{width:66.66667%}.swagger-ui .w-auto{width:auto}@media screen and (min-width:30em){.swagger-ui .w1-ns{width:1rem}.swagger-ui .w2-ns{width:2rem}.swagger-ui .w3-ns{width:4rem}.swagger-ui .w4-ns{width:8rem}.swagger-ui .w5-ns{width:16rem}.swagger-ui .w-10-ns{width:10%}.swagger-ui .w-20-ns{width:20%}.swagger-ui .w-25-ns{width:25%}.swagger-ui .w-30-ns{width:30%}.swagger-ui .w-33-ns{width:33%}.swagger-ui .w-34-ns{width:34%}.swagger-ui .w-40-ns{width:40%}.swagger-ui .w-50-ns{width:50%}.swagger-ui .w-60-ns{width:60%}.swagger-ui .w-70-ns{width:70%}.swagger-ui .w-75-ns{width:75%}.swagger-ui .w-80-ns{width:80%}.swagger-ui .w-90-ns{width:90%}.swagger-ui .w-100-ns{width:100%}.swagger-ui .w-third-ns{width:33.33333%}.swagger-ui .w-two-thirds-ns{width:66.66667%}.swagger-ui .w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .w1-m{width:1rem}.swagger-ui .w2-m{width:2rem}.swagger-ui .w3-m{width:4rem}.swagger-ui .w4-m{width:8rem}.swagger-ui .w5-m{width:16rem}.swagger-ui .w-10-m{width:10%}.swagger-ui .w-20-m{width:20%}.swagger-ui .w-25-m{width:25%}.swagger-ui .w-30-m{width:30%}.swagger-ui .w-33-m{width:33%}.swagger-ui .w-34-m{width:34%}.swagger-ui .w-40-m{width:40%}.swagger-ui .w-50-m{width:50%}.swagger-ui .w-60-m{width:60%}.swagger-ui .w-70-m{width:70%}.swagger-ui .w-75-m{width:75%}.swagger-ui .w-80-m{width:80%}.swagger-ui .w-90-m{width:90%}.swagger-ui .w-100-m{width:100%}.swagger-ui .w-third-m{width:33.33333%}.swagger-ui .w-two-thirds-m{width:66.66667%}.swagger-ui .w-auto-m{width:auto}}@media screen and (min-width:60em){.swagger-ui .w1-l{width:1rem}.swagger-ui .w2-l{width:2rem}.swagger-ui .w3-l{width:4rem}.swagger-ui .w4-l{width:8rem}.swagger-ui .w5-l{width:16rem}.swagger-ui .w-10-l{width:10%}.swagger-ui .w-20-l{width:20%}.swagger-ui .w-25-l{width:25%}.swagger-ui .w-30-l{width:30%}.swagger-ui .w-33-l{width:33%}.swagger-ui .w-34-l{width:34%}.swagger-ui .w-40-l{width:40%}.swagger-ui .w-50-l{width:50%}.swagger-ui .w-60-l{width:60%}.swagger-ui .w-70-l{width:70%}.swagger-ui .w-75-l{width:75%}.swagger-ui .w-80-l{width:80%}.swagger-ui .w-90-l{width:90%}.swagger-ui .w-100-l{width:100%}.swagger-ui .w-third-l{width:33.33333%}.swagger-ui .w-two-thirds-l{width:66.66667%}.swagger-ui .w-auto-l{width:auto}}.swagger-ui .overflow-visible{overflow:visible}.swagger-ui .overflow-hidden{overflow:hidden}.swagger-ui .overflow-scroll{overflow:scroll}.swagger-ui .overflow-auto{overflow:auto}.swagger-ui .overflow-x-visible{overflow-x:visible}.swagger-ui .overflow-x-hidden{overflow-x:hidden}.swagger-ui .overflow-x-scroll{overflow-x:scroll}.swagger-ui .overflow-x-auto{overflow-x:auto}.swagger-ui .overflow-y-visible{overflow-y:visible}.swagger-ui .overflow-y-hidden{overflow-y:hidden}.swagger-ui .overflow-y-scroll{overflow-y:scroll}.swagger-ui .overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.swagger-ui .overflow-visible-ns{overflow:visible}.swagger-ui .overflow-hidden-ns{overflow:hidden}.swagger-ui .overflow-scroll-ns{overflow:scroll}.swagger-ui .overflow-auto-ns{overflow:auto}.swagger-ui .overflow-x-visible-ns{overflow-x:visible}.swagger-ui .overflow-x-hidden-ns{overflow-x:hidden}.swagger-ui .overflow-x-scroll-ns{overflow-x:scroll}.swagger-ui .overflow-x-auto-ns{overflow-x:auto}.swagger-ui .overflow-y-visible-ns{overflow-y:visible}.swagger-ui .overflow-y-hidden-ns{overflow-y:hidden}.swagger-ui .overflow-y-scroll-ns{overflow-y:scroll}.swagger-ui .overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .overflow-visible-m{overflow:visible}.swagger-ui .overflow-hidden-m{overflow:hidden}.swagger-ui .overflow-scroll-m{overflow:scroll}.swagger-ui .overflow-auto-m{overflow:auto}.swagger-ui .overflow-x-visible-m{overflow-x:visible}.swagger-ui .overflow-x-hidden-m{overflow-x:hidden}.swagger-ui .overflow-x-scroll-m{overflow-x:scroll}.swagger-ui .overflow-x-auto-m{overflow-x:auto}.swagger-ui .overflow-y-visible-m{overflow-y:visible}.swagger-ui .overflow-y-hidden-m{overflow-y:hidden}.swagger-ui .overflow-y-scroll-m{overflow-y:scroll}.swagger-ui .overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.swagger-ui .overflow-visible-l{overflow:visible}.swagger-ui .overflow-hidden-l{overflow:hidden}.swagger-ui .overflow-scroll-l{overflow:scroll}.swagger-ui .overflow-auto-l{overflow:auto}.swagger-ui .overflow-x-visible-l{overflow-x:visible}.swagger-ui .overflow-x-hidden-l{overflow-x:hidden}.swagger-ui .overflow-x-scroll-l{overflow-x:scroll}.swagger-ui .overflow-x-auto-l{overflow-x:auto}.swagger-ui .overflow-y-visible-l{overflow-y:visible}.swagger-ui .overflow-y-hidden-l{overflow-y:hidden}.swagger-ui .overflow-y-scroll-l{overflow-y:scroll}.swagger-ui .overflow-y-auto-l{overflow-y:auto}}.swagger-ui .static{position:static}.swagger-ui .relative{position:relative}.swagger-ui .absolute{position:absolute}.swagger-ui .fixed{position:fixed}@media screen and (min-width:30em){.swagger-ui .static-ns{position:static}.swagger-ui .relative-ns{position:relative}.swagger-ui .absolute-ns{position:absolute}.swagger-ui .fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .static-m{position:static}.swagger-ui .relative-m{position:relative}.swagger-ui .absolute-m{position:absolute}.swagger-ui .fixed-m{position:fixed}}@media screen and (min-width:60em){.swagger-ui .static-l{position:static}.swagger-ui .relative-l{position:relative}.swagger-ui .absolute-l{position:absolute}.swagger-ui .fixed-l{position:fixed}}.swagger-ui .o-100{opacity:1}.swagger-ui .o-90{opacity:.9}.swagger-ui .o-80{opacity:.8}.swagger-ui .o-70{opacity:.7}.swagger-ui .o-60{opacity:.6}.swagger-ui .o-50{opacity:.5}.swagger-ui .o-40{opacity:.4}.swagger-ui .o-30{opacity:.3}.swagger-ui .o-20{opacity:.2}.swagger-ui .o-10{opacity:.1}.swagger-ui .o-05{opacity:.05}.swagger-ui .o-025{opacity:.025}.swagger-ui .o-0{opacity:0}.swagger-ui .rotate-45{transform:rotate(45deg)}.swagger-ui .rotate-90{transform:rotate(90deg)}.swagger-ui .rotate-135{transform:rotate(135deg)}.swagger-ui .rotate-180{transform:rotate(180deg)}.swagger-ui .rotate-225{transform:rotate(225deg)}.swagger-ui .rotate-270{transform:rotate(270deg)}.swagger-ui .rotate-315{transform:rotate(315deg)}@media screen and (min-width:30em){.swagger-ui .rotate-45-ns{transform:rotate(45deg)}.swagger-ui .rotate-90-ns{transform:rotate(90deg)}.swagger-ui .rotate-135-ns{transform:rotate(135deg)}.swagger-ui .rotate-180-ns{transform:rotate(180deg)}.swagger-ui .rotate-225-ns{transform:rotate(225deg)}.swagger-ui .rotate-270-ns{transform:rotate(270deg)}.swagger-ui .rotate-315-ns{transform:rotate(315deg)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .rotate-45-m{transform:rotate(45deg)}.swagger-ui .rotate-90-m{transform:rotate(90deg)}.swagger-ui .rotate-135-m{transform:rotate(135deg)}.swagger-ui .rotate-180-m{transform:rotate(180deg)}.swagger-ui .rotate-225-m{transform:rotate(225deg)}.swagger-ui .rotate-270-m{transform:rotate(270deg)}.swagger-ui .rotate-315-m{transform:rotate(315deg)}}@media screen and (min-width:60em){.swagger-ui .rotate-45-l{transform:rotate(45deg)}.swagger-ui .rotate-90-l{transform:rotate(90deg)}.swagger-ui .rotate-135-l{transform:rotate(135deg)}.swagger-ui .rotate-180-l{transform:rotate(180deg)}.swagger-ui .rotate-225-l{transform:rotate(225deg)}.swagger-ui .rotate-270-l{transform:rotate(270deg)}.swagger-ui .rotate-315-l{transform:rotate(315deg)}}.swagger-ui .black-90{color:rgba(0,0,0,.9)}.swagger-ui .black-80{color:rgba(0,0,0,.8)}.swagger-ui .black-70{color:rgba(0,0,0,.7)}.swagger-ui .black-60{color:rgba(0,0,0,.6)}.swagger-ui .black-50{color:rgba(0,0,0,.5)}.swagger-ui .black-40{color:rgba(0,0,0,.4)}.swagger-ui .black-30{color:rgba(0,0,0,.3)}.swagger-ui .black-20{color:rgba(0,0,0,.2)}.swagger-ui .black-10{color:rgba(0,0,0,.1)}.swagger-ui .black-05{color:rgba(0,0,0,.05)}.swagger-ui .white-90{color:hsla(0,0%,100%,.9)}.swagger-ui .white-80{color:hsla(0,0%,100%,.8)}.swagger-ui .white-70{color:hsla(0,0%,100%,.7)}.swagger-ui .white-60{color:hsla(0,0%,100%,.6)}.swagger-ui .white-50{color:hsla(0,0%,100%,.5)}.swagger-ui .white-40{color:hsla(0,0%,100%,.4)}.swagger-ui .white-30{color:hsla(0,0%,100%,.3)}.swagger-ui .white-20{color:hsla(0,0%,100%,.2)}.swagger-ui .white-10{color:hsla(0,0%,100%,.1)}.swagger-ui .black{color:#000}.swagger-ui .near-black{color:#111}.swagger-ui .dark-gray{color:#333}.swagger-ui .mid-gray{color:#555}.swagger-ui .gray{color:#777}.swagger-ui .silver{color:#999}.swagger-ui .light-silver{color:#aaa}.swagger-ui .moon-gray{color:#ccc}.swagger-ui .light-gray{color:#eee}.swagger-ui .near-white{color:#f4f4f4}.swagger-ui .white{color:#fff}.swagger-ui .dark-red{color:#e7040f}.swagger-ui .red{color:#ff4136}.swagger-ui .light-red{color:#ff725c}.swagger-ui .orange{color:#ff6300}.swagger-ui .gold{color:#ffb700}.swagger-ui .yellow{color:gold}.swagger-ui .light-yellow{color:#fbf1a9}.swagger-ui .purple{color:#5e2ca5}.swagger-ui .light-purple{color:#a463f2}.swagger-ui .dark-pink{color:#d5008f}.swagger-ui .hot-pink{color:#ff41b4}.swagger-ui .pink{color:#ff80cc}.swagger-ui .light-pink{color:#ffa3d7}.swagger-ui .dark-green{color:#137752}.swagger-ui .green{color:#19a974}.swagger-ui .light-green{color:#9eebcf}.swagger-ui .navy{color:#001b44}.swagger-ui .dark-blue{color:#00449e}.swagger-ui .blue{color:#357edd}.swagger-ui .light-blue{color:#96ccff}.swagger-ui .lightest-blue{color:#cdecff}.swagger-ui .washed-blue{color:#f6fffe}.swagger-ui .washed-green{color:#e8fdf5}.swagger-ui .washed-yellow{color:#fffceb}.swagger-ui .washed-red{color:#ffdfdf}.swagger-ui .color-inherit{color:inherit}.swagger-ui .bg-black-90{background-color:rgba(0,0,0,.9)}.swagger-ui .bg-black-80{background-color:rgba(0,0,0,.8)}.swagger-ui .bg-black-70{background-color:rgba(0,0,0,.7)}.swagger-ui .bg-black-60{background-color:rgba(0,0,0,.6)}.swagger-ui .bg-black-50{background-color:rgba(0,0,0,.5)}.swagger-ui .bg-black-40{background-color:rgba(0,0,0,.4)}.swagger-ui .bg-black-30{background-color:rgba(0,0,0,.3)}.swagger-ui .bg-black-20{background-color:rgba(0,0,0,.2)}.swagger-ui .bg-black-10{background-color:rgba(0,0,0,.1)}.swagger-ui .bg-black-05{background-color:rgba(0,0,0,.05)}.swagger-ui .bg-white-90{background-color:hsla(0,0%,100%,.9)}.swagger-ui .bg-white-80{background-color:hsla(0,0%,100%,.8)}.swagger-ui .bg-white-70{background-color:hsla(0,0%,100%,.7)}.swagger-ui .bg-white-60{background-color:hsla(0,0%,100%,.6)}.swagger-ui .bg-white-50{background-color:hsla(0,0%,100%,.5)}.swagger-ui .bg-white-40{background-color:hsla(0,0%,100%,.4)}.swagger-ui .bg-white-30{background-color:hsla(0,0%,100%,.3)}.swagger-ui .bg-white-20{background-color:hsla(0,0%,100%,.2)}.swagger-ui .bg-white-10{background-color:hsla(0,0%,100%,.1)}.swagger-ui .bg-black{background-color:#000}.swagger-ui .bg-near-black{background-color:#111}.swagger-ui .bg-dark-gray{background-color:#333}.swagger-ui .bg-mid-gray{background-color:#555}.swagger-ui .bg-gray{background-color:#777}.swagger-ui .bg-silver{background-color:#999}.swagger-ui .bg-light-silver{background-color:#aaa}.swagger-ui .bg-moon-gray{background-color:#ccc}.swagger-ui .bg-light-gray{background-color:#eee}.swagger-ui .bg-near-white{background-color:#f4f4f4}.swagger-ui .bg-white{background-color:#fff}.swagger-ui .bg-transparent{background-color:transparent}.swagger-ui .bg-dark-red{background-color:#e7040f}.swagger-ui .bg-red{background-color:#ff4136}.swagger-ui .bg-light-red{background-color:#ff725c}.swagger-ui .bg-orange{background-color:#ff6300}.swagger-ui .bg-gold{background-color:#ffb700}.swagger-ui .bg-yellow{background-color:gold}.swagger-ui .bg-light-yellow{background-color:#fbf1a9}.swagger-ui .bg-purple{background-color:#5e2ca5}.swagger-ui .bg-light-purple{background-color:#a463f2}.swagger-ui .bg-dark-pink{background-color:#d5008f}.swagger-ui .bg-hot-pink{background-color:#ff41b4}.swagger-ui .bg-pink{background-color:#ff80cc}.swagger-ui .bg-light-pink{background-color:#ffa3d7}.swagger-ui .bg-dark-green{background-color:#137752}.swagger-ui .bg-green{background-color:#19a974}.swagger-ui .bg-light-green{background-color:#9eebcf}.swagger-ui .bg-navy{background-color:#001b44}.swagger-ui .bg-dark-blue{background-color:#00449e}.swagger-ui .bg-blue{background-color:#357edd}.swagger-ui .bg-light-blue{background-color:#96ccff}.swagger-ui .bg-lightest-blue{background-color:#cdecff}.swagger-ui .bg-washed-blue{background-color:#f6fffe}.swagger-ui .bg-washed-green{background-color:#e8fdf5}.swagger-ui .bg-washed-yellow{background-color:#fffceb}.swagger-ui .bg-washed-red{background-color:#ffdfdf}.swagger-ui .bg-inherit{background-color:inherit}.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover{color:#000}.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover{color:#111}.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover{color:#333}.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover{color:#555}.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover{color:#777}.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover{color:#999}.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover{color:#aaa}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover{color:#eee}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover{color:#f4f4f4}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover{color:#fff}.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:rgba(0,0,0,.9)}.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:rgba(0,0,0,.8)}.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:rgba(0,0,0,.7)}.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:rgba(0,0,0,.6)}.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:rgba(0,0,0,.5)}.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:rgba(0,0,0,.4)}.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:rgba(0,0,0,.3)}.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:rgba(0,0,0,.2)}.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:rgba(0,0,0,.1)}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover{color:hsla(0,0%,100%,.9)}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover{color:hsla(0,0%,100%,.8)}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover{color:hsla(0,0%,100%,.7)}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover{color:hsla(0,0%,100%,.6)}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover{color:hsla(0,0%,100%,.5)}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover{color:hsla(0,0%,100%,.4)}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover{color:hsla(0,0%,100%,.3)}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover{color:hsla(0,0%,100%,.2)}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover{color:hsla(0,0%,100%,.1)}.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover{color:inherit}.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#111}.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#555}.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#777}.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover{background-color:#aaa}.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover{background-color:#ccc}.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover{background-color:#eee}.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover{background-color:#f4f4f4}.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#fff}.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:transparent}.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:hsla(0,0%,100%,.9)}.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:hsla(0,0%,100%,.8)}.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:hsla(0,0%,100%,.7)}.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:hsla(0,0%,100%,.6)}.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:hsla(0,0%,100%,.5)}.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:hsla(0,0%,100%,.4)}.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:hsla(0,0%,100%,.3)}.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:hsla(0,0%,100%,.2)}.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover{background-color:hsla(0,0%,100%,.1)}.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e7040f}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover{color:#ff4136}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover{color:#ff725c}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover{color:#ff6300}.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#ffb700}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover{color:gold}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover{color:#fbf1a9}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover{color:#5e2ca5}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover{color:#a463f2}.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#d5008f}.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover{color:#ff41b4}.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover{color:#ff80cc}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover{color:#ffa3d7}.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover{color:#137752}.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#19a974}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover{color:#9eebcf}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover{color:#001b44}.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#00449e}.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover{color:#357edd}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover{color:#96ccff}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover{color:#cdecff}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover{color:#f6fffe}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover{color:#e8fdf5}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover{color:#fffceb}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover{color:#ffdfdf}.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#e7040f}.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#ff4136}.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ff725c}.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#ff6300}.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover{background-color:#ffb700}.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:gold}.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover{background-color:#fbf1a9}.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#a463f2}.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#d5008f}.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#ff41b4}.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#ff80cc}.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#ffa3d7}.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#137752}.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#19a974}.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#9eebcf}.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#001b44}.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#00449e}.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#357edd}.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#96ccff}.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#cdecff}.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#f6fffe}.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#e8fdf5}.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover{background-color:#fffceb}.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#ffdfdf}.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .pa0{padding:0}.swagger-ui .pa1{padding:.25rem}.swagger-ui .pa2{padding:.5rem}.swagger-ui .pa3{padding:1rem}.swagger-ui .pa4{padding:2rem}.swagger-ui .pa5{padding:4rem}.swagger-ui .pa6{padding:8rem}.swagger-ui .pa7{padding:16rem}.swagger-ui .pl0{padding-left:0}.swagger-ui .pl1{padding-left:.25rem}.swagger-ui .pl2{padding-left:.5rem}.swagger-ui .pl3{padding-left:1rem}.swagger-ui .pl4{padding-left:2rem}.swagger-ui .pl5{padding-left:4rem}.swagger-ui .pl6{padding-left:8rem}.swagger-ui .pl7{padding-left:16rem}.swagger-ui .pr0{padding-right:0}.swagger-ui .pr1{padding-right:.25rem}.swagger-ui .pr2{padding-right:.5rem}.swagger-ui .pr3{padding-right:1rem}.swagger-ui .pr4{padding-right:2rem}.swagger-ui .pr5{padding-right:4rem}.swagger-ui .pr6{padding-right:8rem}.swagger-ui .pr7{padding-right:16rem}.swagger-ui .pb0{padding-bottom:0}.swagger-ui .pb1{padding-bottom:.25rem}.swagger-ui .pb2{padding-bottom:.5rem}.swagger-ui .pb3{padding-bottom:1rem}.swagger-ui .pb4{padding-bottom:2rem}.swagger-ui .pb5{padding-bottom:4rem}.swagger-ui .pb6{padding-bottom:8rem}.swagger-ui .pb7{padding-bottom:16rem}.swagger-ui .pt0{padding-top:0}.swagger-ui .pt1{padding-top:.25rem}.swagger-ui .pt2{padding-top:.5rem}.swagger-ui .pt3{padding-top:1rem}.swagger-ui .pt4{padding-top:2rem}.swagger-ui .pt5{padding-top:4rem}.swagger-ui .pt6{padding-top:8rem}.swagger-ui .pt7{padding-top:16rem}.swagger-ui .pv0{padding-top:0;padding-bottom:0}.swagger-ui .pv1{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0{padding-left:0;padding-right:0}.swagger-ui .ph1{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0{margin:0}.swagger-ui .ma1{margin:.25rem}.swagger-ui .ma2{margin:.5rem}.swagger-ui .ma3{margin:1rem}.swagger-ui .ma4{margin:2rem}.swagger-ui .ma5{margin:4rem}.swagger-ui .ma6{margin:8rem}.swagger-ui .ma7{margin:16rem}.swagger-ui .ml0{margin-left:0}.swagger-ui .ml1{margin-left:.25rem}.swagger-ui .ml2{margin-left:.5rem}.swagger-ui .ml3{margin-left:1rem}.swagger-ui .ml4{margin-left:2rem}.swagger-ui .ml5{margin-left:4rem}.swagger-ui .ml6{margin-left:8rem}.swagger-ui .ml7{margin-left:16rem}.swagger-ui .mr0{margin-right:0}.swagger-ui .mr1{margin-right:.25rem}.swagger-ui .mr2{margin-right:.5rem}.swagger-ui .mr3{margin-right:1rem}.swagger-ui .mr4{margin-right:2rem}.swagger-ui .mr5{margin-right:4rem}.swagger-ui .mr6{margin-right:8rem}.swagger-ui .mr7{margin-right:16rem}.swagger-ui .mb0{margin-bottom:0}.swagger-ui .mb1{margin-bottom:.25rem}.swagger-ui .mb2{margin-bottom:.5rem}.swagger-ui .mb3{margin-bottom:1rem}.swagger-ui .mb4{margin-bottom:2rem}.swagger-ui .mb5{margin-bottom:4rem}.swagger-ui .mb6{margin-bottom:8rem}.swagger-ui .mb7{margin-bottom:16rem}.swagger-ui .mt0{margin-top:0}.swagger-ui .mt1{margin-top:.25rem}.swagger-ui .mt2{margin-top:.5rem}.swagger-ui .mt3{margin-top:1rem}.swagger-ui .mt4{margin-top:2rem}.swagger-ui .mt5{margin-top:4rem}.swagger-ui .mt6{margin-top:8rem}.swagger-ui .mt7{margin-top:16rem}.swagger-ui .mv0{margin-top:0;margin-bottom:0}.swagger-ui .mv1{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0{margin-left:0;margin-right:0}.swagger-ui .mh1{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.swagger-ui .pa0-ns{padding:0}.swagger-ui .pa1-ns{padding:.25rem}.swagger-ui .pa2-ns{padding:.5rem}.swagger-ui .pa3-ns{padding:1rem}.swagger-ui .pa4-ns{padding:2rem}.swagger-ui .pa5-ns{padding:4rem}.swagger-ui .pa6-ns{padding:8rem}.swagger-ui .pa7-ns{padding:16rem}.swagger-ui .pl0-ns{padding-left:0}.swagger-ui .pl1-ns{padding-left:.25rem}.swagger-ui .pl2-ns{padding-left:.5rem}.swagger-ui .pl3-ns{padding-left:1rem}.swagger-ui .pl4-ns{padding-left:2rem}.swagger-ui .pl5-ns{padding-left:4rem}.swagger-ui .pl6-ns{padding-left:8rem}.swagger-ui .pl7-ns{padding-left:16rem}.swagger-ui .pr0-ns{padding-right:0}.swagger-ui .pr1-ns{padding-right:.25rem}.swagger-ui .pr2-ns{padding-right:.5rem}.swagger-ui .pr3-ns{padding-right:1rem}.swagger-ui .pr4-ns{padding-right:2rem}.swagger-ui .pr5-ns{padding-right:4rem}.swagger-ui .pr6-ns{padding-right:8rem}.swagger-ui .pr7-ns{padding-right:16rem}.swagger-ui .pb0-ns{padding-bottom:0}.swagger-ui .pb1-ns{padding-bottom:.25rem}.swagger-ui .pb2-ns{padding-bottom:.5rem}.swagger-ui .pb3-ns{padding-bottom:1rem}.swagger-ui .pb4-ns{padding-bottom:2rem}.swagger-ui .pb5-ns{padding-bottom:4rem}.swagger-ui .pb6-ns{padding-bottom:8rem}.swagger-ui .pb7-ns{padding-bottom:16rem}.swagger-ui .pt0-ns{padding-top:0}.swagger-ui .pt1-ns{padding-top:.25rem}.swagger-ui .pt2-ns{padding-top:.5rem}.swagger-ui .pt3-ns{padding-top:1rem}.swagger-ui .pt4-ns{padding-top:2rem}.swagger-ui .pt5-ns{padding-top:4rem}.swagger-ui .pt6-ns{padding-top:8rem}.swagger-ui .pt7-ns{padding-top:16rem}.swagger-ui .pv0-ns{padding-top:0;padding-bottom:0}.swagger-ui .pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-ns{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-ns{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-ns{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-ns{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-ns{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-ns{padding-left:0;padding-right:0}.swagger-ui .ph1-ns{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-ns{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-ns{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-ns{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-ns{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-ns{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-ns{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-ns{margin:0}.swagger-ui .ma1-ns{margin:.25rem}.swagger-ui .ma2-ns{margin:.5rem}.swagger-ui .ma3-ns{margin:1rem}.swagger-ui .ma4-ns{margin:2rem}.swagger-ui .ma5-ns{margin:4rem}.swagger-ui .ma6-ns{margin:8rem}.swagger-ui .ma7-ns{margin:16rem}.swagger-ui .ml0-ns{margin-left:0}.swagger-ui .ml1-ns{margin-left:.25rem}.swagger-ui .ml2-ns{margin-left:.5rem}.swagger-ui .ml3-ns{margin-left:1rem}.swagger-ui .ml4-ns{margin-left:2rem}.swagger-ui .ml5-ns{margin-left:4rem}.swagger-ui .ml6-ns{margin-left:8rem}.swagger-ui .ml7-ns{margin-left:16rem}.swagger-ui .mr0-ns{margin-right:0}.swagger-ui .mr1-ns{margin-right:.25rem}.swagger-ui .mr2-ns{margin-right:.5rem}.swagger-ui .mr3-ns{margin-right:1rem}.swagger-ui .mr4-ns{margin-right:2rem}.swagger-ui .mr5-ns{margin-right:4rem}.swagger-ui .mr6-ns{margin-right:8rem}.swagger-ui .mr7-ns{margin-right:16rem}.swagger-ui .mb0-ns{margin-bottom:0}.swagger-ui .mb1-ns{margin-bottom:.25rem}.swagger-ui .mb2-ns{margin-bottom:.5rem}.swagger-ui .mb3-ns{margin-bottom:1rem}.swagger-ui .mb4-ns{margin-bottom:2rem}.swagger-ui .mb5-ns{margin-bottom:4rem}.swagger-ui .mb6-ns{margin-bottom:8rem}.swagger-ui .mb7-ns{margin-bottom:16rem}.swagger-ui .mt0-ns{margin-top:0}.swagger-ui .mt1-ns{margin-top:.25rem}.swagger-ui .mt2-ns{margin-top:.5rem}.swagger-ui .mt3-ns{margin-top:1rem}.swagger-ui .mt4-ns{margin-top:2rem}.swagger-ui .mt5-ns{margin-top:4rem}.swagger-ui .mt6-ns{margin-top:8rem}.swagger-ui .mt7-ns{margin-top:16rem}.swagger-ui .mv0-ns{margin-top:0;margin-bottom:0}.swagger-ui .mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-ns{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-ns{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-ns{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-ns{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-ns{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-ns{margin-left:0;margin-right:0}.swagger-ui .mh1-ns{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-ns{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-ns{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-ns{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-ns{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-ns{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .pa0-m{padding:0}.swagger-ui .pa1-m{padding:.25rem}.swagger-ui .pa2-m{padding:.5rem}.swagger-ui .pa3-m{padding:1rem}.swagger-ui .pa4-m{padding:2rem}.swagger-ui .pa5-m{padding:4rem}.swagger-ui .pa6-m{padding:8rem}.swagger-ui .pa7-m{padding:16rem}.swagger-ui .pl0-m{padding-left:0}.swagger-ui .pl1-m{padding-left:.25rem}.swagger-ui .pl2-m{padding-left:.5rem}.swagger-ui .pl3-m{padding-left:1rem}.swagger-ui .pl4-m{padding-left:2rem}.swagger-ui .pl5-m{padding-left:4rem}.swagger-ui .pl6-m{padding-left:8rem}.swagger-ui .pl7-m{padding-left:16rem}.swagger-ui .pr0-m{padding-right:0}.swagger-ui .pr1-m{padding-right:.25rem}.swagger-ui .pr2-m{padding-right:.5rem}.swagger-ui .pr3-m{padding-right:1rem}.swagger-ui .pr4-m{padding-right:2rem}.swagger-ui .pr5-m{padding-right:4rem}.swagger-ui .pr6-m{padding-right:8rem}.swagger-ui .pr7-m{padding-right:16rem}.swagger-ui .pb0-m{padding-bottom:0}.swagger-ui .pb1-m{padding-bottom:.25rem}.swagger-ui .pb2-m{padding-bottom:.5rem}.swagger-ui .pb3-m{padding-bottom:1rem}.swagger-ui .pb4-m{padding-bottom:2rem}.swagger-ui .pb5-m{padding-bottom:4rem}.swagger-ui .pb6-m{padding-bottom:8rem}.swagger-ui .pb7-m{padding-bottom:16rem}.swagger-ui .pt0-m{padding-top:0}.swagger-ui .pt1-m{padding-top:.25rem}.swagger-ui .pt2-m{padding-top:.5rem}.swagger-ui .pt3-m{padding-top:1rem}.swagger-ui .pt4-m{padding-top:2rem}.swagger-ui .pt5-m{padding-top:4rem}.swagger-ui .pt6-m{padding-top:8rem}.swagger-ui .pt7-m{padding-top:16rem}.swagger-ui .pv0-m{padding-top:0;padding-bottom:0}.swagger-ui .pv1-m{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-m{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-m{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-m{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-m{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-m{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-m{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-m{padding-left:0;padding-right:0}.swagger-ui .ph1-m{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-m{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-m{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-m{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-m{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-m{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-m{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-m{margin:0}.swagger-ui .ma1-m{margin:.25rem}.swagger-ui .ma2-m{margin:.5rem}.swagger-ui .ma3-m{margin:1rem}.swagger-ui .ma4-m{margin:2rem}.swagger-ui .ma5-m{margin:4rem}.swagger-ui .ma6-m{margin:8rem}.swagger-ui .ma7-m{margin:16rem}.swagger-ui .ml0-m{margin-left:0}.swagger-ui .ml1-m{margin-left:.25rem}.swagger-ui .ml2-m{margin-left:.5rem}.swagger-ui .ml3-m{margin-left:1rem}.swagger-ui .ml4-m{margin-left:2rem}.swagger-ui .ml5-m{margin-left:4rem}.swagger-ui .ml6-m{margin-left:8rem}.swagger-ui .ml7-m{margin-left:16rem}.swagger-ui .mr0-m{margin-right:0}.swagger-ui .mr1-m{margin-right:.25rem}.swagger-ui .mr2-m{margin-right:.5rem}.swagger-ui .mr3-m{margin-right:1rem}.swagger-ui .mr4-m{margin-right:2rem}.swagger-ui .mr5-m{margin-right:4rem}.swagger-ui .mr6-m{margin-right:8rem}.swagger-ui .mr7-m{margin-right:16rem}.swagger-ui .mb0-m{margin-bottom:0}.swagger-ui .mb1-m{margin-bottom:.25rem}.swagger-ui .mb2-m{margin-bottom:.5rem}.swagger-ui .mb3-m{margin-bottom:1rem}.swagger-ui .mb4-m{margin-bottom:2rem}.swagger-ui .mb5-m{margin-bottom:4rem}.swagger-ui .mb6-m{margin-bottom:8rem}.swagger-ui .mb7-m{margin-bottom:16rem}.swagger-ui .mt0-m{margin-top:0}.swagger-ui .mt1-m{margin-top:.25rem}.swagger-ui .mt2-m{margin-top:.5rem}.swagger-ui .mt3-m{margin-top:1rem}.swagger-ui .mt4-m{margin-top:2rem}.swagger-ui .mt5-m{margin-top:4rem}.swagger-ui .mt6-m{margin-top:8rem}.swagger-ui .mt7-m{margin-top:16rem}.swagger-ui .mv0-m{margin-top:0;margin-bottom:0}.swagger-ui .mv1-m{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-m{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-m{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-m{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-m{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-m{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-m{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-m{margin-left:0;margin-right:0}.swagger-ui .mh1-m{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-m{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-m{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-m{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-m{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-m{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.swagger-ui .pa0-l{padding:0}.swagger-ui .pa1-l{padding:.25rem}.swagger-ui .pa2-l{padding:.5rem}.swagger-ui .pa3-l{padding:1rem}.swagger-ui .pa4-l{padding:2rem}.swagger-ui .pa5-l{padding:4rem}.swagger-ui .pa6-l{padding:8rem}.swagger-ui .pa7-l{padding:16rem}.swagger-ui .pl0-l{padding-left:0}.swagger-ui .pl1-l{padding-left:.25rem}.swagger-ui .pl2-l{padding-left:.5rem}.swagger-ui .pl3-l{padding-left:1rem}.swagger-ui .pl4-l{padding-left:2rem}.swagger-ui .pl5-l{padding-left:4rem}.swagger-ui .pl6-l{padding-left:8rem}.swagger-ui .pl7-l{padding-left:16rem}.swagger-ui .pr0-l{padding-right:0}.swagger-ui .pr1-l{padding-right:.25rem}.swagger-ui .pr2-l{padding-right:.5rem}.swagger-ui .pr3-l{padding-right:1rem}.swagger-ui .pr4-l{padding-right:2rem}.swagger-ui .pr5-l{padding-right:4rem}.swagger-ui .pr6-l{padding-right:8rem}.swagger-ui .pr7-l{padding-right:16rem}.swagger-ui .pb0-l{padding-bottom:0}.swagger-ui .pb1-l{padding-bottom:.25rem}.swagger-ui .pb2-l{padding-bottom:.5rem}.swagger-ui .pb3-l{padding-bottom:1rem}.swagger-ui .pb4-l{padding-bottom:2rem}.swagger-ui .pb5-l{padding-bottom:4rem}.swagger-ui .pb6-l{padding-bottom:8rem}.swagger-ui .pb7-l{padding-bottom:16rem}.swagger-ui .pt0-l{padding-top:0}.swagger-ui .pt1-l{padding-top:.25rem}.swagger-ui .pt2-l{padding-top:.5rem}.swagger-ui .pt3-l{padding-top:1rem}.swagger-ui .pt4-l{padding-top:2rem}.swagger-ui .pt5-l{padding-top:4rem}.swagger-ui .pt6-l{padding-top:8rem}.swagger-ui .pt7-l{padding-top:16rem}.swagger-ui .pv0-l{padding-top:0;padding-bottom:0}.swagger-ui .pv1-l{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-l{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-l{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-l{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-l{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-l{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-l{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-l{padding-left:0;padding-right:0}.swagger-ui .ph1-l{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-l{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-l{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-l{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-l{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-l{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-l{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-l{margin:0}.swagger-ui .ma1-l{margin:.25rem}.swagger-ui .ma2-l{margin:.5rem}.swagger-ui .ma3-l{margin:1rem}.swagger-ui .ma4-l{margin:2rem}.swagger-ui .ma5-l{margin:4rem}.swagger-ui .ma6-l{margin:8rem}.swagger-ui .ma7-l{margin:16rem}.swagger-ui .ml0-l{margin-left:0}.swagger-ui .ml1-l{margin-left:.25rem}.swagger-ui .ml2-l{margin-left:.5rem}.swagger-ui .ml3-l{margin-left:1rem}.swagger-ui .ml4-l{margin-left:2rem}.swagger-ui .ml5-l{margin-left:4rem}.swagger-ui .ml6-l{margin-left:8rem}.swagger-ui .ml7-l{margin-left:16rem}.swagger-ui .mr0-l{margin-right:0}.swagger-ui .mr1-l{margin-right:.25rem}.swagger-ui .mr2-l{margin-right:.5rem}.swagger-ui .mr3-l{margin-right:1rem}.swagger-ui .mr4-l{margin-right:2rem}.swagger-ui .mr5-l{margin-right:4rem}.swagger-ui .mr6-l{margin-right:8rem}.swagger-ui .mr7-l{margin-right:16rem}.swagger-ui .mb0-l{margin-bottom:0}.swagger-ui .mb1-l{margin-bottom:.25rem}.swagger-ui .mb2-l{margin-bottom:.5rem}.swagger-ui .mb3-l{margin-bottom:1rem}.swagger-ui .mb4-l{margin-bottom:2rem}.swagger-ui .mb5-l{margin-bottom:4rem}.swagger-ui .mb6-l{margin-bottom:8rem}.swagger-ui .mb7-l{margin-bottom:16rem}.swagger-ui .mt0-l{margin-top:0}.swagger-ui .mt1-l{margin-top:.25rem}.swagger-ui .mt2-l{margin-top:.5rem}.swagger-ui .mt3-l{margin-top:1rem}.swagger-ui .mt4-l{margin-top:2rem}.swagger-ui .mt5-l{margin-top:4rem}.swagger-ui .mt6-l{margin-top:8rem}.swagger-ui .mt7-l{margin-top:16rem}.swagger-ui .mv0-l{margin-top:0;margin-bottom:0}.swagger-ui .mv1-l{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-l{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-l{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-l{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-l{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-l{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-l{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-l{margin-left:0;margin-right:0}.swagger-ui .mh1-l{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-l{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-l{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-l{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-l{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-l{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-l{margin-left:16rem;margin-right:16rem}}.swagger-ui .na1{margin:-.25rem}.swagger-ui .na2{margin:-.5rem}.swagger-ui .na3{margin:-1rem}.swagger-ui .na4{margin:-2rem}.swagger-ui .na5{margin:-4rem}.swagger-ui .na6{margin:-8rem}.swagger-ui .na7{margin:-16rem}.swagger-ui .nl1{margin-left:-.25rem}.swagger-ui .nl2{margin-left:-.5rem}.swagger-ui .nl3{margin-left:-1rem}.swagger-ui .nl4{margin-left:-2rem}.swagger-ui .nl5{margin-left:-4rem}.swagger-ui .nl6{margin-left:-8rem}.swagger-ui .nl7{margin-left:-16rem}.swagger-ui .nr1{margin-right:-.25rem}.swagger-ui .nr2{margin-right:-.5rem}.swagger-ui .nr3{margin-right:-1rem}.swagger-ui .nr4{margin-right:-2rem}.swagger-ui .nr5{margin-right:-4rem}.swagger-ui .nr6{margin-right:-8rem}.swagger-ui .nr7{margin-right:-16rem}.swagger-ui .nb1{margin-bottom:-.25rem}.swagger-ui .nb2{margin-bottom:-.5rem}.swagger-ui .nb3{margin-bottom:-1rem}.swagger-ui .nb4{margin-bottom:-2rem}.swagger-ui .nb5{margin-bottom:-4rem}.swagger-ui .nb6{margin-bottom:-8rem}.swagger-ui .nb7{margin-bottom:-16rem}.swagger-ui .nt1{margin-top:-.25rem}.swagger-ui .nt2{margin-top:-.5rem}.swagger-ui .nt3{margin-top:-1rem}.swagger-ui .nt4{margin-top:-2rem}.swagger-ui .nt5{margin-top:-4rem}.swagger-ui .nt6{margin-top:-8rem}.swagger-ui .nt7{margin-top:-16rem}@media screen and (min-width:30em){.swagger-ui .na1-ns{margin:-.25rem}.swagger-ui .na2-ns{margin:-.5rem}.swagger-ui .na3-ns{margin:-1rem}.swagger-ui .na4-ns{margin:-2rem}.swagger-ui .na5-ns{margin:-4rem}.swagger-ui .na6-ns{margin:-8rem}.swagger-ui .na7-ns{margin:-16rem}.swagger-ui .nl1-ns{margin-left:-.25rem}.swagger-ui .nl2-ns{margin-left:-.5rem}.swagger-ui .nl3-ns{margin-left:-1rem}.swagger-ui .nl4-ns{margin-left:-2rem}.swagger-ui .nl5-ns{margin-left:-4rem}.swagger-ui .nl6-ns{margin-left:-8rem}.swagger-ui .nl7-ns{margin-left:-16rem}.swagger-ui .nr1-ns{margin-right:-.25rem}.swagger-ui .nr2-ns{margin-right:-.5rem}.swagger-ui .nr3-ns{margin-right:-1rem}.swagger-ui .nr4-ns{margin-right:-2rem}.swagger-ui .nr5-ns{margin-right:-4rem}.swagger-ui .nr6-ns{margin-right:-8rem}.swagger-ui .nr7-ns{margin-right:-16rem}.swagger-ui .nb1-ns{margin-bottom:-.25rem}.swagger-ui .nb2-ns{margin-bottom:-.5rem}.swagger-ui .nb3-ns{margin-bottom:-1rem}.swagger-ui .nb4-ns{margin-bottom:-2rem}.swagger-ui .nb5-ns{margin-bottom:-4rem}.swagger-ui .nb6-ns{margin-bottom:-8rem}.swagger-ui .nb7-ns{margin-bottom:-16rem}.swagger-ui .nt1-ns{margin-top:-.25rem}.swagger-ui .nt2-ns{margin-top:-.5rem}.swagger-ui .nt3-ns{margin-top:-1rem}.swagger-ui .nt4-ns{margin-top:-2rem}.swagger-ui .nt5-ns{margin-top:-4rem}.swagger-ui .nt6-ns{margin-top:-8rem}.swagger-ui .nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .na1-m{margin:-.25rem}.swagger-ui .na2-m{margin:-.5rem}.swagger-ui .na3-m{margin:-1rem}.swagger-ui .na4-m{margin:-2rem}.swagger-ui .na5-m{margin:-4rem}.swagger-ui .na6-m{margin:-8rem}.swagger-ui .na7-m{margin:-16rem}.swagger-ui .nl1-m{margin-left:-.25rem}.swagger-ui .nl2-m{margin-left:-.5rem}.swagger-ui .nl3-m{margin-left:-1rem}.swagger-ui .nl4-m{margin-left:-2rem}.swagger-ui .nl5-m{margin-left:-4rem}.swagger-ui .nl6-m{margin-left:-8rem}.swagger-ui .nl7-m{margin-left:-16rem}.swagger-ui .nr1-m{margin-right:-.25rem}.swagger-ui .nr2-m{margin-right:-.5rem}.swagger-ui .nr3-m{margin-right:-1rem}.swagger-ui .nr4-m{margin-right:-2rem}.swagger-ui .nr5-m{margin-right:-4rem}.swagger-ui .nr6-m{margin-right:-8rem}.swagger-ui .nr7-m{margin-right:-16rem}.swagger-ui .nb1-m{margin-bottom:-.25rem}.swagger-ui .nb2-m{margin-bottom:-.5rem}.swagger-ui .nb3-m{margin-bottom:-1rem}.swagger-ui .nb4-m{margin-bottom:-2rem}.swagger-ui .nb5-m{margin-bottom:-4rem}.swagger-ui .nb6-m{margin-bottom:-8rem}.swagger-ui .nb7-m{margin-bottom:-16rem}.swagger-ui .nt1-m{margin-top:-.25rem}.swagger-ui .nt2-m{margin-top:-.5rem}.swagger-ui .nt3-m{margin-top:-1rem}.swagger-ui .nt4-m{margin-top:-2rem}.swagger-ui .nt5-m{margin-top:-4rem}.swagger-ui .nt6-m{margin-top:-8rem}.swagger-ui .nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.swagger-ui .na1-l{margin:-.25rem}.swagger-ui .na2-l{margin:-.5rem}.swagger-ui .na3-l{margin:-1rem}.swagger-ui .na4-l{margin:-2rem}.swagger-ui .na5-l{margin:-4rem}.swagger-ui .na6-l{margin:-8rem}.swagger-ui .na7-l{margin:-16rem}.swagger-ui .nl1-l{margin-left:-.25rem}.swagger-ui .nl2-l{margin-left:-.5rem}.swagger-ui .nl3-l{margin-left:-1rem}.swagger-ui .nl4-l{margin-left:-2rem}.swagger-ui .nl5-l{margin-left:-4rem}.swagger-ui .nl6-l{margin-left:-8rem}.swagger-ui .nl7-l{margin-left:-16rem}.swagger-ui .nr1-l{margin-right:-.25rem}.swagger-ui .nr2-l{margin-right:-.5rem}.swagger-ui .nr3-l{margin-right:-1rem}.swagger-ui .nr4-l{margin-right:-2rem}.swagger-ui .nr5-l{margin-right:-4rem}.swagger-ui .nr6-l{margin-right:-8rem}.swagger-ui .nr7-l{margin-right:-16rem}.swagger-ui .nb1-l{margin-bottom:-.25rem}.swagger-ui .nb2-l{margin-bottom:-.5rem}.swagger-ui .nb3-l{margin-bottom:-1rem}.swagger-ui .nb4-l{margin-bottom:-2rem}.swagger-ui .nb5-l{margin-bottom:-4rem}.swagger-ui .nb6-l{margin-bottom:-8rem}.swagger-ui .nb7-l{margin-bottom:-16rem}.swagger-ui .nt1-l{margin-top:-.25rem}.swagger-ui .nt2-l{margin-top:-.5rem}.swagger-ui .nt3-l{margin-top:-1rem}.swagger-ui .nt4-l{margin-top:-2rem}.swagger-ui .nt5-l{margin-top:-4rem}.swagger-ui .nt6-l{margin-top:-8rem}.swagger-ui .nt7-l{margin-top:-16rem}}.swagger-ui .collapse{border-collapse:collapse;border-spacing:0}.swagger-ui .striped--light-silver:nth-child(odd){background-color:#aaa}.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#ccc}.swagger-ui .striped--light-gray:nth-child(odd){background-color:#eee}.swagger-ui .striped--near-white:nth-child(odd){background-color:#f4f4f4}.swagger-ui .stripe-light:nth-child(odd){background-color:hsla(0,0%,100%,.1)}.swagger-ui .stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.swagger-ui .strike{text-decoration:line-through}.swagger-ui .underline{text-decoration:underline}.swagger-ui .no-underline{text-decoration:none}@media screen and (min-width:30em){.swagger-ui .strike-ns{text-decoration:line-through}.swagger-ui .underline-ns{text-decoration:underline}.swagger-ui .no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .strike-m{text-decoration:line-through}.swagger-ui .underline-m{text-decoration:underline}.swagger-ui .no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.swagger-ui .strike-l{text-decoration:line-through}.swagger-ui .underline-l{text-decoration:underline}.swagger-ui .no-underline-l{text-decoration:none}}.swagger-ui .tl{text-align:left}.swagger-ui .tr{text-align:right}.swagger-ui .tc{text-align:center}.swagger-ui .tj{text-align:justify}@media screen and (min-width:30em){.swagger-ui .tl-ns{text-align:left}.swagger-ui .tr-ns{text-align:right}.swagger-ui .tc-ns{text-align:center}.swagger-ui .tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tl-m{text-align:left}.swagger-ui .tr-m{text-align:right}.swagger-ui .tc-m{text-align:center}.swagger-ui .tj-m{text-align:justify}}@media screen and (min-width:60em){.swagger-ui .tl-l{text-align:left}.swagger-ui .tr-l{text-align:right}.swagger-ui .tc-l{text-align:center}.swagger-ui .tj-l{text-align:justify}}.swagger-ui .ttc{text-transform:capitalize}.swagger-ui .ttl{text-transform:lowercase}.swagger-ui .ttu{text-transform:uppercase}.swagger-ui .ttn{text-transform:none}@media screen and (min-width:30em){.swagger-ui .ttc-ns{text-transform:capitalize}.swagger-ui .ttl-ns{text-transform:lowercase}.swagger-ui .ttu-ns{text-transform:uppercase}.swagger-ui .ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ttc-m{text-transform:capitalize}.swagger-ui .ttl-m{text-transform:lowercase}.swagger-ui .ttu-m{text-transform:uppercase}.swagger-ui .ttn-m{text-transform:none}}@media screen and (min-width:60em){.swagger-ui .ttc-l{text-transform:capitalize}.swagger-ui .ttl-l{text-transform:lowercase}.swagger-ui .ttu-l{text-transform:uppercase}.swagger-ui .ttn-l{text-transform:none}}.swagger-ui .f-6,.swagger-ui .f-headline{font-size:6rem}.swagger-ui .f-5,.swagger-ui .f-subheadline{font-size:5rem}.swagger-ui .f1{font-size:3rem}.swagger-ui .f2{font-size:2.25rem}.swagger-ui .f3{font-size:1.5rem}.swagger-ui .f4{font-size:1.25rem}.swagger-ui .f5{font-size:1rem}.swagger-ui .f6{font-size:.875rem}.swagger-ui .f7{font-size:.75rem}@media screen and (min-width:30em){.swagger-ui .f-6-ns,.swagger-ui .f-headline-ns{font-size:6rem}.swagger-ui .f-5-ns,.swagger-ui .f-subheadline-ns{font-size:5rem}.swagger-ui .f1-ns{font-size:3rem}.swagger-ui .f2-ns{font-size:2.25rem}.swagger-ui .f3-ns{font-size:1.5rem}.swagger-ui .f4-ns{font-size:1.25rem}.swagger-ui .f5-ns{font-size:1rem}.swagger-ui .f6-ns{font-size:.875rem}.swagger-ui .f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .f-6-m,.swagger-ui .f-headline-m{font-size:6rem}.swagger-ui .f-5-m,.swagger-ui .f-subheadline-m{font-size:5rem}.swagger-ui .f1-m{font-size:3rem}.swagger-ui .f2-m{font-size:2.25rem}.swagger-ui .f3-m{font-size:1.5rem}.swagger-ui .f4-m{font-size:1.25rem}.swagger-ui .f5-m{font-size:1rem}.swagger-ui .f6-m{font-size:.875rem}.swagger-ui .f7-m{font-size:.75rem}}@media screen and (min-width:60em){.swagger-ui .f-6-l,.swagger-ui .f-headline-l{font-size:6rem}.swagger-ui .f-5-l,.swagger-ui .f-subheadline-l{font-size:5rem}.swagger-ui .f1-l{font-size:3rem}.swagger-ui .f2-l{font-size:2.25rem}.swagger-ui .f3-l{font-size:1.5rem}.swagger-ui .f4-l{font-size:1.25rem}.swagger-ui .f5-l{font-size:1rem}.swagger-ui .f6-l{font-size:.875rem}.swagger-ui .f7-l{font-size:.75rem}}.swagger-ui .measure{max-width:30em}.swagger-ui .measure-wide{max-width:34em}.swagger-ui .measure-narrow{max-width:20em}.swagger-ui .indent{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps{font-variant:small-caps}.swagger-ui .truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media screen and (min-width:30em){.swagger-ui .measure-ns{max-width:30em}.swagger-ui .measure-wide-ns{max-width:34em}.swagger-ui .measure-narrow-ns{max-width:20em}.swagger-ui .indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-ns{font-variant:small-caps}.swagger-ui .truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .measure-m{max-width:30em}.swagger-ui .measure-wide-m{max-width:34em}.swagger-ui .measure-narrow-m{max-width:20em}.swagger-ui .indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-m{font-variant:small-caps}.swagger-ui .truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:60em){.swagger-ui .measure-l{max-width:30em}.swagger-ui .measure-wide-l{max-width:34em}.swagger-ui .measure-narrow-l{max-width:20em}.swagger-ui .indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-l{font-variant:small-caps}.swagger-ui .truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.swagger-ui .overflow-container{overflow-y:scroll}.swagger-ui .center{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto{margin-right:auto}.swagger-ui .ml-auto{margin-left:auto}@media screen and (min-width:30em){.swagger-ui .center-ns{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-ns{margin-right:auto}.swagger-ui .ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .center-m{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-m{margin-right:auto}.swagger-ui .ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.swagger-ui .center-l{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-l{margin-right:auto}.swagger-ui .ml-auto-l{margin-left:auto}}.swagger-ui .clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}@media screen and (min-width:30em){.swagger-ui .clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:60em){.swagger-ui .clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}.swagger-ui .ws-normal{white-space:normal}.swagger-ui .nowrap{white-space:nowrap}.swagger-ui .pre{white-space:pre}@media screen and (min-width:30em){.swagger-ui .ws-normal-ns{white-space:normal}.swagger-ui .nowrap-ns{white-space:nowrap}.swagger-ui .pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ws-normal-m{white-space:normal}.swagger-ui .nowrap-m{white-space:nowrap}.swagger-ui .pre-m{white-space:pre}}@media screen and (min-width:60em){.swagger-ui .ws-normal-l{white-space:normal}.swagger-ui .nowrap-l{white-space:nowrap}.swagger-ui .pre-l{white-space:pre}}.swagger-ui .v-base{vertical-align:baseline}.swagger-ui .v-mid{vertical-align:middle}.swagger-ui .v-top{vertical-align:top}.swagger-ui .v-btm{vertical-align:bottom}@media screen and (min-width:30em){.swagger-ui .v-base-ns{vertical-align:baseline}.swagger-ui .v-mid-ns{vertical-align:middle}.swagger-ui .v-top-ns{vertical-align:top}.swagger-ui .v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .v-base-m{vertical-align:baseline}.swagger-ui .v-mid-m{vertical-align:middle}.swagger-ui .v-top-m{vertical-align:top}.swagger-ui .v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.swagger-ui .v-base-l{vertical-align:baseline}.swagger-ui .v-mid-l{vertical-align:middle}.swagger-ui .v-top-l{vertical-align:top}.swagger-ui .v-btm-l{vertical-align:bottom}}.swagger-ui .dim{opacity:1;transition:opacity .15s ease-in}.swagger-ui .dim:focus,.swagger-ui .dim:hover{opacity:.5;transition:opacity .15s ease-in}.swagger-ui .dim:active{opacity:.8;transition:opacity .15s ease-out}.swagger-ui .glow{transition:opacity .15s ease-in}.swagger-ui .glow:focus,.swagger-ui .glow:hover{opacity:1;transition:opacity .15s ease-in}.swagger-ui .hide-child .child{opacity:0;transition:opacity .15s ease-in}.swagger-ui .hide-child:active .child,.swagger-ui .hide-child:focus .child,.swagger-ui .hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.swagger-ui .underline-hover:focus,.swagger-ui .underline-hover:hover{text-decoration:underline}.swagger-ui .grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-out}.swagger-ui .grow:focus,.swagger-ui .grow:hover{transform:scale(1.05)}.swagger-ui .grow:active{transform:scale(.9)}.swagger-ui .grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-in-out}.swagger-ui .grow-large:focus,.swagger-ui .grow-large:hover{transform:scale(1.2)}.swagger-ui .grow-large:active{transform:scale(.95)}.swagger-ui .pointer:hover{cursor:pointer}.swagger-ui .shadow-hover{cursor:pointer;position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:after{content:"";box-shadow:0 0 16px 2px rgba(0,0,0,.2);border-radius:inherit;opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;transition:opacity .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:focus:after,.swagger-ui .shadow-hover:hover:after{opacity:1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .z-0{z-index:0}.swagger-ui .z-1{z-index:1}.swagger-ui .z-2{z-index:2}.swagger-ui .z-3{z-index:3}.swagger-ui .z-4{z-index:4}.swagger-ui .z-5{z-index:5}.swagger-ui .z-999{z-index:999}.swagger-ui .z-9999{z-index:9999}.swagger-ui .z-max{z-index:2147483647}.swagger-ui .z-inherit{z-index:inherit}.swagger-ui .z-initial{z-index:auto}.swagger-ui .z-unset{z-index:unset}.swagger-ui .nested-copy-line-height ol,.swagger-ui .nested-copy-line-height p,.swagger-ui .nested-copy-line-height ul{line-height:1.5}.swagger-ui .nested-headline-line-height h1,.swagger-ui .nested-headline-line-height h2,.swagger-ui .nested-headline-line-height h3,.swagger-ui .nested-headline-line-height h4,.swagger-ui .nested-headline-line-height h5,.swagger-ui .nested-headline-line-height h6{line-height:1.25}.swagger-ui .nested-list-reset ol,.swagger-ui .nested-list-reset ul{padding-left:0;margin-left:0;list-style-type:none}.swagger-ui .nested-copy-indent p+p{text-indent:.1em;margin-top:0;margin-bottom:0}.swagger-ui .nested-copy-seperator p+p{margin-top:1.5em}.swagger-ui .nested-img img{width:100%;max-width:100%;display:block}.swagger-ui .nested-links a{color:#357edd;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.swagger-ui .wrapper{width:100%;max-width:1460px;margin:0 auto;padding:0 20px;box-sizing:border-box}.swagger-ui .opblock-tag-section{display:flex;flex-direction:column}.swagger-ui .try-out.btn-group{padding:0}.swagger-ui .opblock-tag{display:flex;align-items:center;padding:10px 20px 10px 10px;cursor:pointer;transition:all .2s;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{font-size:24px;margin:0 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-tag.no-desc span{flex:1}.swagger-ui .opblock-tag svg{transition:all .4s}.swagger-ui .opblock-tag small{font-size:14px;font-weight:400;flex:1;padding:0 10px;font-family:sans-serif;color:#3b4151}.swagger-ui .parameter__type{font-size:12px;padding:5px 0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .parameter-controls{margin-top:.75em}.swagger-ui .examples__title{display:block;font-size:1.1em;font-weight:700;margin-bottom:.75em}.swagger-ui .examples__section{margin-top:1.5em}.swagger-ui .examples__section-header{font-weight:700;font-size:.9rem;margin-bottom:.5rem}.swagger-ui .examples-select{margin-bottom:.75em}.swagger-ui .examples-select__section-label{font-weight:700;font-size:.9rem;margin-right:.5rem}.swagger-ui .example__section{margin-top:1.5em}.swagger-ui .example__section-header{font-weight:700;font-size:.9rem;margin-bottom:.5rem}.swagger-ui .view-line-link{position:relative;top:3px;width:20px;margin:0 5px;cursor:pointer;transition:all .5s}.swagger-ui .opblock{margin:0 0 15px;border:1px solid #000;border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.19)}.swagger-ui .opblock .tab-header{display:flex;flex:1}.swagger-ui .opblock .tab-header .tab-item{padding:0 40px;cursor:pointer}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{position:absolute;bottom:-15px;left:50%;width:120%;height:4px;content:"";transform:translateX(-50%);background:grey}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{display:flex;align-items:center;padding:8px 20px;min-height:50px;background:hsla(0,0%,100%,.8);box-shadow:0 1px 2px rgba(0,0,0,.1)}.swagger-ui .opblock .opblock-section-header>label{font-size:12px;font-weight:700;display:flex;align-items:center;margin:0 0 0 auto;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{font-size:14px;flex:1;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary-method{font-size:14px;font-weight:700;min-width:80px;padding:6px 15px;text-align:center;border-radius:3px;background:#000;text-shadow:0 1px 0 rgba(0,0,0,.1);font-family:sans-serif;color:#fff}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:16px;display:flex;align-items:center;word-break:break-word;padding:0 10px;font-family:monospace;font-weight:600;color:#3b4151}@media (max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-path{flex-shrink:0;max-width:calc(100% - 110px - 15rem)}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{font-size:13px;flex:1 1 auto;word-break:break-word;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary{display:flex;align-items:center;padding:5px;cursor:pointer}.swagger-ui .opblock .opblock-summary .view-line-link{position:relative;top:2px;width:0;margin:0;cursor:pointer;transition:all .5s}.swagger-ui .opblock .opblock-summary:hover .view-line-link{width:18px;margin:0 5px}.swagger-ui .opblock.opblock-post{border-color:#49cc90;background:rgba(73,204,144,.1)}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{border-color:#fca130;background:rgba(252,161,48,.1)}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{border-color:#f93e3e;background:rgba(249,62,62,.1)}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{border-color:#61affe;background:rgba(97,175,254,.1)}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{border-color:#50e3c2;background:rgba(80,227,194,.1)}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{border-color:#9012fe;background:rgba(144,18,254,.1)}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{border-color:#0d5aa7;background:rgba(13,90,167,.1)}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{opacity:.6;border-color:#ebebeb;background:hsla(0,0%,92.2%,.1)}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{width:100%;margin:20px 0;padding:10px;border:2px solid #d8dde7}.swagger-ui .download-url-wrapper .failed,.swagger-ui .filter .failed{color:red}.swagger-ui .download-url-wrapper .loading,.swagger-ui .filter .loading{color:#aaa}.swagger-ui .model-example{margin-top:1em}.swagger-ui .tab{display:flex;padding:0;list-style:none}.swagger-ui .tab li{font-size:12px;min-width:60px;padding:0;cursor:pointer;font-family:sans-serif;color:#3b4151}.swagger-ui .tab li:first-of-type{position:relative;padding-left:0;padding-right:12px}.swagger-ui .tab li:first-of-type:after{position:absolute;top:0;right:6px;width:1px;height:100%;content:"";background:rgba(0,0,0,.2)}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{font-size:12px;margin:0 0 5px;padding:15px 20px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{font-size:12px;margin:0 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{font-size:14px;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{width:100%;padding:8px 40px}.swagger-ui .body-param-options{display:flex;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{font-size:12px;margin:10px 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .responses-inner .curl{white-space:normal}.swagger-ui .response-col_status{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .response-col_status .response-undocumented{font-size:11px;font-family:monospace;font-weight:600;color:#909090}.swagger-ui .response-col_links{padding-left:2em;max-width:40em;font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .response-col_links .response-undocumented{font-size:11px;font-family:monospace;font-weight:600;color:#909090}.swagger-ui .response-col_links .operation-link{margin-bottom:1.5em}.swagger-ui .response-col_links .operation-link .description{margin-bottom:.5em}.swagger-ui .opblock-body .opblock-loading-animation{display:block;margin:3em auto}.swagger-ui .opblock-body pre.microlight{font-size:12px;margin:0;padding:10px;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;border-radius:4px;background:#333;overflow-wrap:break-word;font-family:monospace;font-weight:600;color:#fff}.swagger-ui .opblock-body pre.microlight .headerline{display:block}.swagger-ui .highlight-code{position:relative}.swagger-ui .highlight-code>.microlight{overflow-y:auto;max-height:400px;min-height:6em}.swagger-ui .highlight-code>.microlight code{white-space:pre-wrap!important;word-break:break-all}.swagger-ui .curl-command{position:relative}.swagger-ui .download-contents{position:absolute;bottom:10px;right:10px;cursor:pointer;background:#7d8293;text-align:center;padding:5px;border-radius:4px;font-family:sans-serif;font-weight:600;color:#fff;font-size:14px;height:30px;width:75px}.swagger-ui .scheme-container{margin:0 0 20px;padding:30px 0;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.15)}.swagger-ui .scheme-container .schemes{display:flex;align-items:flex-end}.swagger-ui .scheme-container .schemes>label{font-size:12px;font-weight:700;display:flex;flex-direction:column;margin:-20px 15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{padding:40px 0 60px;margin-top:1em;min-height:1px;display:flex;justify-content:center;align-items:center;flex-direction:column}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;content:"loading";transform:translate(-50%,-50%);text-transform:uppercase;font-family:sans-serif;color:#3b4151}.swagger-ui .loading-container .loading:before{position:absolute;top:50%;left:50%;display:block;width:60px;height:60px;margin:-30px;content:"";-webkit-animation:rotation 1s linear infinite,opacity .5s;animation:rotation 1s linear infinite,opacity .5s;opacity:1;border:2px solid rgba(85,85,85,.1);border-top-color:rgba(0,0,0,.6);border-radius:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden}@-webkit-keyframes rotation{to{transform:rotate(1turn)}}@keyframes rotation{to{transform:rotate(1turn)}}.swagger-ui .response-controls{padding-top:1em;display:flex}.swagger-ui .response-control-media-type{margin-right:1em}.swagger-ui .response-control-media-type--accept-controller select{border-color:green}.swagger-ui .response-control-media-type__accept-message{color:green;font-size:.7em}.swagger-ui .response-control-examples__title,.swagger-ui .response-control-media-type__title{display:block;margin-bottom:.2em;font-size:.7em}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui .hidden{display:none}.swagger-ui .no-margin{height:auto;border:none;margin:0;padding:0}.swagger-ui .float-right{float:right}.swagger-ui img.full-width{width:100%}.swagger-ui .svg-assets{position:absolute;width:0;height:0}.swagger-ui section h3{font-family:sans-serif;color:#3b4151}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{text-decoration:inherit;color:inherit;cursor:pointer}.swagger-ui .fallback{padding:1em;color:#aaa}.swagger-ui .version-pragma{height:100%;padding:5em 0}.swagger-ui .version-pragma__message{display:flex;justify-content:center;height:100%;font-size:1.2em;text-align:center;line-height:1.5em;padding:0 .6em}.swagger-ui .version-pragma__message>div{max-width:55ch;flex:1}.swagger-ui .version-pragma__message code{background-color:#dedede;padding:4px 4px 2px;white-space:pre}.swagger-ui .opblock-link{font-weight:400}.swagger-ui .opblock-link.shown{font-weight:700}.swagger-ui span.token-string{color:#555}.swagger-ui span.token-not-formatted{color:#555;font-weight:700}.swagger-ui .btn{font-size:14px;font-weight:700;padding:5px 23px;transition:all .3s;border:2px solid grey;border-radius:4px;background:transparent;box-shadow:0 1px 2px rgba(0,0,0,.1);font-family:sans-serif;color:#3b4151}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{border-color:#ff6060;background-color:transparent;font-family:sans-serif;color:#ff6060}.swagger-ui .btn.authorize{line-height:1;display:inline;color:#49cc90;border-color:#49cc90;background-color:transparent}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{background-color:#4990e2;color:#fff;border-color:#4990e2}.swagger-ui .btn-group{display:flex;padding:30px}.swagger-ui .btn-group .btn{flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{padding:0 10px;border:none;background:none}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .expand-methods,.swagger-ui .expand-operation{border:none;background:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{width:20px;height:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{transition:all .3s;fill:#707070}.swagger-ui button{cursor:pointer;outline:none}.swagger-ui button.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui .copy-to-clipboard{position:absolute;bottom:10px;right:100px;width:30px;height:30px;background:#7d8293;border-radius:4px;border:none}.swagger-ui .copy-to-clipboard button{padding-left:25px;border:none;height:25px;background:url('data:image/svg+xml;charset=utf-8,') 50% no-repeat}.swagger-ui .curl-command .copy-to-clipboard{bottom:5px;right:10px;width:20px;height:20px}.swagger-ui .curl-command .copy-to-clipboard button{padding-left:18px;height:18px}.swagger-ui select{font-size:14px;font-weight:700;padding:5px 40px 5px 10px;border:2px solid #41444e;border-radius:4px;background:#f7f7f7 url('data:image/svg+xml;charset=utf-8,') right 10px center no-repeat;background-size:20px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);font-family:sans-serif;color:#3b4151;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui select[multiple]{margin:5px 0;padding:5px;background:#f7f7f7}.swagger-ui select.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui .opblock-body select{min-width:230px}@media (max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}.swagger-ui label{font-size:12px;font-weight:700;margin:0 0 5px;font-family:sans-serif;color:#3b4151}@media (max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{max-width:175px}}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{min-width:100px;margin:5px 0;padding:8px 10px;border:1px solid #d9d9d9;border-radius:4px;background:#fff}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui textarea.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui input[disabled],.swagger-ui select[disabled],.swagger-ui textarea[disabled]{background-color:#fafafa;color:#888;cursor:not-allowed}.swagger-ui select[disabled]{border-color:#888}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}@-webkit-keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}.swagger-ui textarea{font-size:12px;width:100%;min-height:280px;padding:10px;border:none;border-radius:4px;outline:none;background:hsla(0,0%,100%,.8);font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{font-size:12px;min-height:100px;margin:0;padding:10px;resize:none;border-radius:4px;background:#41444e;font-family:monospace;font-weight:600;color:#fff}.swagger-ui .checkbox{padding:5px 0 10px;transition:opacity .5s;color:#303030}.swagger-ui .checkbox label{display:flex}.swagger-ui .checkbox p{font-weight:400!important;font-style:italic;margin:0!important;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{position:relative;top:3px;display:inline-block;width:16px;height:16px;margin:0 8px 0 0;padding:5px;cursor:pointer;border-radius:1px;background:#e8e8e8;box-shadow:0 0 0 2px #e8e8e8;flex:none}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url('data:image/svg+xml;charset=utf-8,') 50% no-repeat}.swagger-ui .dialog-ux{position:fixed;z-index:9999;top:0;right:0;bottom:0;left:0}.swagger-ui .dialog-ux .backdrop-ux{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{position:absolute;z-index:9999;top:50%;left:50%;width:100%;min-width:300px;max-width:650px;transform:translate(-50%,-50%);border:1px solid #ebebeb;border-radius:4px;background:#fff;box-shadow:0 10px 30px 0 rgba(0,0,0,.2)}.swagger-ui .dialog-ux .modal-ux-content{overflow-y:auto;max-height:540px;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{font-size:12px;margin:0 0 5px;color:#41444e;font-family:sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-content h4{font-size:18px;font-weight:600;margin:15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-header{display:flex;padding:12px 0;border-bottom:1px solid #ebebeb;align-items:center}.swagger-ui .dialog-ux .modal-ux-header .close-modal{padding:0 10px;border:none;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui .dialog-ux .modal-ux-header h3{font-size:20px;font-weight:600;margin:0;padding:0 20px;flex:1;font-family:sans-serif;color:#3b4151}.swagger-ui .model{font-size:12px;font-weight:300;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{text-decoration:line-through}.swagger-ui .model-toggle{font-size:10px;position:relative;top:6px;display:inline-block;margin:auto .3em;cursor:pointer;transition:transform .15s ease-in;transform:rotate(90deg);transform-origin:50% 50%}.swagger-ui .model-toggle.collapsed{transform:rotate(0deg)}.swagger-ui .model-toggle:after{display:block;width:20px;height:20px;content:"";background:url('data:image/svg+xml;charset=utf-8,') 50% no-repeat;background-size:100%}.swagger-ui .model-jump-to-path{position:relative;cursor:pointer}.swagger-ui .model-jump-to-path .view-line-link{position:absolute;top:-.4em;cursor:pointer}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{position:absolute;top:-1.8em;visibility:hidden;padding:.1em .5em;white-space:nowrap;color:#ebebeb;border-radius:4px;background:rgba(0,0,0,.7)}.swagger-ui .model p{margin:0 0 1em}.swagger-ui .model .property{color:#999;font-style:italic}.swagger-ui .model .property.primitive{color:#6b6b6b}.swagger-ui table.model tr.description{color:#666;font-weight:400}.swagger-ui table.model tr.description td:first-child{font-weight:700}.swagger-ui table.model tr.property-row.required td:first-child{font-weight:700}.swagger-ui table.model tr.property-row td{vertical-align:top}.swagger-ui table.model tr.property-row td:first-child{padding-right:.2em}.swagger-ui table.model tr.property-row .star{color:red}.swagger-ui table.model tr.extension{color:#777}.swagger-ui table.model tr.extension td:last-child{vertical-align:top}.swagger-ui section.models{margin:30px 0;border:1px solid rgba(59,65,81,.3);border-radius:4px}.swagger-ui section.models .pointer{cursor:pointer}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{margin:0 0 5px;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui section.models h4{font-size:16px;display:flex;align-items:center;margin:0;padding:10px 20px 10px 10px;cursor:pointer;transition:all .2s;font-family:sans-serif;color:#606060}.swagger-ui section.models h4 svg{transition:all .4s}.swagger-ui section.models h4 span{flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{font-size:16px;margin:0 0 10px;font-family:sans-serif;color:#707070}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{margin:0 20px 15px;position:relative;transition:all .5s;border-radius:4px;background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-container .models-jump-to-path{position:absolute;top:8px;right:5px;opacity:.65}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{padding:10px;display:inline-block;border-radius:4px;background:rgba(0,0,0,.1)}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{font-size:16px;font-family:sans-serif;color:#505050}.swagger-ui .model-title img{margin-left:1em;position:relative;bottom:0}.swagger-ui .model-deprecated-warning{font-size:16px;font-weight:600;margin-right:1em;font-family:sans-serif;color:#f93e3e}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#606060}.swagger-ui .servers>label{font-size:12px;margin:-20px 15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .servers>label select{min-width:130px;max-width:100%}.swagger-ui .servers h4.message{padding-bottom:2em}.swagger-ui .servers table tr{width:30em}.swagger-ui .servers table td{display:inline-block;max-width:15em;vertical-align:middle;padding-top:10px;padding-bottom:10px}.swagger-ui .servers table td:first-of-type{padding-right:1em}.swagger-ui .servers table td input{width:100%;height:100%}.swagger-ui .servers .computed-url{margin:2em 0}.swagger-ui .servers .computed-url code{display:inline-block;padding:4px;font-size:16px;margin:0 1em}.swagger-ui .servers-title{font-size:12px;font-weight:700}.swagger-ui .operation-servers h4.message{margin-bottom:2em}.swagger-ui table{width:100%;padding:0 10px;border-collapse:collapse}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{width:174px;padding:0 0 0 2em}.swagger-ui table.headers td{font-size:12px;font-weight:300;vertical-align:middle;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui table.headers .header-example{color:#999;font-style:italic}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{font-size:12px;font-weight:700;padding:12px 0;text-align:left;border-bottom:1px solid rgba(59,65,81,.2);font-family:sans-serif;color:#3b4151}.swagger-ui .parameters-col_description{width:99%;margin-bottom:2em}.swagger-ui .parameters-col_description input[type=text]{width:100%;max-width:340px}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameter__name{font-size:16px;font-weight:400;margin-right:.75em;font-family:sans-serif;color:#3b4151}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required span{color:red}.swagger-ui .parameter__name.required:after{font-size:10px;position:relative;top:-6px;padding:5px;content:"required";color:rgba(255,0,0,.6)}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{font-size:12px;font-style:italic;font-family:monospace;font-weight:600;color:grey}.swagger-ui .parameter__deprecated{font-size:12px;font-style:italic;font-family:monospace;font-weight:600;color:red}.swagger-ui .parameter__empty_value_toggle{display:block;font-size:13px;padding-top:5px;padding-bottom:12px}.swagger-ui .parameter__empty_value_toggle input{margin-right:7px}.swagger-ui .parameter__empty_value_toggle.disabled{opacity:.7}.swagger-ui .table-container{padding:20px}.swagger-ui .response-col_description{width:99%}.swagger-ui .response-col_links{min-width:6em}.swagger-ui .response__extension{font-size:12px;font-style:italic;font-family:monospace;font-weight:600;color:grey}.swagger-ui .topbar{padding:10px 0;background-color:#1b1b1b}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{display:flex;align-items:center}.swagger-ui .topbar a{font-size:1.5em;font-weight:700;flex:1;max-width:300px;text-decoration:none;font-family:sans-serif;color:#fff}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:flex;flex:3;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{width:100%;margin:0;border:2px solid #62a03f;border-radius:4px 0 0 4px;outline:none}.swagger-ui .topbar .download-url-wrapper .select-label{display:flex;align-items:center;width:100%;max-width:600px;margin:0;color:#f0f0f0}.swagger-ui .topbar .download-url-wrapper .select-label span{font-size:16px;flex:1;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{flex:2;width:100%;border:2px solid #62a03f;outline:none;box-shadow:none}.swagger-ui .topbar .download-url-wrapper .download-url-button{font-size:16px;font-weight:700;padding:4px 30px;border:none;border-radius:0 4px 4px 0;background:#62a03f;font-family:sans-serif;color:#fff}.swagger-ui .info{margin:50px 0}.swagger-ui .info.failed-config{max-width:880px;margin-left:auto;margin-right:auto;text-align:center}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info pre{font-size:14px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{font-family:sans-serif;color:#3b4151}.swagger-ui .info a{font-size:14px;transition:all .4s;font-family:sans-serif;color:#4990e2}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{font-size:12px;font-weight:300!important;margin:0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .info .title{font-size:36px;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .info .title small{font-size:10px;position:relative;top:-5px;display:inline-block;margin:0 0 0 5px;padding:2px 4px;vertical-align:super;border-radius:57px;background:#7d8492}.swagger-ui .info .title small.version-stamp{background-color:#89bf04}.swagger-ui .info .title small pre{margin:0;padding:0;font-family:sans-serif;color:#fff}.swagger-ui .auth-btn-wrapper{display:flex;padding:10px 0;justify-content:center}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:flex;flex:1;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{padding-right:20px;margin-right:10px}.swagger-ui .auth-container{margin:0 0 10px;padding:10px 20px;border-bottom:1px solid #ebebeb}.swagger-ui .auth-container:last-of-type{margin:0;padding:10px 20px;border:0}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{font-size:12px;padding:10px;border-radius:4px;background-color:#fee;color:red;margin:1em;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .auth-container .errors b{text-transform:capitalize;margin-right:1em}.swagger-ui .scopes h2{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .scopes h2 a{font-size:12px;color:#4990e2;cursor:pointer;padding-left:10px;text-decoration:underline}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{margin:20px;padding:10px 20px;-webkit-animation:scaleUp .5s;animation:scaleUp .5s;border:2px solid #f93e3e;border-radius:4px;background:rgba(249,62,62,.1)}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{font-size:14px;margin:0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper .errors .message{white-space:pre-line}.swagger-ui .errors-wrapper .errors .message.thrown{max-width:100%}.swagger-ui .errors-wrapper .errors .error-line{text-decoration:underline;cursor:pointer}.swagger-ui .errors-wrapper hgroup{display:flex;align-items:center}.swagger-ui .errors-wrapper hgroup h4{font-size:20px;margin:0;flex:1;font-family:sans-serif;color:#3b4151}@-webkit-keyframes scaleUp{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@keyframes scaleUp{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}.swagger-ui .Resizer.vertical.disabled{display:none}.swagger-ui .markdown p,.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown p,.swagger-ui .renderedMarkdown pre{margin:1em auto;word-break:break-all;word-break:break-word}.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown pre{color:#000;font-weight:400;white-space:pre-wrap;background:none;padding:0}.swagger-ui .markdown code,.swagger-ui .renderedMarkdown code{font-size:14px;padding:5px 7px;border-radius:4px;background:rgba(0,0,0,.05);font-family:monospace;font-weight:600;color:#9012fe}.swagger-ui .markdown pre>code,.swagger-ui .renderedMarkdown pre>code{display:block} - -/*# sourceMappingURL=swagger-ui.css.map*/ diff --git a/src/static/img/favicon-16x16.png b/src/static/img/favicon-16x16.png deleted file mode 100644 index 8b194e617af1c135e6b37939591d24ac3a5efa18..0000000000000000000000000000000000000000 Binary files a/src/static/img/favicon-16x16.png and /dev/null differ diff --git a/src/static/img/favicon-32x32.png b/src/static/img/favicon-32x32.png deleted file mode 100644 index 249737fe44558e679f0b67134e274461d988fa98..0000000000000000000000000000000000000000 Binary files a/src/static/img/favicon-32x32.png and /dev/null differ diff --git a/src/static/js/swagger-ui-bundle.js b/src/static/js/swagger-ui-bundle.js deleted file mode 100644 index f5f9b0f43b706599e33755936a7c38c349e8d33d..0000000000000000000000000000000000000000 --- a/src/static/js/swagger-ui-bundle.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["esprima"],t):"object"==typeof exports?exports.SwaggerUIBundle=t(function(){try{return require("esprima")}catch(e){}}()):e.SwaggerUIBundle=t(e.esprima)}(this,(function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=549)}([function(e,t,n){"use strict";e.exports=n(129)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:$(e)}function r(e){return s(e)?e:K(e)}function o(e){return u(e)?e:Y(e)}function a(e){return i(e)&&!c(e)?e:G(e)}function i(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=a;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",v=5,g=1<>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?A(e)+t:t}function O(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return P(e,t,0)}function I(e,t){return P(e,t,t)}function P(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var N=0,M=1,R=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function U(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function q(){return{value:void 0,done:!0}}function z(e){return!!H(e)}function V(e){return e&&"function"==typeof e.next}function W(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function J(e){return e&&"number"==typeof e.length}function $(e){return null==e?ie():i(e)?e.toSeq():ce(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?s(e)?e.toSeq():e.fromEntrySeq():se(e)}function Y(e){return null==e?ie():i(e)?s(e)?e.entrySeq():e.toIndexedSeq():ue(e)}function G(e){return(null==e?ie():i(e)?s(e)?e.entrySeq():e:ue(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=N,F.VALUES=M,F.ENTRIES=R,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t($,n),$.of=function(){return $(arguments)},$.prototype.toSeq=function(){return this},$.prototype.toString=function(){return this.__toString("Seq {","}")},$.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},$.prototype.__iterate=function(e,t){return pe(this,e,t,!0)},$.prototype.__iterator=function(e,t){return fe(this,e,t,!0)},t(K,$),K.prototype.toKeyedSeq=function(){return this},t(Y,$),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return pe(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return fe(this,e,t,!1)},t(G,$),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},$.isSeq=ae,$.Keyed=K,$.Set=G,$.Indexed=Y;var Z,X,Q,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Z||(Z=new te([]))}function se(e){var t=Array.isArray(e)?new te(e).fromEntrySeq():V(e)?new oe(e).fromEntrySeq():z(e)?new re(e).fromEntrySeq():"object"==typeof e?new ne(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function ue(e){var t=le(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function ce(e){var t=le(e)||"object"==typeof e&&new ne(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}function le(e){return J(e)?new te(e):V(e)?new oe(e):z(e)?new re(e):void 0}function pe(e,t,n,r){var o=e._cache;if(o){for(var a=o.length-1,i=0;i<=a;i++){var s=o[n?a-i:i];if(!1===t(s[1],r?s[0]:i,e))return i+1}return i}return e.__iterateUncached(t,n)}function fe(e,t,n,r){var o=e._cache;if(o){var a=o.length-1,i=0;return new F((function(){var e=o[n?a-i:i];return i++>a?q():U(t,r?e[0]:i-1,e[1])}))}return e.__iteratorUncached(t,n)}function he(e,t){return t?de(t,e,"",{"":e}):me(e)}function de(e,t,n,r){return Array.isArray(t)?e.call(r,n,Y(t).map((function(n,r){return de(e,n,r,t)}))):ve(t)?e.call(r,n,K(t).map((function(n,r){return de(e,n,r,t)}))):t}function me(e){return Array.isArray(e)?Y(e).map(me).toList():ve(e)?K(e).map(me).toMap():e}function ve(e){return e&&(e.constructor===Object||void 0===e.constructor)}function ge(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if((e=e.valueOf())===(t=t.valueOf())||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function ye(e,t){if(e===t)return!0;if(!i(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||s(e)!==s(t)||u(e)!==u(t)||l(e)!==l(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!c(e);if(l(e)){var r=e.entries();return t.every((function(e,t){var o=r.next().value;return o&&ge(o[1],e)&&(n||ge(o[0],t))}))&&r.next().done}var o=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{o=!0;var a=e;e=t,t=a}var p=!0,f=t.__iterate((function(t,r){if(n?!e.has(t):o?!ge(t,e.get(r,b)):!ge(e.get(r,b),t))return p=!1,!1}));return p&&e.size===f}function be(e,t){if(!(this instanceof be))return new be(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(X)return X;X=this}}function _e(e,t){if(!e)throw new Error(t)}function we(e,t,n){if(!(this instanceof we))return new we(e,t,n);if(_e(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),tr?q():U(e,o,n[t?r-o++:o++])}))},t(ne,K),ne.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},ne.prototype.has=function(e){return this._object.hasOwnProperty(e)},ne.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,o=r.length-1,a=0;a<=o;a++){var i=r[t?o-a:a];if(!1===e(n[i],i,this))return a+1}return a},ne.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,o=r.length-1,a=0;return new F((function(){var i=r[t?o-a:a];return a++>o?q():U(e,i,n[i])}))},ne.prototype[d]=!0,t(re,Y),re.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=W(this._iterable),r=0;if(V(n))for(var o;!(o=n.next()).done&&!1!==e(o.value,r++,this););return r},re.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=W(this._iterable);if(!V(n))return new F(q);var r=0;return new F((function(){var t=n.next();return t.done?t:U(e,r++,t.value)}))},t(oe,Y),oe.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n,r=this._iterator,o=this._iteratorCache,a=0;a=r.length){var t=n.next();if(t.done)return t;r[o]=t.value}return U(e,o,r[o++])}))},t(be,Y),be.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},be.prototype.get=function(e,t){return this.has(e)?this._value:t},be.prototype.includes=function(e){return ge(this._value,e)},be.prototype.slice=function(e,t){var n=this.size;return j(e,t,n)?this:new be(this._value,I(t,n)-T(e,n))},be.prototype.reverse=function(){return this},be.prototype.indexOf=function(e){return ge(this._value,e)?0:-1},be.prototype.lastIndexOf=function(e){return ge(this._value,e)?this.size:-1},be.prototype.__iterate=function(e,t){for(var n=0;n=0&&t=0&&nn?q():U(e,a++,i)}))},we.prototype.equals=function(e){return e instanceof we?this._start===e._start&&this._end===e._end&&this._step===e._step:ye(this,e)},t(xe,n),t(Ee,xe),t(Se,xe),t(Ce,xe),xe.Keyed=Ee,xe.Indexed=Se,xe.Set=Ce;var Ae="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){var n=65535&(e|=0),r=65535&(t|=0);return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0};function ke(e){return e>>>1&1073741824|3221225471&e}function Oe(e){if(!1===e||null==e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t=typeof e;if("number"===t){if(e!=e||e===1/0)return 0;var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)n^=e/=4294967295;return ke(n)}if("string"===t)return e.length>Fe?je(e):Te(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"===t)return Ie(e);if("function"==typeof e.toString)return Te(e.toString());throw new Error("Value type "+t+" cannot be hashed.")}function je(e){var t=ze[e];return void 0===t&&(t=Te(e),qe===Ue&&(qe=0,ze={}),qe++,ze[e]=t),t}function Te(e){for(var t=0,n=0;n0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}var Re,De="function"==typeof WeakMap;De&&(Re=new WeakMap);var Le=0,Be="__immutablehash__";"function"==typeof Symbol&&(Be=Symbol(Be));var Fe=16,Ue=255,qe=0,ze={};function Ve(e){_e(e!==1/0,"Cannot perform this action with an infinite size.")}function We(e){return null==e?ot():He(e)&&!l(e)?e:ot().withMutations((function(t){var n=r(e);Ve(n.size),n.forEach((function(e,n){return t.set(n,e)}))}))}function He(e){return!(!e||!e[$e])}t(We,Ee),We.of=function(){var t=e.call(arguments,0);return ot().withMutations((function(e){for(var n=0;n=t.length)throw new Error("Missing value for key: "+t[n]);e.set(t[n],t[n+1])}}))},We.prototype.toString=function(){return this.__toString("Map {","}")},We.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},We.prototype.set=function(e,t){return at(this,e,t)},We.prototype.setIn=function(e,t){return this.updateIn(e,b,(function(){return t}))},We.prototype.remove=function(e){return at(this,e,b)},We.prototype.deleteIn=function(e){return this.updateIn(e,(function(){return b}))},We.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},We.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=vt(this,xn(e),t,n);return r===b?void 0:r},We.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):ot()},We.prototype.merge=function(){return ft(this,void 0,arguments)},We.prototype.mergeWith=function(t){return ft(this,t,e.call(arguments,1))},We.prototype.mergeIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,ot(),(function(e){return"function"==typeof e.merge?e.merge.apply(e,n):n[n.length-1]}))},We.prototype.mergeDeep=function(){return ft(this,ht,arguments)},We.prototype.mergeDeepWith=function(t){var n=e.call(arguments,1);return ft(this,dt(t),n)},We.prototype.mergeDeepIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,ot(),(function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,n):n[n.length-1]}))},We.prototype.sort=function(e){return zt(pn(this,e))},We.prototype.sortBy=function(e,t){return zt(pn(this,t,e))},We.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},We.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new S)},We.prototype.asImmutable=function(){return this.__ensureOwner()},We.prototype.wasAltered=function(){return this.__altered},We.prototype.__iterator=function(e,t){return new et(this,e,t)},We.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate((function(t){return r++,e(t[1],t[0],n)}),t),r},We.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?rt(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},We.isMap=He;var Je,$e="@@__IMMUTABLE_MAP__@@",Ke=We.prototype;function Ye(e,t){this.ownerID=e,this.entries=t}function Ge(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function Ze(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function Xe(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function Qe(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function et(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&nt(e._root)}function tt(e,t){return U(e,t[0],t[1])}function nt(e,t){return{node:e,index:0,__prev:t}}function rt(e,t,n,r){var o=Object.create(Ke);return o.size=e,o._root=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function ot(){return Je||(Je=rt(0))}function at(e,t,n){var r,o;if(e._root){var a=x(_),i=x(w);if(r=it(e._root,e.__ownerID,0,void 0,t,n,a,i),!i.value)return e;o=e.size+(a.value?n===b?-1:1:0)}else{if(n===b)return e;o=1,r=new Ye(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=o,e._root=r,e.__hash=void 0,e.__altered=!0,e):r?rt(o,r):ot()}function it(e,t,n,r,o,a,i,s){return e?e.update(t,n,r,o,a,i,s):a===b?e:(E(s),E(i),new Qe(t,r,[o,a]))}function st(e){return e.constructor===Qe||e.constructor===Xe}function ut(e,t,n,r,o){if(e.keyHash===r)return new Xe(t,r,[e.entry,o]);var a,i=(0===n?e.keyHash:e.keyHash>>>n)&y,s=(0===n?r:r>>>n)&y;return new Ge(t,1<>>=1)i[s]=1&n?t[a++]:void 0;return i[r]=o,new Ze(e,a+1,i)}function ft(e,t,n){for(var o=[],a=0;a>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function yt(e,t,n,r){var o=r?e:C(e);return o[t]=n,o}function bt(e,t,n,r){var o=e.length+1;if(r&&t+1===o)return e[t]=n,e;for(var a=new Array(o),i=0,s=0;s=wt)return ct(e,u,r,o);var f=e&&e===this.ownerID,h=f?u:C(u);return p?s?c===l-1?h.pop():h[c]=h.pop():h[c]=[r,o]:h.push([r,o]),f?(this.entries=h,this):new Ye(e,h)}},Ge.prototype.get=function(e,t,n,r){void 0===t&&(t=Oe(n));var o=1<<((0===e?t:t>>>e)&y),a=this.bitmap;return 0==(a&o)?r:this.nodes[gt(a&o-1)].get(e+v,t,n,r)},Ge.prototype.update=function(e,t,n,r,o,a,i){void 0===n&&(n=Oe(r));var s=(0===t?n:n>>>t)&y,u=1<=xt)return pt(e,f,c,s,d);if(l&&!d&&2===f.length&&st(f[1^p]))return f[1^p];if(l&&d&&1===f.length&&st(d))return d;var m=e&&e===this.ownerID,g=l?d?c:c^u:c|u,_=l?d?yt(f,p,d,m):_t(f,p,m):bt(f,p,d,m);return m?(this.bitmap=g,this.nodes=_,this):new Ge(e,g,_)},Ze.prototype.get=function(e,t,n,r){void 0===t&&(t=Oe(n));var o=(0===e?t:t>>>e)&y,a=this.nodes[o];return a?a.get(e+v,t,n,r):r},Ze.prototype.update=function(e,t,n,r,o,a,i){void 0===n&&(n=Oe(r));var s=(0===t?n:n>>>t)&y,u=o===b,c=this.nodes,l=c[s];if(u&&!l)return this;var p=it(l,e,t+v,n,r,o,a,i);if(p===l)return this;var f=this.count;if(l){if(!p&&--f0&&r=0&&e>>t&y;if(r>=this.array.length)return new Ot([],e);var o,a=0===r;if(t>0){var i=this.array[r];if((o=i&&i.removeBefore(e,t-v,n))===i&&a)return this}if(a&&!o)return this;var s=Lt(this,e);if(!a)for(var u=0;u>>t&y;if(o>=this.array.length)return this;if(t>0){var a=this.array[o];if((r=a&&a.removeAfter(e,t-v,n))===a&&o===this.array.length-1)return this}var i=Lt(this,e);return i.array.splice(o+1),r&&(i.array[o]=r),i};var jt,Tt,It={};function Pt(e,t){var n=e._origin,r=e._capacity,o=qt(r),a=e._tail;return i(e._root,e._level,0);function i(e,t,n){return 0===t?s(e,n):u(e,t,n)}function s(e,i){var s=i===o?a&&a.array:e&&e.array,u=i>n?0:n-i,c=r-i;return c>g&&(c=g),function(){if(u===c)return It;var e=t?--c:u++;return s&&s[e]}}function u(e,o,a){var s,u=e&&e.array,c=a>n?0:n-a>>o,l=1+(r-a>>o);return l>g&&(l=g),function(){for(;;){if(s){var e=s();if(e!==It)return e;s=null}if(c===l)return It;var n=t?--l:c++;s=i(u&&u[n],o-v,a+(n<=e.size||t<0)return e.withMutations((function(e){t<0?Ft(e,t).set(0,n):Ft(e,0,t+1).set(t,n)}));t+=e._origin;var r=e._tail,o=e._root,a=x(w);return t>=qt(e._capacity)?r=Dt(r,e.__ownerID,0,t,n,a):o=Dt(o,e.__ownerID,e._level,t,n,a),a.value?e.__ownerID?(e._root=o,e._tail=r,e.__hash=void 0,e.__altered=!0,e):Nt(e._origin,e._capacity,e._level,o,r):e}function Dt(e,t,n,r,o,a){var i,s=r>>>n&y,u=e&&s0){var c=e&&e.array[s],l=Dt(c,t,n-v,r,o,a);return l===c?e:((i=Lt(e,t)).array[s]=l,i)}return u&&e.array[s]===o?e:(E(a),i=Lt(e,t),void 0===o&&s===i.array.length-1?i.array.pop():i.array[s]=o,i)}function Lt(e,t){return t&&e&&t===e.ownerID?e:new Ot(e?e.array.slice():[],t)}function Bt(e,t){if(t>=qt(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&y],r-=v;return n}}function Ft(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new S,o=e._origin,a=e._capacity,i=o+t,s=void 0===n?a:n<0?a+n:o+n;if(i===o&&s===a)return e;if(i>=s)return e.clear();for(var u=e._level,c=e._root,l=0;i+l<0;)c=new Ot(c&&c.array.length?[void 0,c]:[],r),l+=1<<(u+=v);l&&(i+=l,o+=l,s+=l,a+=l);for(var p=qt(a),f=qt(s);f>=1<p?new Ot([],r):h;if(h&&f>p&&iv;g-=v){var b=p>>>g&y;m=m.array[b]=Lt(m.array[b],r)}m.array[p>>>v&y]=h}if(s=f)i-=f,s-=f,u=v,c=null,d=d&&d.removeBefore(r,0,i);else if(i>o||f>>u&y;if(_!==f>>>u&y)break;_&&(l+=(1<o&&(c=c.removeBefore(r,u,i-l)),c&&fa&&(a=c.size),i(u)||(c=c.map((function(e){return he(e)}))),r.push(c)}return a>e.size&&(e=e.setSize(a)),mt(e,t,r)}function qt(e){return e>>v<=g&&i.size>=2*a.size?(r=(o=i.filter((function(e,t){return void 0!==e&&s!==t}))).toKeyedSeq().map((function(e){return e[0]})).flip().toMap(),e.__ownerID&&(r.__ownerID=o.__ownerID=e.__ownerID)):(r=a.remove(t),o=s===i.size-1?i.pop():i.set(s,void 0))}else if(u){if(n===i.get(s)[1])return e;r=a,o=i.set(s,[t,n])}else r=a.set(t,i.size),o=i.set(i.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=o,e.__hash=void 0,e):Wt(r,o)}function $t(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function Kt(e){this._iter=e,this.size=e.size}function Yt(e){this._iter=e,this.size=e.size}function Gt(e){this._iter=e,this.size=e.size}function Zt(e){var t=bn(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=_n,t.__iterateUncached=function(t,n){var r=this;return e.__iterate((function(e,n){return!1!==t(n,e,r)}),n)},t.__iteratorUncached=function(t,n){if(t===R){var r=e.__iterator(t,n);return new F((function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e}))}return e.__iterator(t===M?N:M,n)},t}function Xt(e,t,n){var r=bn(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,o){var a=e.get(r,b);return a===b?o:t.call(n,a,r,e)},r.__iterateUncached=function(r,o){var a=this;return e.__iterate((function(e,o,i){return!1!==r(t.call(n,e,o,i),o,a)}),o)},r.__iteratorUncached=function(r,o){var a=e.__iterator(R,o);return new F((function(){var o=a.next();if(o.done)return o;var i=o.value,s=i[0];return U(r,s,t.call(n,i[1],s,e),o)}))},r}function Qt(e,t){var n=bn(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=Zt(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=_n,n.__iterate=function(t,n){var r=this;return e.__iterate((function(e,n){return t(e,n,r)}),!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function en(e,t,n,r){var o=bn(e);return r&&(o.has=function(r){var o=e.get(r,b);return o!==b&&!!t.call(n,o,r,e)},o.get=function(r,o){var a=e.get(r,b);return a!==b&&t.call(n,a,r,e)?a:o}),o.__iterateUncached=function(o,a){var i=this,s=0;return e.__iterate((function(e,a,u){if(t.call(n,e,a,u))return s++,o(e,r?a:s-1,i)}),a),s},o.__iteratorUncached=function(o,a){var i=e.__iterator(R,a),s=0;return new F((function(){for(;;){var a=i.next();if(a.done)return a;var u=a.value,c=u[0],l=u[1];if(t.call(n,l,c,e))return U(o,r?c:s++,l,a)}}))},o}function tn(e,t,n){var r=We().asMutable();return e.__iterate((function(o,a){r.update(t.call(n,o,a,e),0,(function(e){return e+1}))})),r.asImmutable()}function nn(e,t,n){var r=s(e),o=(l(e)?zt():We()).asMutable();e.__iterate((function(a,i){o.update(t.call(n,a,i,e),(function(e){return(e=e||[]).push(r?[i,a]:a),e}))}));var a=yn(e);return o.map((function(t){return mn(e,a(t))}))}function rn(e,t,n,r){var o=e.size;if(void 0!==t&&(t|=0),void 0!==n&&(n===1/0?n=o:n|=0),j(t,n,o))return e;var a=T(t,o),i=I(n,o);if(a!=a||i!=i)return rn(e.toSeq().cacheResult(),t,n,r);var s,u=i-a;u==u&&(s=u<0?0:u);var c=bn(e);return c.size=0===s?s:e.size&&s||void 0,!r&&ae(e)&&s>=0&&(c.get=function(t,n){return(t=k(this,t))>=0&&ts)return q();var e=o.next();return r||t===M?e:U(t,u-1,t===N?void 0:e.value[1],e)}))},c}function on(e,t,n){var r=bn(e);return r.__iterateUncached=function(r,o){var a=this;if(o)return this.cacheResult().__iterate(r,o);var i=0;return e.__iterate((function(e,o,s){return t.call(n,e,o,s)&&++i&&r(e,o,a)})),i},r.__iteratorUncached=function(r,o){var a=this;if(o)return this.cacheResult().__iterator(r,o);var i=e.__iterator(R,o),s=!0;return new F((function(){if(!s)return q();var e=i.next();if(e.done)return e;var o=e.value,u=o[0],c=o[1];return t.call(n,c,u,a)?r===R?e:U(r,u,c,e):(s=!1,q())}))},r}function an(e,t,n,r){var o=bn(e);return o.__iterateUncached=function(o,a){var i=this;if(a)return this.cacheResult().__iterate(o,a);var s=!0,u=0;return e.__iterate((function(e,a,c){if(!s||!(s=t.call(n,e,a,c)))return u++,o(e,r?a:u-1,i)})),u},o.__iteratorUncached=function(o,a){var i=this;if(a)return this.cacheResult().__iterator(o,a);var s=e.__iterator(R,a),u=!0,c=0;return new F((function(){var e,a,l;do{if((e=s.next()).done)return r||o===M?e:U(o,c++,o===N?void 0:e.value[1],e);var p=e.value;a=p[0],l=p[1],u&&(u=t.call(n,l,a,i))}while(u);return o===R?e:U(o,a,l,e)}))},o}function sn(e,t){var n=s(e),o=[e].concat(t).map((function(e){return i(e)?n&&(e=r(e)):e=n?se(e):ue(Array.isArray(e)?e:[e]),e})).filter((function(e){return 0!==e.size}));if(0===o.length)return e;if(1===o.length){var a=o[0];if(a===e||n&&s(a)||u(e)&&u(a))return a}var c=new te(o);return n?c=c.toKeyedSeq():u(e)||(c=c.toSetSeq()),(c=c.flatten(!0)).size=o.reduce((function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}}),0),c}function un(e,t,n){var r=bn(e);return r.__iterateUncached=function(r,o){var a=0,s=!1;function u(e,c){var l=this;e.__iterate((function(e,o){return(!t||c0}function dn(e,t,r){var o=bn(e);return o.size=new te(r).map((function(e){return e.size})).min(),o.__iterate=function(e,t){for(var n,r=this.__iterator(M,t),o=0;!(n=r.next()).done&&!1!==e(n.value,o++,this););return o},o.__iteratorUncached=function(e,o){var a=r.map((function(e){return e=n(e),W(o?e.reverse():e)})),i=0,s=!1;return new F((function(){var n;return s||(n=a.map((function(e){return e.next()})),s=n.some((function(e){return e.done}))),s?q():U(e,i++,t.apply(null,n.map((function(e){return e.value}))))}))},o}function mn(e,t){return ae(e)?t:e.constructor(t)}function vn(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function gn(e){return Ve(e.size),A(e)}function yn(e){return s(e)?r:u(e)?o:a}function bn(e){return Object.create((s(e)?K:u(e)?Y:G).prototype)}function _n(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):$.prototype.cacheResult.call(this)}function wn(e,t){return e>t?1:e=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):Kn(e,t)},Vn.prototype.pushAll=function(e){if(0===(e=o(e)).size)return this;Ve(e.size);var t=this.size,n=this._head;return e.reverse().forEach((function(e){t++,n={value:e,next:n}})),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):Kn(t,n)},Vn.prototype.pop=function(){return this.slice(1)},Vn.prototype.unshift=function(){return this.push.apply(this,arguments)},Vn.prototype.unshiftAll=function(e){return this.pushAll(e)},Vn.prototype.shift=function(){return this.pop.apply(this,arguments)},Vn.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Yn()},Vn.prototype.slice=function(e,t){if(j(e,t,this.size))return this;var n=T(e,this.size);if(I(t,this.size)!==this.size)return Se.prototype.slice.call(this,e,t);for(var r=this.size-n,o=this._head;n--;)o=o.next;return this.__ownerID?(this.size=r,this._head=o,this.__hash=void 0,this.__altered=!0,this):Kn(r,o)},Vn.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Kn(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Vn.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&!1!==e(r.value,n++,this);)r=r.next;return n},Vn.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new F((function(){if(r){var t=r.value;return r=r.next,U(e,n++,t)}return q()}))},Vn.isStack=Wn;var Hn,Jn="@@__IMMUTABLE_STACK__@@",$n=Vn.prototype;function Kn(e,t,n,r){var o=Object.create($n);return o.size=e,o._head=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Yn(){return Hn||(Hn=Kn(0))}function Gn(e,t){var n=function(n){e.prototype[n]=t[n]};return Object.keys(t).forEach(n),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(n),e}$n[Jn]=!0,$n.withMutations=Ke.withMutations,$n.asMutable=Ke.asMutable,$n.asImmutable=Ke.asImmutable,$n.wasAltered=Ke.wasAltered,n.Iterator=F,Gn(n,{toArray:function(){Ve(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate((function(t,n){e[n]=t})),e},toIndexedSeq:function(){return new Kt(this)},toJS:function(){return this.toSeq().map((function(e){return e&&"function"==typeof e.toJS?e.toJS():e})).__toJS()},toJSON:function(){return this.toSeq().map((function(e){return e&&"function"==typeof e.toJSON?e.toJSON():e})).__toJS()},toKeyedSeq:function(){return new $t(this,!0)},toMap:function(){return We(this.toKeyedSeq())},toObject:function(){Ve(this.size);var e={};return this.__iterate((function(t,n){e[n]=t})),e},toOrderedMap:function(){return zt(this.toKeyedSeq())},toOrderedSet:function(){return Ln(s(this)?this.valueSeq():this)},toSet:function(){return jn(s(this)?this.valueSeq():this)},toSetSeq:function(){return new Yt(this)},toSeq:function(){return u(this)?this.toIndexedSeq():s(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Vn(s(this)?this.valueSeq():this)},toList:function(){return St(s(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(e,t){return 0===this.size?e+t:e+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+t},concat:function(){return mn(this,sn(this,e.call(arguments,0)))},includes:function(e){return this.some((function(t){return ge(t,e)}))},entries:function(){return this.__iterator(R)},every:function(e,t){Ve(this.size);var n=!0;return this.__iterate((function(r,o,a){if(!e.call(t,r,o,a))return n=!1,!1})),n},filter:function(e,t){return mn(this,en(this,e,t,!0))},find:function(e,t,n){var r=this.findEntry(e,t);return r?r[1]:n},forEach:function(e,t){return Ve(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){Ve(this.size),e=void 0!==e?""+e:",";var t="",n=!0;return this.__iterate((function(r){n?n=!1:t+=e,t+=null!=r?r.toString():""})),t},keys:function(){return this.__iterator(N)},map:function(e,t){return mn(this,Xt(this,e,t))},reduce:function(e,t,n){var r,o;return Ve(this.size),arguments.length<2?o=!0:r=t,this.__iterate((function(t,a,i){o?(o=!1,r=t):r=e.call(n,r,t,a,i)})),r},reduceRight:function(e,t,n){var r=this.toKeyedSeq().reverse();return r.reduce.apply(r,arguments)},reverse:function(){return mn(this,Qt(this,!0))},slice:function(e,t){return mn(this,rn(this,e,t,!0))},some:function(e,t){return!this.every(tr(e),t)},sort:function(e){return mn(this,pn(this,e))},values:function(){return this.__iterator(M)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some((function(){return!0}))},count:function(e,t){return A(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return tn(this,e,t)},equals:function(e){return ye(this,e)},entrySeq:function(){var e=this;if(e._cache)return new te(e._cache);var t=e.toSeq().map(er).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(tr(e),t)},findEntry:function(e,t,n){var r=n;return this.__iterate((function(n,o,a){if(e.call(t,n,o,a))return r=[o,n],!1})),r},findKey:function(e,t){var n=this.findEntry(e,t);return n&&n[0]},findLast:function(e,t,n){return this.toKeyedSeq().reverse().find(e,t,n)},findLastEntry:function(e,t,n){return this.toKeyedSeq().reverse().findEntry(e,t,n)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(O)},flatMap:function(e,t){return mn(this,cn(this,e,t))},flatten:function(e){return mn(this,un(this,e,!0))},fromEntrySeq:function(){return new Gt(this)},get:function(e,t){return this.find((function(t,n){return ge(n,e)}),void 0,t)},getIn:function(e,t){for(var n,r=this,o=xn(e);!(n=o.next()).done;){var a=n.value;if((r=r&&r.get?r.get(a,b):b)===b)return t}return r},groupBy:function(e,t){return nn(this,e,t)},has:function(e){return this.get(e,b)!==b},hasIn:function(e){return this.getIn(e,b)!==b},isSubset:function(e){return e="function"==typeof e.includes?e:n(e),this.every((function(t){return e.includes(t)}))},isSuperset:function(e){return(e="function"==typeof e.isSubset?e:n(e)).isSubset(this)},keyOf:function(e){return this.findKey((function(t){return ge(t,e)}))},keySeq:function(){return this.toSeq().map(Qn).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return fn(this,e)},maxBy:function(e,t){return fn(this,t,e)},min:function(e){return fn(this,e?nr(e):ar)},minBy:function(e,t){return fn(this,t?nr(t):ar,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return mn(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return mn(this,an(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(tr(e),t)},sortBy:function(e,t){return mn(this,pn(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return mn(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return mn(this,on(this,e,t))},takeUntil:function(e,t){return this.takeWhile(tr(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var Zn=n.prototype;Zn[p]=!0,Zn[B]=Zn.values,Zn.__toJS=Zn.toArray,Zn.__toStringMapper=rr,Zn.inspect=Zn.toSource=function(){return this.toString()},Zn.chain=Zn.flatMap,Zn.contains=Zn.includes,Gn(r,{flip:function(){return mn(this,Zt(this))},mapEntries:function(e,t){var n=this,r=0;return mn(this,this.toSeq().map((function(o,a){return e.call(t,[a,o],r++,n)})).fromEntrySeq())},mapKeys:function(e,t){var n=this;return mn(this,this.toSeq().flip().map((function(r,o){return e.call(t,r,o,n)})).flip())}});var Xn=r.prototype;function Qn(e,t){return t}function er(e,t){return[t,e]}function tr(e){return function(){return!e.apply(this,arguments)}}function nr(e){return function(){return-e.apply(this,arguments)}}function rr(e){return"string"==typeof e?JSON.stringify(e):String(e)}function or(){return C(arguments)}function ar(e,t){return et?-1:0}function ir(e){if(e.size===1/0)return 0;var t=l(e),n=s(e),r=t?1:0;return sr(e.__iterate(n?t?function(e,t){r=31*r+ur(Oe(e),Oe(t))|0}:function(e,t){r=r+ur(Oe(e),Oe(t))|0}:t?function(e){r=31*r+Oe(e)|0}:function(e){r=r+Oe(e)|0}),r)}function sr(e,t){return t=Ae(t,3432918353),t=Ae(t<<15|t>>>-15,461845907),t=Ae(t<<13|t>>>-13,5),t=Ae((t=(t+3864292196|0)^e)^t>>>16,2246822507),t=ke((t=Ae(t^t>>>13,3266489909))^t>>>16)}function ur(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}return Xn[f]=!0,Xn[B]=Zn.entries,Xn.__toJS=Zn.toObject,Xn.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+rr(e)},Gn(o,{toKeyedSeq:function(){return new $t(this,!1)},filter:function(e,t){return mn(this,en(this,e,t,!1))},findIndex:function(e,t){var n=this.findEntry(e,t);return n?n[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return mn(this,Qt(this,!1))},slice:function(e,t){return mn(this,rn(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=T(e,e<0?this.count():this.size);var r=this.slice(0,e);return mn(this,1===n?r:r.concat(C(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var n=this.findLastEntry(e,t);return n?n[0]:-1},first:function(){return this.get(0)},flatten:function(e){return mn(this,un(this,e,!1))},get:function(e,t){return(e=k(this,e))<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find((function(t,n){return n===e}),void 0,t)},has:function(e){return(e=k(this,e))>=0&&(void 0!==this.size?this.size===1/0||e1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function Me(e){return t=e.replace(/\.[^./]*$/,""),Y()($()(t));var t}function Re(e,t,n,r,o){if(!t)return[];var a=[],i=t.get("required"),s=t.get("maximum"),u=t.get("minimum"),c=t.get("type"),l=t.get("format"),p=t.get("maxLength"),f=t.get("minLength"),h=t.get("uniqueItems"),m=t.get("maxItems"),g=t.get("minItems"),y=t.get("pattern");if(c&&(n||i||void 0!==e||"array"===c)){var b="string"===c&&e,_="array"===c&&U()(e)&&e.length,w="array"===c&&W.a.List.isList(e)&&e.count(),x=[b,_,w,"array"===c&&"string"==typeof e&&e,"file"===c&&e instanceof se.a.File,"boolean"===c&&(e||!1===e),"number"===c&&(e||0===e),"integer"===c&&(e||0===e),"object"===c&&"object"===z()(e)&&null!==e,"object"===c&&"string"==typeof e&&e],E=v()(x).call(x,(function(e){return!!e}));if((n||i)&&!E&&!r)return a.push("Required field is not provided"),a;if("object"===c&&(null===o||"application/json"===o)){var S,C=e;if("string"==typeof e)try{C=JSON.parse(e)}catch(e){return a.push("Parameter string value must be valid JSON"),a}if(t&&t.has("required")&&Ce(i.isList)&&i.isList()&&T()(i).call(i,(function(e){void 0===C[e]&&a.push({propKey:e,error:"Required property not found"})})),t&&t.has("properties"))T()(S=t.get("properties")).call(S,(function(e,t){var n=Re(C[t],e,!1,r,o);a.push.apply(a,d()(B()(n).call(n,(function(e){return{propKey:t,error:e}}))))}))}if(y){var A=function(e,t){if(!new RegExp(t).test(e))return"Value must follow pattern "+t}(e,y);A&&a.push(A)}if(g&&"array"===c){var k=function(e,t){var n;if(!e&&t>=1||e&&e.lengtht)return P()(n="Array must not contain more then ".concat(t," item")).call(n,1===t?"":"s")}(e,m);j&&a.push({needRemove:!0,error:j})}if(h&&"array"===c){var I=function(e,t){if(e&&("true"===t||!0===t)){var n=Object(V.fromJS)(e),r=n.toSet();if(e.length>r.size){var o=Object(V.Set)();if(T()(n).call(n,(function(e,t){O()(n).call(n,(function(t){return Ce(t.equals)?t.equals(e):t===e})).size>1&&(o=o.add(t))})),0!==o.size)return B()(o).call(o,(function(e){return{index:e,error:"No duplicates allowed."}})).toArray()}}}(e,h);I&&a.push.apply(a,d()(I))}if(p||0===p){var N=function(e,t){var n;if(e.length>t)return P()(n="Value must be no longer than ".concat(t," character")).call(n,1!==t?"s":"")}(e,p);N&&a.push(N)}if(f){var M=function(e,t){var n;if(e.lengtht)return"Value must be less than ".concat(t)}(e,s);R&&a.push(R)}if(u||0===u){var D=function(e,t){if(e2&&void 0!==arguments[2]?arguments[2]:{},r=n.isOAS3,o=void 0!==r&&r,a=n.bypassRequiredCheck,i=void 0!==a&&a,s=e.get("required"),u=Object(le.a)(e,{isOAS3:o}),c=u.schema,l=u.parameterContentMediaType;return Re(t,c,s,i,l)},Le=function(e,t,n){if(e&&(!e.xml||!e.xml.name)){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;var r=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=r[1]}return Object(ie.memoizedCreateXMLExample)(e,t,n)},Be=[{when:/json/,shouldStringifyTypes:["string"]}],Fe=["object"],Ue=function(e,t,n,r){var o=Object(ie.memoizedSampleFromSchema)(e,t,r),a=z()(o),i=S()(Be).call(Be,(function(e,t){var r;return t.when.test(n)?P()(r=[]).call(r,d()(e),d()(t.shouldStringifyTypes)):e}),Fe);return te()(i,(function(e){return e===a}))?f()(o,null,2):o},qe=function(e,t,n,r){var o,a=Ue(e,t,n,r);try{"\n"===(o=ve.a.safeDump(ve.a.safeLoad(a),{lineWidth:-1}))[o.length-1]&&(o=y()(o).call(o,0,o.length-1))}catch(e){return console.error(e),"error: could not generate yaml example"}return o.replace(/\t/g," ")},ze=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return e&&Ce(e.toJS)&&(e=e.toJS()),r&&Ce(r.toJS)&&(r=r.toJS()),/xml/.test(t)?Le(e,n,r):/(yaml|yml)/.test(t)?qe(e,n,t,r):Ue(e,n,t,r)},Ve=function(){var e={},t=se.a.location.search;if(!t)return{};if(""!=t){var n=t.substr(1).split("&");for(var r in n)n.hasOwnProperty(r)&&(r=n[r].split("="),e[decodeURIComponent(r[0])]=r[1]&&decodeURIComponent(r[1])||"")}return e},We=function(t){return(t instanceof e?t:e.from(t.toString(),"utf-8")).toString("base64")},He={operationsSorter:{alpha:function(e,t){return e.get("path").localeCompare(t.get("path"))},method:function(e,t){return e.get("method").localeCompare(t.get("method"))}},tagsSorter:{alpha:function(e,t){return e.localeCompare(t)}}},Je=function(e){var t=[];for(var n in e){var r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},$e=function(e,t,n){return!!Q()(n,(function(n){return re()(e[n],t[n])}))};function Ke(e){return"string"!=typeof e||""===e?"":Object(H.sanitizeUrl)(e)}function Ye(e){return!(!e||l()(e).call(e,"localhost")>=0||l()(e).call(e,"127.0.0.1")>=0||"none"===e)}function Ge(e){if(!W.a.OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;var t=u()(e).call(e,(function(e,t){return i()(t).call(t,"2")&&A()(e.get("content")||{}).length>0})),n=e.get("default")||W.a.OrderedMap(),r=(n.get("content")||W.a.OrderedMap()).keySeq().toJS().length?n:null;return t||r}var Ze=function(e){return"string"==typeof e||e instanceof String?o()(e).call(e).replace(/\s/g,"%20"):""},Xe=function(e){return ce()(Ze(e).replace(/%20/g,"_"))},Qe=function(e){return O()(e).call(e,(function(e,t){return/^x-/.test(t)}))},et=function(e){return O()(e).call(e,(function(e,t){return/^pattern|maxLength|minLength|maximum|minimum/.test(t)}))};function tt(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==z()(e)||U()(e)||null===e||!t)return e;var o=x()({},e);return T()(n=A()(o)).call(n,(function(e){e===t&&r(o[e],e)?delete o[e]:o[e]=tt(o[e],t,r)})),o}function nt(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"===z()(e)&&null!==e)try{return f()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function rt(e){return"number"==typeof e?e.toString():e}function ot(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.returnAll,r=void 0!==n&&n,o=t.allowHashes,a=void 0===o||o;if(!W.a.Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");var i,s,u,c=e.get("name"),l=e.get("in"),p=[];e&&e.hashCode&&l&&c&&a&&p.push(P()(i=P()(s="".concat(l,".")).call(s,c,".hash-")).call(i,e.hashCode()));l&&c&&p.push(P()(u="".concat(l,".")).call(u,c));return p.push(c),r?p:p[0]||""}function at(e,t){var n,r=ot(e,{returnAll:!0});return O()(n=B()(r).call(r,(function(e){return t[e]}))).call(n,(function(e){return void 0!==e}))[0]}function it(){return ut(fe()(32).toString("base64"))}function st(e){return ut(de()("sha256").update(e).digest("base64"))}function ut(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var ct=function(e){return!e||!(!ye(e)||!e.isEmpty())}}).call(this,n(77).Buffer)},function(e,t,n){var r=n(244);function o(e,t){for(var n=0;n1?t-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:r,n=null,a=null;return function(){return o(t,n,arguments)||(a=e.apply(null,arguments)),n=arguments,a}}))},function(e,t,n){e.exports=n(598)},function(e,t,n){e.exports=n(610)},function(e,t,n){e.exports=n(607)},function(e,t,n){"use strict";var r=n(42),o=n(107).f,a=n(358),i=n(33),s=n(109),u=n(70),c=n(52),l=function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t};e.exports=function(e,t){var n,p,f,h,d,m,v,g,y=e.target,b=e.global,_=e.stat,w=e.proto,x=b?r:_?r[y]:(r[y]||{}).prototype,E=b?i:i[y]||(i[y]={}),S=E.prototype;for(f in t)n=!a(b?f:y+(_?".":"#")+f,e.forced)&&x&&c(x,f),d=E[f],n&&(m=e.noTargetGet?(g=o(x,f))&&g.value:x[f]),h=n&&m?m:t[f],n&&typeof d==typeof h||(v=e.bind&&n?s(h,r):e.wrap&&n?l(h):w&&"function"==typeof h?s(Function.call,h):h,(e.sham||h&&h.sham||d&&d.sham)&&u(v,"sham",!0),E[f]=v,w&&(c(i,p=y+"Prototype")||u(i,p,{}),i[p][f]=h,e.real&&S&&!S[f]&&u(S,f,h)))}},function(e,t,n){var r=n(244),o=n(874),a=n(878),i=n(883),s=n(450),u=n(888),c=n(451),l=n(452),p=n(3);function f(e,t){var n=l(e);if(c){var r=c(e);t&&(r=u(r).call(r,(function(t){return s(e,t).enumerable}))),n.push.apply(n,r)}return n}e.exports=function(e){for(var t=1;t>",i=function(){invariant(!1,"ImmutablePropTypes type checking code is stripped in production.")};i.isRequired=i;var s=function(){return i};function u(e){var t=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":e instanceof o.Iterable?"Immutable."+e.toSource().split(" ")[0]:t}function c(e){function t(t,n,r,o,i,s){for(var u=arguments.length,c=Array(u>6?u-6:0),l=6;l4)}function l(e){var t=e.get("swagger");return"string"==typeof t&&i()(t).call(t,"2.0")}function p(e){return function(t,n){return function(r){return n&&n.specSelectors&&n.specSelectors.specJson?c(n.specSelectors.specJson())?u.a.createElement(e,o()({},r,n,{Ori:t})):u.a.createElement(t,r):(console.warn("OAS3 wrapper: couldn't get spec"),null)}}}},function(e,t,n){e.exports=n(670)},function(e,t,n){e.exports=n(664)},function(e,t,n){var r=n(42),o=n(233),a=n(52),i=n(179),s=n(235),u=n(362),c=o("wks"),l=r.Symbol,p=u?l:l&&l.withoutSetter||i;e.exports=function(e){return a(c,e)||(s&&a(l,e)?c[e]=l[e]:c[e]=p("Symbol."+e)),c[e]}},function(e,t,n){"use strict";var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,u=i(e),c=1;c0){var o=D()(n).call(n,(function(e){return console.error(e),e.line=e.fullPath?g(y,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",M()(e,"message",{enumerable:!0,value:e.message}),e}));a.newThrownErrBatch(o)}return r.updateResolved(t)}))}},Ce=[],Ae=Z()(P()(_.a.mark((function e(){var t,n,r,o,a,i,s,u,c,l,p,f,h,d,m,v,g,y;return _.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=Ce.system){e.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),e.abrupt("return");case 4:if(n=t.errActions,r=t.errSelectors,o=t.fn,a=o.resolveSubtree,i=o.fetch,s=o.AST,u=void 0===s?{}:s,c=t.specSelectors,l=t.specActions,a){e.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),e.abrupt("return");case 8:return p=u.getLineNumberForPath?u.getLineNumberForPath:function(){},f=c.specStr(),h=t.getConfigs(),d=h.modelPropertyMacro,m=h.parameterMacro,v=h.requestInterceptor,g=h.responseInterceptor,e.prev=11,e.next=14,T()(Ce).call(Ce,function(){var e=P()(_.a.mark((function e(t,o){var s,u,l,h,y,b,w,E,C;return _.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t;case 2:return s=e.sent,u=s.resultMap,l=s.specWithCurrentSubtrees,e.next=7,a(l,o,{baseDoc:c.url(),modelPropertyMacro:d,parameterMacro:m,requestInterceptor:v,responseInterceptor:g});case 7:if(h=e.sent,y=h.errors,b=h.spec,r.allErrors().size&&n.clearBy((function(e){var t;return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!O()(t=e.get("fullPath")).call(t,(function(e,t){return e===o[t]||void 0===o[t]}))})),B()(y)&&y.length>0&&(w=D()(y).call(y,(function(e){return e.line=e.fullPath?p(f,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",M()(e,"message",{enumerable:!0,value:e.message}),e})),n.newThrownErrBatch(w)),!b||!c.isOAS3()||"components"!==o[0]||"securitySchemes"!==o[1]){e.next=15;break}return e.next=15,A.a.all(D()(E=S()(C=x()(b)).call(C,(function(e){return"openIdConnect"===e.type}))).call(E,function(){var e=P()(_.a.mark((function e(t){var n,r;return _.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n={url:t.openIdConnectUrl,requestInterceptor:v,responseInterceptor:g},e.prev=1,e.next=4,i(n);case 4:(r=e.sent)instanceof Error||r.status>=400?console.error(r.statusText+" "+n.url):t.openIdConnectData=JSON.parse(r.text),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(1),console.error(e.t0);case 11:case"end":return e.stop()}}),e,null,[[1,8]])})));return function(t){return e.apply(this,arguments)}}()));case 15:return Q()(u,o,b),Q()(l,o,b),e.abrupt("return",{resultMap:u,specWithCurrentSubtrees:l});case 18:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}(),A.a.resolve({resultMap:(c.specResolvedSubtree([])||Object(V.Map)()).toJS(),specWithCurrentSubtrees:c.specJson().toJS()}));case 14:y=e.sent,delete Ce.system,Ce=[],e.next=22;break;case 19:e.prev=19,e.t0=e.catch(11),console.error(e.t0);case 22:l.updateResolvedSubtree([],y.resultMap);case 23:case"end":return e.stop()}}),e,null,[[11,19]])}))),35),ke=function(e){return function(t){var n;y()(n=D()(Ce).call(Ce,(function(e){return e.join("@@")}))).call(n,e.join("@@"))>-1||(Ce.push(e),Ce.system=t,Ae())}};function Oe(e,t,n,r,o){return{type:oe,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:o}}}function je(e,t,n,r){return{type:oe,payload:{path:e,param:t,value:n,isXml:r}}}var Te=function(e,t){return{type:ve,payload:{path:e,value:t}}},Ie=function(){return{type:ve,payload:{path:[],value:Object(V.Map)()}}},Pe=function(e,t){return{type:ie,payload:{pathMethod:e,isOAS3:t}}},Ne=function(e,t,n,r){return{type:ae,payload:{pathMethod:e,paramName:t,paramIn:n,includeEmptyValue:r}}};function Me(e){return{type:he,payload:{pathMethod:e}}}function Re(e,t){return{type:de,payload:{path:e,value:t,key:"consumes_value"}}}function De(e,t){return{type:de,payload:{path:e,value:t,key:"produces_value"}}}var Le=function(e,t,n){return{payload:{path:e,method:t,res:n},type:se}},Be=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ue}},Fe=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ce}},Ue=function(e){return{payload:e,type:le}},qe=function(e){return function(t){var n,r,o=t.fn,a=t.specActions,i=t.specSelectors,s=t.getConfigs,c=t.oas3Selectors,p=e.pathName,h=e.method,m=e.operation,g=s(),y=g.requestInterceptor,b=g.responseInterceptor,w=m.toJS();m&&m.get("parameters")&&v()(n=S()(r=m.get("parameters")).call(r,(function(e){return e&&!0===e.get("allowEmptyValue")}))).call(n,(function(t){if(i.parameterInclusionSettingFor([p,h],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};var n=Object(ee.C)(t,e.parameters);(!n||n&&0===n.size)&&(e.parameters[t.get("name")]="")}}));if(e.contextUrl=H()(i.url()).toString(),w&&w.operationId?e.operationId=w.operationId:w&&p&&h&&(e.operationId=o.opId(w,p,h)),i.isOAS3()){var x,E=d()(x="".concat(p,":")).call(x,h);e.server=c.selectedServer(E)||c.selectedServer();var C=c.serverVariables({server:e.server,namespace:E}).toJS(),A=c.serverVariables({server:e.server}).toJS();e.serverVariables=f()(C).length?C:A,e.requestContentType=c.requestContentType(p,h),e.responseContentType=c.responseContentType(p,h)||"*/*";var k=c.requestBodyValue(p,h),O=c.requestBodyInclusionSetting(p,h);if(Object(ee.t)(k))e.requestBody=JSON.parse(k);else if(k&&k.toJS){var j;e.requestBody=S()(j=D()(k).call(k,(function(e){return V.Map.isMap(e)?e.get("value"):e}))).call(j,(function(e,t){return(B()(e)?0!==e.length:!Object(ee.q)(e))||O.get(t)})).toJS()}else e.requestBody=k}var T=l()({},e);T=o.buildRequest(T),a.setRequest(e.pathName,e.method,T);var I=function(){var t=P()(_.a.mark((function t(n){var r,o;return _.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,y.apply(undefined,[n]);case 2:return r=t.sent,o=l()({},r),a.setMutatedRequest(e.pathName,e.method,o),t.abrupt("return",r);case 6:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}();e.requestInterceptor=I,e.responseInterceptor=b;var N=u()();return o.execute(e).then((function(t){t.duration=u()()-N,a.setResponse(e.pathName,e.method,t)})).catch((function(t){console.error(t),a.setResponse(e.pathName,e.method,{error:!0,err:$()(t)})}))}},ze=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.path,n=e.method,r=i()(e,["path","method"]);return function(e){var a=e.fn.fetch,i=e.specSelectors,s=e.specActions,u=i.specJsonWithResolvedSubtrees().toJS(),c=i.operationScheme(t,n),l=i.contentTypeValues([t,n]).toJS(),p=l.requestContentType,f=l.responseContentType,h=/xml/i.test(p),d=i.parameterValues([t,n],h).toJS();return s.executeRequest(o()(o()({},r),{},{fetch:a,spec:u,pathName:t,method:n,parameters:d,requestContentType:p,scheme:c,responseContentType:f}))}};function Ve(e,t){return{type:pe,payload:{path:e,method:t}}}function We(e,t){return{type:fe,payload:{path:e,method:t}}}function He(e,t,n){return{type:ge,payload:{scheme:e,path:t,method:n}}}},function(e,t,n){var r=n(33),o=n(52),a=n(232),i=n(71).f;e.exports=function(e){var t=r.Symbol||(r.Symbol={});o(t,e)||i(t,e,{value:a.f(e)})}},function(e,t,n){var r=n(35);e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},function(e,t,n){"use strict";var r=n(163),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],a=["scalar","sequence","mapping"];e.exports=function(e,t){var n,i;if(t=t||{},Object.keys(t).forEach((function(t){if(-1===o.indexOf(t))throw new r('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')})),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=(n=t.styleAliases||null,i={},null!==n&&Object.keys(n).forEach((function(e){n[e].forEach((function(t){i[String(t)]=e}))})),i),-1===a.indexOf(this.kind))throw new r('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}},function(e,t,n){var r=n(402),o=n(246),a=n(684),i=n(181),s=n(186);e.exports=function(e,t){var n;if(void 0===i||null==a(e)){if(o(e)||(n=s(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var u=0,c=function(){};return{s:c,n:function(){return u>=e.length?{done:!0}:{done:!1,value:e[u++]}},e:function(e){throw e},f:c}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var l,p=!0,f=!1;return{s:function(){n=r(e)},n:function(){var e=n.next();return p=e.done,e},e:function(e){f=!0,l=e},f:function(){try{p||null==n.return||n.return()}finally{if(f)throw l}}}}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(45);e.exports=function(e){if(!r(e))throw TypeError(String(e)+" is not an object");return e}},function(e,t){var n=Array.isArray;e.exports=n},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){var r=n(453),o=n(451),a=n(894);e.exports=function(e,t){if(null==e)return{};var n,i,s=a(e,t);if(o){var u=o(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}},function(e,t,n){"use strict";n.r(t),n.d(t,"UPDATE_SELECTED_SERVER",(function(){return r})),n.d(t,"UPDATE_REQUEST_BODY_VALUE",(function(){return o})),n.d(t,"UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG",(function(){return a})),n.d(t,"UPDATE_REQUEST_BODY_INCLUSION",(function(){return i})),n.d(t,"UPDATE_ACTIVE_EXAMPLES_MEMBER",(function(){return s})),n.d(t,"UPDATE_REQUEST_CONTENT_TYPE",(function(){return u})),n.d(t,"UPDATE_RESPONSE_CONTENT_TYPE",(function(){return c})),n.d(t,"UPDATE_SERVER_VARIABLE_VALUE",(function(){return l})),n.d(t,"SET_REQUEST_BODY_VALIDATE_ERROR",(function(){return p})),n.d(t,"CLEAR_REQUEST_BODY_VALIDATE_ERROR",(function(){return f})),n.d(t,"CLEAR_REQUEST_BODY_VALUE",(function(){return h})),n.d(t,"setSelectedServer",(function(){return d})),n.d(t,"setRequestBodyValue",(function(){return m})),n.d(t,"setRetainRequestBodyValueFlag",(function(){return v})),n.d(t,"setRequestBodyInclusion",(function(){return g})),n.d(t,"setActiveExamplesMember",(function(){return y})),n.d(t,"setRequestContentType",(function(){return b})),n.d(t,"setResponseContentType",(function(){return _})),n.d(t,"setServerVariableValue",(function(){return w})),n.d(t,"setRequestBodyValidateError",(function(){return x})),n.d(t,"clearRequestBodyValidateError",(function(){return E})),n.d(t,"initRequestBodyValidateError",(function(){return S})),n.d(t,"clearRequestBodyValue",(function(){return C}));var r="oas3_set_servers",o="oas3_set_request_body_value",a="oas3_set_request_body_retain_flag",i="oas3_set_request_body_inclusion",s="oas3_set_active_examples_member",u="oas3_set_request_content_type",c="oas3_set_response_content_type",l="oas3_set_server_variable_value",p="oas3_set_request_body_validate_error",f="oas3_clear_request_body_validate_error",h="oas3_clear_request_body_value";function d(e,t){return{type:r,payload:{selectedServerUrl:e,namespace:t}}}function m(e){var t=e.value,n=e.pathMethod;return{type:o,payload:{value:t,pathMethod:n}}}var v=function(e){var t=e.value,n=e.pathMethod;return{type:a,payload:{value:t,pathMethod:n}}};function g(e){var t=e.value,n=e.pathMethod,r=e.name;return{type:i,payload:{value:t,pathMethod:n,name:r}}}function y(e){var t=e.name,n=e.pathMethod,r=e.contextType,o=e.contextName;return{type:s,payload:{name:t,pathMethod:n,contextType:r,contextName:o}}}function b(e){var t=e.value,n=e.pathMethod;return{type:u,payload:{value:t,pathMethod:n}}}function _(e){var t=e.value,n=e.path,r=e.method;return{type:c,payload:{value:t,path:n,method:r}}}function w(e){var t=e.server,n=e.namespace,r=e.key,o=e.val;return{type:l,payload:{server:t,namespace:n,key:r,val:o}}}var x=function(e){var t=e.path,n=e.method,r=e.validationErrors;return{type:p,payload:{path:t,method:n,validationErrors:r}}},E=function(e){var t=e.path,n=e.method;return{type:f,payload:{path:t,method:n}}},S=function(e){var t=e.pathMethod;return{type:f,payload:{path:t[0],method:t[1]}}},C=function(e){var t=e.pathMethod;return{type:h,payload:{pathMethod:t}}}},function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};e.exports=o},function(e,t,n){e.exports=n(647)},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,n){"use strict";n.d(t,"b",(function(){return b})),n.d(t,"e",(function(){return _})),n.d(t,"c",(function(){return x})),n.d(t,"a",(function(){return E})),n.d(t,"d",(function(){return S}));var r=n(51),o=n.n(r),a=n(18),i=n.n(a),s=n(37),u=n.n(s),c=n(2),l=n.n(c),p=n(19),f=n.n(p),h=n(60),d=n.n(h),m=n(353),v=n.n(m),g=function(e){return String.prototype.toLowerCase.call(e)},y=function(e){return e.replace(/[^\w]/gi,"_")};function b(e){var t=e.openapi;return!!t&&v()(t,"3")}function _(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=r.v2OperationIdCompatibilityMode;if(!e||"object"!==f()(e))return null;var a=(e.operationId||"").replace(/\s/g,"");return a.length?y(e.operationId):w(t,n,{v2OperationIdCompatibilityMode:o})}function w(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=r.v2OperationIdCompatibilityMode;if(o){var a,i,s=l()(a="".concat(t.toLowerCase(),"_")).call(a,e).replace(/[\s!@#$%^&*()_+=[{\]};:<>|./?,\\'""-]/g,"_");return(s=s||l()(i="".concat(e.substring(1),"_")).call(i,t)).replace(/((_){2,})/g,"_").replace(/^(_)*/g,"").replace(/([_])*$/g,"")}return l()(n="".concat(g(t))).call(n,y(e))}function x(e,t){var n;return l()(n="".concat(g(t),"-")).call(n,e)}function E(e,t){return e&&e.paths?function(e,t){return function(e,t,n){if(!e||"object"!==f()(e)||!e.paths||"object"!==f()(e.paths))return null;var r=e.paths;for(var o in r)for(var a in r[o])if("PARAMETERS"!==a.toUpperCase()){var i=r[o][a];if(i&&"object"===f()(i)){var s={spec:e,pathName:o,method:a.toUpperCase(),operation:i},u=t(s);if(n&&u)return s}}return}(e,t,!0)||null}(e,(function(e){var n,r=e.pathName,o=e.method,a=e.operation;if(!a||"object"!==f()(a))return!1;var i=a.operationId,s=_(a,r,o),c=x(r,o);return u()(n=[s,c,i]).call(n,(function(e){return e&&e===t}))})):null}function S(e){var t=e.spec,n=t.paths,r={};if(!n||t.$$normalized)return e;for(var a in n){var s=n[a];if(d()(s)){var c=s.parameters,p=function(e){var n=s[e];if(!d()(n))return"continue";var p=_(n,a,e);if(p){r[p]?r[p].push(n):r[p]=[n];var f=r[p];if(f.length>1)i()(f).call(f,(function(e,t){var n;e.__originalOperationId=e.__originalOperationId||e.operationId,e.operationId=l()(n="".concat(p)).call(n,t+1)}));else if(void 0!==n.operationId){var h=f[0];h.__originalOperationId=h.__originalOperationId||n.operationId,h.operationId=p}}if("parameters"!==e){var m=[],v={};for(var g in t)"produces"!==g&&"consumes"!==g&&"security"!==g||(v[g]=t[g],m.push(v));if(c&&(v.parameters=c,m.push(v)),m.length){var y,b=o()(m);try{for(b.s();!(y=b.n()).done;){var w=y.value;for(var x in w)if(n[x]){if("parameters"===x){var E,S=o()(w[x]);try{var C=function(){var e,t=E.value;u()(e=n[x]).call(e,(function(e){return e.name&&e.name===t.name||e.$ref&&e.$ref===t.$ref||e.$$ref&&e.$$ref===t.$$ref||e===t}))||n[x].push(t)};for(S.s();!(E=S.n()).done;)C()}catch(e){S.e(e)}finally{S.f()}}}else n[x]=w[x]}}catch(e){b.e(e)}finally{b.f()}}}};for(var f in s)p(f)}}return t.$$normalized=!0,e}},function(e,t,n){"use strict";n.r(t),n.d(t,"NEW_THROWN_ERR",(function(){return a})),n.d(t,"NEW_THROWN_ERR_BATCH",(function(){return i})),n.d(t,"NEW_SPEC_ERR",(function(){return s})),n.d(t,"NEW_SPEC_ERR_BATCH",(function(){return u})),n.d(t,"NEW_AUTH_ERR",(function(){return c})),n.d(t,"CLEAR",(function(){return l})),n.d(t,"CLEAR_BY",(function(){return p})),n.d(t,"newThrownErr",(function(){return f})),n.d(t,"newThrownErrBatch",(function(){return h})),n.d(t,"newSpecErr",(function(){return d})),n.d(t,"newSpecErrBatch",(function(){return m})),n.d(t,"newAuthErr",(function(){return v})),n.d(t,"clear",(function(){return g})),n.d(t,"clearBy",(function(){return y}));var r=n(143),o=n.n(r),a="err_new_thrown_err",i="err_new_thrown_err_batch",s="err_new_spec_err",u="err_new_spec_err_batch",c="err_new_auth_err",l="err_clear",p="err_clear_by";function f(e){return{type:a,payload:o()(e)}}function h(e){return{type:i,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:u,payload:e}}function v(e){return{type:c,payload:e}}function g(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:l,payload:e}}function y(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:p,payload:e}}},function(e,t,n){var r=n(49),o=n(35),a=n(52),i=Object.defineProperty,s={},u=function(e){throw e};e.exports=function(e,t){if(a(s,e))return s[e];t||(t={});var n=[][e],c=!!a(t,"ACCESSORS")&&t.ACCESSORS,l=a(t,0)?t[0]:u,p=a(t,1)?t[1]:void 0;return s[e]=!!n&&!o((function(){if(c&&!r)return!0;var e={length:-1};c?i(e,1,{enumerable:!0,get:u}):e[1]=1,n.call(e,l,p)}))}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t,n){var r=n(77),o=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function i(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=i),a(o,i),i.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},i.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},i.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},i.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return q(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return z(e).length;default:if(r)return q(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return A(this,t,n);case"ascii":return O(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return C(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,o){var a,i=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;i=2,s/=2,u/=2,n/=2}function c(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o){var l=-1;for(a=n;as&&(n=s-u),a=n;a>=0;a--){for(var p=!0,f=0;fo&&(r=o):r=o;var a=t.length;if(a%2!=0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var i=0;i>8,o=n%256,a.push(o),a.push(r);return a}(t,e.length-n),e,n,r)}function C(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function A(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+p<=n)switch(p){case 1:c<128&&(l=c);break;case 2:128==(192&(a=e[o+1]))&&(u=(31&c)<<6|63&a)>127&&(l=u);break;case 3:a=e[o+1],i=e[o+2],128==(192&a)&&128==(192&i)&&(u=(15&c)<<12|(63&a)<<6|63&i)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:a=e[o+1],i=e[o+2],s=e[o+3],128==(192&a)&&128==(192&i)&&128==(192&s)&&(u=(15&c)<<18|(63&a)<<12|(63&i)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,p=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=p}return function(e){var t=e.length;if(t<=k)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var a=(o>>>=0)-(r>>>=0),i=(n>>>=0)-(t>>>=0),s=Math.min(a,i),c=this.slice(r,o),l=e.slice(t,n),p=0;po)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return _(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return x(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var k=4096;function O(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",a=t;an)throw new RangeError("Trying to access beyond buffer length")}function N(e,t,n,r,o,a){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function M(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,a=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,a=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function D(e,t,n,r,o,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,r,a){return a||D(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function B(e,t,n,r,a){return a||D(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,a=0;++a=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,a=this[e+--r];r>0&&(o*=256);)a+=this[e+--r]*o;return a>=(o*=128)&&(a-=Math.pow(2,8*t)),a},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||N(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,a=0;for(this[t]=255&e;++a=0&&(a*=256);)this[t+o]=e/a&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):M(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):R(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);N(this,e,t,n,o-1,-o)}var a=0,i=1,s=0;for(this[t]=255&e;++a>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);N(this,e,t,n,o-1,-o)}var a=n-1,i=1,s=0;for(this[t+a]=255&e;--a>=0&&(i*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/i>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):M(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||N(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return B(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return B(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(a<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(a=t;a55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===r){(t-=3)>-1&&a.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function z(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(F,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function V(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(55))},function(e,t,n){"use strict";var r=n(848);e.exports=r},function(e,t,n){var r=n(908);function o(e,t,n,o,a,i,s){try{var u=e[i](s),c=u.value}catch(e){return void n(e)}u.done?t(c):r.resolve(c).then(o,a)}e.exports=function(e){return function(){var t=this,n=arguments;return new r((function(r,a){var i=e.apply(t,n);function s(e){o(i,r,a,s,u,"next",e)}function u(e){o(i,r,a,s,u,"throw",e)}s(void 0)}))}}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},function(e,t,n){var r=n(151),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t,n){var r,o,a,i=n(364),s=n(42),u=n(45),c=n(70),l=n(52),p=n(234),f=n(180),h=n(152),d=s.WeakMap;if(i){var m=p.state||(p.state=new d),v=m.get,g=m.has,y=m.set;r=function(e,t){return t.facade=e,y.call(m,e,t),t},o=function(e){return v.call(m,e)||{}},a=function(e){return g.call(m,e)}}else{var b=f("state");h[b]=!0,r=function(e,t){return t.facade=e,c(e,b,t),t},o=function(e){return l(e,b)?e[b]:{}},a=function(e){return l(e,b)}}e.exports={set:r,get:o,has:a,enforce:function(e){return a(e)?o(e):r(e,{})},getterFor:function(e){return function(t){var n;if(!u(t)||(n=o(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";function r(e){return function(){return e}}var o=function(){};o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,n){"use strict";var r=n(31),o=n(40),a=n(475),i=n(124),s=n(476),u=n(140),c=n(204),l=n(26),p=[],f=0,h=a.getPooled(),d=!1,m=null;function v(){x.ReactReconcileTransaction&&m||r("123")}var g=[{initialize:function(){this.dirtyComponentsLength=p.length},close:function(){this.dirtyComponentsLength!==p.length?(p.splice(0,this.dirtyComponentsLength),w()):p.length=0}},{initialize:function(){this.callbackQueue.reset()},close:function(){this.callbackQueue.notifyAll()}}];function y(){this.reinitializeTransaction(),this.dirtyComponentsLength=null,this.callbackQueue=a.getPooled(),this.reconcileTransaction=x.ReactReconcileTransaction.getPooled(!0)}function b(e,t){return e._mountOrder-t._mountOrder}function _(e){var t=e.dirtyComponentsLength;t!==p.length&&r("124",t,p.length),p.sort(b),f++;for(var n=0;nS;S++)if((h||S in w)&&(b=x(y=w[S],S,_),e))if(t)A[S]=b;else if(b)switch(e){case 3:return!0;case 5:return y;case 6:return S;case 2:u.call(A,y)}else switch(e){case 4:return!1;case 7:u.call(A,y)}return p?-1:c||l?l:A}};e.exports={forEach:c(0),map:c(1),filter:c(2),some:c(3),every:c(4),find:c(5),findIndex:c(6),filterOut:c(7)}},function(e,t,n){"use strict";e.exports={current:null}},function(e,t){e.exports=function(e){return null!=e&&"object"==typeof e}},function(e,t){var n,r,o=e.exports={};function a(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function s(e){if(n===setTimeout)return setTimeout(e,0);if((n===a||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:a}catch(e){n=a}try{r="function"==typeof clearTimeout?clearTimeout:i}catch(e){r=i}}();var u,c=[],l=!1,p=-1;function f(){l&&u&&(l=!1,u.length?c=u.concat(c):p=-1,c.length&&h())}function h(){if(!l){var e=s(f);l=!0;for(var t=c.length;t;){for(u=c,c=[];++p1)for(var n=1;n0&&"/"!==t[0]}));function Se(e,t,n){var r;t=t||[];var o=we.apply(void 0,A()(r=[e]).call(r,O()(t))).get("parameters",Object(I.List)());return f()(o).call(o,(function(e,t){var r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set(Object(T.B)(t,{allowHashes:!1}),r)}),Object(I.fromJS)({}))}function Ce(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(I.List.isList(e))return u()(e).call(e,(function(e){return I.Map.isMap(e)&&e.get("in")===t}))}function Ae(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(I.List.isList(e))return u()(e).call(e,(function(e){return I.Map.isMap(e)&&e.get("type")===t}))}function ke(e,t){var n,r;t=t||[];var o=z(e).getIn(A()(n=["paths"]).call(n,O()(t)),Object(I.fromJS)({})),a=e.getIn(A()(r=["meta","paths"]).call(r,O()(t)),Object(I.fromJS)({})),i=Oe(e,t),s=o.get("parameters")||new I.List,u=a.get("consumes_value")?a.get("consumes_value"):Ae(s,"file")?"multipart/form-data":Ae(s,"formData")?"application/x-www-form-urlencoded":void 0;return Object(I.fromJS)({requestContentType:u,responseContentType:i})}function Oe(e,t){var n,r;t=t||[];var o=z(e).getIn(A()(n=["paths"]).call(n,O()(t)),null);if(null!==o){var a=e.getIn(A()(r=["meta","paths"]).call(r,O()(t),["produces_value"]),null),i=o.getIn(["produces",0],null);return a||i||"application/json"}}function je(e,t){var n;t=t||[];var r=z(e),o=r.getIn(A()(n=["paths"]).call(n,O()(t)),null);if(null!==o){var a=t,s=i()(a,1)[0],u=o.get("produces",null),c=r.getIn(["paths",s,"produces"],null),l=r.getIn(["produces"],null);return u||c||l}}function Te(e,t){var n;t=t||[];var r=z(e),o=r.getIn(A()(n=["paths"]).call(n,O()(t)),null);if(null!==o){var a=t,s=i()(a,1)[0],u=o.get("consumes",null),c=r.getIn(["paths",s,"consumes"],null),l=r.getIn(["consumes"],null);return u||c||l}}var Ie=function(e,t,n){var r=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),a=o()(r)?r[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||a||""},Pe=function(e,t,n){var r;return _()(r=["http","https"]).call(r,Ie(e,t,n))>-1},Ne=function(e,t){var n;t=t||[];var r=e.getIn(A()(n=["meta","paths"]).call(n,O()(t),["parameters"]),Object(I.fromJS)([])),o=!0;return x()(r).call(r,(function(e){var t=e.get("errors");t&&t.count()&&(o=!1)})),o},Me=function(e,t){var n,r,o={requestBody:!1,requestContentType:{}},a=e.getIn(A()(n=["resolvedSubtrees","paths"]).call(n,O()(t),["requestBody"]),Object(I.fromJS)([]));return a.size<1||(a.getIn(["required"])&&(o.requestBody=a.getIn(["required"])),x()(r=a.getIn(["content"]).entrySeq()).call(r,(function(e){var t=e[0];if(e[1].getIn(["schema","required"])){var n=e[1].getIn(["schema","required"]).toJS();o.requestContentType[t]=n}}))),o},Re=function(e,t,n,r){var o;if((n||r)&&n===r)return!0;var a=e.getIn(A()(o=["resolvedSubtrees","paths"]).call(o,O()(t),["requestBody","content"]),Object(I.fromJS)([]));if(a.size<2||!n||!r)return!1;var i=a.getIn([n,"schema","properties"],Object(I.fromJS)([])),s=a.getIn([r,"schema","properties"],Object(I.fromJS)([]));return!!i.equals(s)};function De(e){return I.Map.isMap(e)?e:new I.Map}},function(e,t,n){"use strict";(function(t){var r=n(915),o=n(916),a=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,i=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i,s=new RegExp("^[\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF]+");function u(e){return(e||"").toString().replace(s,"")}var c=[["#","hash"],["?","query"],function(e){return e.replace("\\","/")},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d+)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],l={hash:1,query:1};function p(e){var n,r=("undefined"!=typeof window?window:void 0!==t?t:"undefined"!=typeof self?self:{}).location||{},o={},i=typeof(e=e||r);if("blob:"===e.protocol)o=new h(unescape(e.pathname),{});else if("string"===i)for(n in o=new h(e,{}),l)delete o[n];else if("object"===i){for(n in e)n in l||(o[n]=e[n]);void 0===o.slashes&&(o.slashes=a.test(e.href))}return o}function f(e){e=u(e);var t=i.exec(e);return{protocol:t[1]?t[1].toLowerCase():"",slashes:!!t[2],rest:t[3]}}function h(e,t,n){if(e=u(e),!(this instanceof h))return new h(e,t,n);var a,i,s,l,d,m,v=c.slice(),g=typeof t,y=this,b=0;for("object"!==g&&"string"!==g&&(n=t,t=null),n&&"function"!=typeof n&&(n=o.parse),t=p(t),a=!(i=f(e||"")).protocol&&!i.slashes,y.slashes=i.slashes||a&&t.slashes,y.protocol=i.protocol||t.protocol||"",e=i.rest,i.slashes||(v[3]=[/(.*)/,"pathname"]);b=n.length?{value:void 0,done:!0}:(e=r(n,o),t.index+=e.length,{value:e,done:!1})}))},function(e,t,n){var r=n(238),o=n(71).f,a=n(70),i=n(52),s=n(559),u=n(39)("toStringTag");e.exports=function(e,t,n,c){if(e){var l=n?e:e.prototype;i(l,u)||o(l,u,{configurable:!0,value:t}),c&&!r&&a(l,"toString",s)}}},function(e,t,n){"use strict";e.exports=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e}},function(e,t,n){e.exports=n(636)},function(e,t,n){e.exports=n(869)},function(e,t,n){"use strict";n.r(t),n.d(t,"UPDATE_LAYOUT",(function(){return o})),n.d(t,"UPDATE_FILTER",(function(){return a})),n.d(t,"UPDATE_MODE",(function(){return i})),n.d(t,"SHOW",(function(){return s})),n.d(t,"updateLayout",(function(){return u})),n.d(t,"updateFilter",(function(){return c})),n.d(t,"show",(function(){return l})),n.d(t,"changeMode",(function(){return p}));var r=n(5),o="layout_update_layout",a="layout_update_filter",i="layout_update_mode",s="layout_show";function u(e){return{type:o,payload:e}}function c(e){return{type:a,payload:e}}function l(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=Object(r.w)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=Object(r.w)(e),{type:i,payload:{thing:e,mode:t}}}},function(e,t,n){"use strict";var r=n(1075),o=n(1076);function a(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}t.parse=b,t.resolve=function(e,t){return b(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?b(e,!1,!0).resolveObject(t):t},t.format=function(e){o.isString(e)&&(e=b(e));return e instanceof a?e.format():a.prototype.format.call(e)},t.Url=a;var i=/^([a-z0-9.+-]+:)/i,s=/:[0-9]*$/,u=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),l=["'"].concat(c),p=["%","/","?",";","#"].concat(l),f=["/","?","#"],h=/^[+a-z0-9A-Z_-]{0,63}$/,d=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:!0,"javascript:":!0},v={javascript:!0,"javascript:":!0},g={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},y=n(1077);function b(e,t,n){if(e&&o.isObject(e)&&e instanceof a)return e;var r=new a;return r.parse(e,t,n),r}a.prototype.parse=function(e,t,n){if(!o.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var a=e.indexOf("?"),s=-1!==a&&a127?N+="x":N+=P[M];if(!N.match(h)){var D=T.slice(0,k),L=T.slice(k+1),B=P.match(d);B&&(D.push(B[1]),L.unshift(B[2])),L.length&&(b="/"+L.join(".")+b),this.hostname=D.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),j||(this.hostname=r.toASCII(this.hostname));var F=this.port?":"+this.port:"",U=this.hostname||"";this.host=U+F,this.href+=this.host,j&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==b[0]&&(b="/"+b))}if(!m[x])for(k=0,I=l.length;k0)&&n.host.split("@"))&&(n.auth=j.shift(),n.host=n.hostname=j.shift());return n.search=e.search,n.query=e.query,o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n}if(!E.length)return n.pathname=null,n.search?n.path="/"+n.search:n.path=null,n.href=n.format(),n;for(var C=E.slice(-1)[0],A=(n.host||e.host||E.length>1)&&("."===C||".."===C)||""===C,k=0,O=E.length;O>=0;O--)"."===(C=E[O])?E.splice(O,1):".."===C?(E.splice(O,1),k++):k&&(E.splice(O,1),k--);if(!w&&!x)for(;k--;k)E.unshift("..");!w||""===E[0]||E[0]&&"/"===E[0].charAt(0)||E.unshift(""),A&&"/"!==E.join("/").substr(-1)&&E.push("");var j,T=""===E[0]||E[0]&&"/"===E[0].charAt(0);S&&(n.hostname=n.host=T?"":E.length?E.shift():"",(j=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@"))&&(n.auth=j.shift(),n.host=n.hostname=j.shift()));return(w=w||n.host&&E.length)&&!T&&E.unshift(""),E.length?n.pathname=E.join("/"):(n.pathname=null,n.path=null),o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},a.prototype.parseHost=function(){var e=this.host,t=s.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},function(e,t,n){var r=n(421),o=n(161),a=n(193),i=n(54),s=n(117),u=n(194),c=n(160),l=n(252),p=Object.prototype.hasOwnProperty;e.exports=function(e){if(null==e)return!0;if(s(e)&&(i(e)||"string"==typeof e||"function"==typeof e.splice||u(e)||l(e)||a(e)))return!e.length;var t=o(e);if("[object Map]"==t||"[object Set]"==t)return!e.size;if(c(e))return!r(e).length;for(var n in e)if(p.call(e,n))return!1;return!0}},function(e,t,n){var r=n(49),o=n(176),a=n(108),i=n(69),s=n(178),u=n(52),c=n(357),l=Object.getOwnPropertyDescriptor;t.f=r?l:function(e,t){if(e=i(e),t=s(t,!0),c)try{return l(e,t)}catch(e){}if(u(e,t))return a(!o.f.call(e,t),e[t])}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(80);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r,o=n(53),a=n(237),i=n(231),s=n(152),u=n(369),c=n(228),l=n(180),p=l("IE_PROTO"),f=function(){},h=function(e){return" - - - - diff --git a/src/test/__init__.py b/src/test/__init__.py deleted file mode 100644 index 48d608d3ae8a09eaea547df6037cd23340b57244..0000000000000000000000000000000000000000 --- a/src/test/__init__.py +++ /dev/null @@ -1,551 +0,0 @@ -import logging -import uuid - -import connexion -import pymongo -import requests -from flask_testing import TestCase - -from encoder import JSONEncoder - -from configparser import ConfigParser -from clients import srm -import util - -CONFIG = ConfigParser() -CONFIG.read("conf/config.cfg") -HOST = CONFIG.get("server", "host") -PORT = int(CONFIG.get("server", "port")) -CLIENT_ID = CONFIG.get("keycloak", "client1_id") -CLIENT_SECRET = CONFIG.get("keycloak", "client1_secret") -SERVER = "/operatorplatform/federation/v1" -HOST_KEYCLOAK = CONFIG.get("keycloak", "host") -PORT_KEYCLOAK = int(CONFIG.get("keycloak", "port")) - -# Dual role testing configuration -PARTNER_API_ROOT = "http://federation-manager-remote:8989" - - -class BaseTestCase(TestCase): - - def create_app(self): - # logging.getLogger('connexion.operation').setLevel('ERROR') - logging.basicConfig(level=logging.ERROR) - app = connexion.App(__name__, specification_dir='../swagger/') - app.app.json_encoder = JSONEncoder - app.add_api('swagger.yaml') - - # keycloak - self.client_id = CLIENT_ID - self.client_secret = CLIENT_SECRET - - # Base url application server - self.base_url = f"{HOST}:{PORT}{SERVER}" - - if not hasattr(BaseTestCase, "run_suffix"): - BaseTestCase.run_suffix = uuid.uuid4().hex[:8] - BaseTestCase.artefact_id_pop_run = str(uuid.uuid5(uuid.NAMESPACE_DNS, - f"fm-test-pop-{BaseTestCase.run_suffix}")) - BaseTestCase.artefact_id_oop_run = str(uuid.uuid5(uuid.NAMESPACE_DNS, - f"fm-test-oop-{BaseTestCase.run_suffix}")) - BaseTestCase.app_id_pop_run = f"test_app_pop_{BaseTestCase.run_suffix}" - BaseTestCase.app_id_oop_run = f"test_app_oop_{BaseTestCase.run_suffix}" - - # Partner OP (POP) configuration - self.artefact_id_pop = BaseTestCase.artefact_id_pop_run - self.app_id_pop = BaseTestCase.app_id_pop_run - self.artefact_name_pop = "ollama" - self.artefact_repo_pop = "https://otwld.github.io/ollama-helm/" - - # Originating OP (OOP) configuration - self.artefact_id_oop = BaseTestCase.artefact_id_oop_run - self.app_id_oop = BaseTestCase.app_id_oop_run - self.artefact_name_oop = "kubernetes-dashboard" - self.artefact_repo_oop = "https://kubernetes.github.io/dashboard/" - self.deployable_artefact_name = self.artefact_name_pop - self.deployable_artefact_repo = self.artefact_repo_pop - - # Common artifact configuration - self.app_provider = "test_app_provider" - self.artefact_version = "0.3.0" - self.repo_type = util.RepoType.PUBLIC.value - - return app.app - - def cleanup_fm_test_state(self): - """Remove leftover FM documents for the fixed integration test IDs.""" - app_ids = [self.app_id_pop, self.app_id_oop] - artefact_ids = [self.artefact_id_pop, self.artefact_id_oop] - - client = pymongo.MongoClient(f"mongodb://{CONFIG.get('mongodb', 'host')}:{CONFIG.get('mongodb', 'port')}") - database = client["federation-manager"] - - database["originating_application_deployment_management"].delete_many({"orig_ad_app_id": {"$in": app_ids}}) - database["originating_application_deployment_management_originating_o_p"].delete_many( - {"orig_ad_app_id": {"$in": app_ids}} - ) - database["originating_application_onboarding_management"].delete_many({"orig_ao_app_id": {"$in": app_ids}}) - database["originating_application_onboarding_management_originating_o_p"].delete_many( - {"orig_ao_app_id": {"$in": app_ids}} - ) - database["originating_application_onboarding_management_update"].delete_many({}) - database["originating_application_onboarding_management_update_originating_o_p"].delete_many({}) - database["originating_artefact_management"].delete_many({"orig_am_artefact_id": {"$in": artefact_ids}}) - database["originating_artefact_management_originating_o_p"].delete_many( - {"orig_am_artefact_id": {"$in": artefact_ids}} - ) - database["originating_operator_platform"].delete_many({}) - database["originating_operator_platform_originating_o_p"].delete_many({}) - database["originating_operator_platform_update"].delete_many({}) - database["originating_operator_platform_update_originating_o_p"].delete_many({}) - client.close() - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.zone_partner = "" - BaseTestCase.zone_originating = "" - BaseTestCase.instances_partner = [] - BaseTestCase.instances_originating = [] - - def cleanup_ecp_test_state(self): - """Remove leftover SRM/ECP artefacts and onboardings for test fixtures.""" - for app_id in [self.app_id_pop, self.app_id_oop]: - try: - srm.delete_onboarding(app_id) - except Exception: - pass - - def build_api_url(self, api_root, path): - return f"{api_root}{SERVER}/{path}" - - def get_federation_context_at_api_root(self, token, api_root): - """Get federation context directly from a specific FM API root.""" - url = self.build_api_url(api_root, "fed-context-id") - return self.make_request_partner_op("GET", url, token=token) - - def get_federation_at_api_root(self, federation_id, token, api_root): - """Get federation details directly from a specific FM API root.""" - url = self.build_api_url(api_root, f"{federation_id}/partner") - return self.make_request_partner_op("GET", url, token=token) - - def get_app_instances_at_api_root(self, federation_id, app_id, app_provider_id, token, api_root): - """Get application instances directly from a specific FM API root.""" - url = self.build_api_url(api_root, f"{federation_id}/application/lcm/app/{app_id}/appProvider/{app_provider_id}") - return self.make_request_partner_op("GET", url, token=token) - - def cleanup_remote_partner_test_state(self, token, api_root=PARTNER_API_ROOT): - """Remove leftover partner-side FM resources created by originating-mode integration tests.""" - response = self.get_federation_context_at_api_root(token, api_root) - if response.status_code != 200: - return - - federation_context_id = response.json().get("federationContextId") - if not federation_context_id: - return - - instances_response = self.get_app_instances_at_api_root( - federation_context_id, - self.app_id_oop, - self.app_provider, - token, - api_root, - ) - if instances_response.status_code == 200: - for zone_info in instances_response.json(): - zone_id = zone_info.get("zoneId") - if not zone_id: - continue - for instance in zone_info.get("appInstanceInfo", []): - instance_id = instance.get("appInstIdentifier") - if not instance_id: - continue - try: - url = self.build_api_url( - api_root, - f"{federation_context_id}/application/lcm/app/{self.app_id_oop}/instance/{instance_id}/zone/{zone_id}", - ) - self.make_request_partner_op("DELETE", url, token=token) - except Exception: - pass - - for app_id in [self.app_id_oop]: - try: - url = self.build_api_url(api_root, f"{federation_context_id}/application/onboarding/app/{app_id}") - self.make_request_partner_op("DELETE", url, token=token) - except Exception: - pass - - for artefact_id in [self.artefact_id_oop]: - try: - url = self.build_api_url(api_root, f"{federation_context_id}/artefact/{artefact_id}") - self.make_request_partner_op("DELETE", url, token=token) - except Exception: - pass - - try: - federation_response = self.get_federation_at_api_root(federation_context_id, token, api_root) - if federation_response.status_code == 200: - federation_data = federation_response.json() - for zone in federation_data.get("offeredAvailabilityZones", []): - zone_id = zone.get("zoneId") if isinstance(zone, dict) else None - if not zone_id: - continue - try: - url = self.build_api_url(api_root, f"{federation_context_id}/zones/{zone_id}") - self.make_request_partner_op("DELETE", url, token=token) - except Exception: - pass - except Exception: - pass - - try: - url = self.build_api_url(api_root, f"{federation_context_id}/partner") - self.make_request_partner_op("DELETE", url, token=token) - except Exception: - pass - - for artefact_id in [self.artefact_id_pop, self.artefact_id_oop]: - try: - srm.delete_artefact(artefact_id) - except Exception: - pass - - def get_access_token(self): - # URL to obtain access token from Keycloak - token_url = f"http://{HOST_KEYCLOAK}:{PORT_KEYCLOAK}/realms/federation/protocol/openid-connect/token" - - payload = { - "client_id": self.client_id, - "client_secret": self.client_secret, - "grant_type": "client_credentials" - } - - try: - # POST to obtain access token - response = requests.post(token_url, data=payload) - # Returns access token - return response.json()["access_token"] - except Exception as e: - print(f"Warning: Could not get access token: {e}") - return "mock_token_for_testing" - - def make_request_partner_op(self, method, url, body=None, token=None): - """Make request as Partner OP (external request without X-Internal header)""" - headers = { - "Content-Type": "application/json; accept=application/json", - "Authorization": f"Bearer {token or self.get_access_token()}" - } - - if method.upper() == "GET": - return requests.get(url, headers=headers) - elif method.upper() == "POST": - return requests.post(url, headers=headers, json=body) - elif method.upper() == "PUT": - return requests.put(url, headers=headers, json=body) - elif method.upper() == "PATCH": - return requests.patch(url, headers=headers, json=body) - elif method.upper() == "DELETE": - return requests.delete(url, headers=headers) - - def make_request_originating_op(self, method, url, body=None, token=None, partner_api_root=None): - """Make request as Originating OP (internal request with X-Internal header)""" - headers = { - "Content-Type": "application/json; accept=application/json", - "Authorization": f"Bearer {token or self.get_access_token()}", - "X-Internal": "true", - "X-Partner-Api-Root": partner_api_root or PARTNER_API_ROOT - } - - if method.upper() == "GET": - return requests.get(url, headers=headers) - elif method.upper() == "POST": - return requests.post(url, headers=headers, json=body) - elif method.upper() == "PUT": - return requests.put(url, headers=headers, json=body) - elif method.upper() == "PATCH": - return requests.patch(url, headers=headers, json=body) - elif method.upper() == "DELETE": - return requests.delete(url, headers=headers) - - def run_both_roles(self, test_func, *args, **kwargs): - """Helper method to run a test function for both Partner OP and Originating OP roles""" - results = {} - - # Test Partner OP role (external request) - try: - results['partner_op'] = test_func('partner_op', *args, **kwargs) - except Exception as e: - results['partner_op'] = {'error': str(e)} - - # Test Originating OP role (internal request) - try: - results['originating_op'] = test_func('originating_op', *args, **kwargs) - except Exception as e: - results['originating_op'] = {'error': str(e)} - - return results - - def post_federation(self, token, role='partner_op'): - """Create federation context for specified role""" - federation_context_id = "" - - url = f"http://{self.base_url}/partner" - body = { - "origOPFederationId": "string", - "origOPCountryCode": "US", - "origOPMobileNetworkCodes": { - "mcc": "111", - "mncs": [ - "11" - ] - }, - "origOPFixedNetworkCodes": [ - "string" - ], - "initialDate": "2024-02-26T11:05:07.925Z", - "partnerStatusLink": "string", - "partnerCallbackCredentials": { - "tokenUrl": "string", - "clientId": "string", - "clientSecret": "string" - } - } - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, token) - else: - response = self.make_request_partner_op("POST", url, body, token) - - assert response.status_code == 200 - data_response = response.json() - federation_context_id = data_response.get("federationContextId") - - return federation_context_id - - def post_availability_zones(self, federation_context_id, zone_id, token, role='partner_op'): - """Create availability zones for specified role""" - url = f"http://{self.base_url}/{federation_context_id}/zones" - body = { - "acceptedAvailabilityZones": [ - zone_id - ], - "availZoneNotifLink": "string" - } - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, token) - else: - response = self.make_request_partner_op("POST", url, body, token) - - assert response.status_code == 200 - return - - def post_artefact(self, federation_context_id, artefact_id, artefact_name, artefact_repo, token, - role='partner_op'): - """Create artefact for specified role""" - url = f"http://{self.base_url}/{federation_context_id}/artefact" - body = { - "artefactId": artefact_id, - "appProviderId": self.app_provider, - "artefactName": artefact_name, - "artefactVersionInfo": self.artefact_version, - "artefactVirtType": "CONTAINER_TYPE", - "artefactDescriptorType": "HELM", - "repoType": self.repo_type, - "artefactRepoLocation": { - "repoURL": artefact_repo - }, - "componentSpec": [ - { - "componentName": artefact_name, - "images": [ - artefact_id - ], - "numOfInstances": 1, - "restartPolicy": "RESTART_POLICY_ALWAYS", - "computeResourceProfile": { - "cpuArchType": "ISA_X86_64", - "numCPU": "500m", - "memory": 0 - } - } - ] - } - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, token) - else: - response = self.make_request_partner_op("POST", url, body, token) - - assert response.status_code == 200 - return - - def post_onboarding(self, federation_context_id, app_id, zone_id, artefact_id, token, role='partner_op'): - """Create onboarding for specified role""" - url = f"http://{self.base_url}/{federation_context_id}/application/onboarding" - body = { - "appId": app_id, - "appProviderId": self.app_provider, - "appDeploymentZones": [ - zone_id - ], - "appMetaData": { - "appName": "dsdsdsdssdssdsdssd", - "version": "string", - "appDescription": "sdssdssdsdssdsdsdss", - "mobilitySupport": False, - "accessToken": "sdsddssddssdsssdsdsdsdsdsdsdsddsddsdsdsdsdsd", - "category": "IOT" - }, - "appQoSProfile": { - "latencyConstraints": "NONE", - "bandwidthRequired": 1, - "multiUserClients": "APP_TYPE_SINGLE_USER", - "noOfUsersPerAppInst": 1, - "appProvisioning": True - }, - "appComponentSpecs": [ - { - "serviceNameNB": "dsdsdsdsdsdsdsdsdsdds", - "serviceNameEW": "sdsdsdsdddsssdsdssdsd", - "componentName": "sdssssssssdsdsdsdsdss", - "artefactId": artefact_id - } - ], - "appStatusCallbackLink": "string" - } - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, token) - else: - response = self.make_request_partner_op("POST", url, body, token) - - assert response.status_code == 202 - return - - def delete_deployments(self, federation_id, app_id, instance_id, zone_id, token, role='partner_op'): - """Delete deployments for specified role""" - url = f"http://{self.base_url}/{federation_id}/application/lcm/app/{app_id}/instance/{instance_id}/zone/{zone_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=token) - else: - response = self.make_request_partner_op("DELETE", url, token=token) - - return response - - def delete_onboarding(self, federation_id, app_id, token, role='partner_op'): - """Delete onboarding for specified role""" - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/{app_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=token) - else: - response = self.make_request_partner_op("DELETE", url, token=token) - - return response - - def delete_artefact(self, federation_id, artefact_id, token, role='partner_op'): - """Delete artefact for specified role""" - url = f"http://{self.base_url}/{federation_id}/artefact/{artefact_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=token) - else: - response = self.make_request_partner_op("DELETE", url, token=token) - - return response - - def delete_zone(self, federation_id, zone_id, token, role='partner_op'): - """Delete zone for specified role""" - url = f"http://{self.base_url}/{federation_id}/zones/{zone_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=token) - else: - response = self.make_request_partner_op("DELETE", url, token=token) - - return response - - def delete_federation(self, federation_id, token, role='partner_op'): - """Delete federation for specified role""" - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=token) - else: - response = self.make_request_partner_op("DELETE", url, token=token) - - return response - - def get_federation(self, federation_id, token, role='partner_op'): - """Get federation for specified role""" - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=token) - else: - response = self.make_request_partner_op("GET", url, token=token) - - return response.json() - - def get_availability_zone(self, federation_id, zone_id, token, role='partner_op'): - """Get zone details for specified role""" - url = f"http://{self.base_url}/{federation_id}/zones/{zone_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=token) - else: - response = self.make_request_partner_op("GET", url, token=token) - - return response.json() - - def get_zone_from_partner_details(self, federation_id, token, role='partner_op'): - zone_selected = "" - - try: - partner_details = self.get_federation(federation_id, token, role) - # Get zone list - zones_list = partner_details.get("offeredAvailabilityZones") - - if not zones_list: - return zone_selected - - for zone in zones_list: - # If the zone value is a dict, is a correct zone, else there is an issue and returns a str - if isinstance(zone, dict): - zone_id = zone.get("zoneId") - if zone_id: - zone_selected = zone_id - break - except Exception as e: - print(f"Error getting zone from partner details: {e}") - zone_selected = "" - - return zone_selected - - def get_flavour_from_zone_details(self, federation_id, zone_id, token, role='partner_op'): - flavour_selected = "" - - try: - zone_details = self.get_availability_zone(federation_id, zone_id, token, role) - flavours = zone_details.get("flavoursSupported") - if len(flavours) > 0: - for f in flavours: - flavour_selected = f.get("flavourId") - break - except: - flavour_selected = "" - - return flavour_selected - - def get_federation_context(self, token, role='partner_op'): - """Get federation resources for specified role""" - url = f"http://{self.base_url}/fed-context-id" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=token) - else: - response = self.make_request_partner_op("GET", url, token=token) - - return response.json() diff --git a/src/test/local-deployment/docker-compose.yml b/src/test/local-deployment/docker-compose.yml deleted file mode 100644 index 99f2ef09a9fce9dbf8415f3dbb51fd2396c34dbb..0000000000000000000000000000000000000000 --- a/src/test/local-deployment/docker-compose.yml +++ /dev/null @@ -1,235 +0,0 @@ -services: - k3s: - image: rancher/k3s:v1.28.2-k3s1 - container_name: k3s - privileged: true - command: server --disable=traefik --tls-san k3s - environment: - K3S_TOKEN: secret-token - K3S_KUBECONFIG_MODE: "644" - tmpfs: - - /run - - /var/run - volumes: - - k3s-data:/var/lib/rancher/k3s - - k3s-config:/etc/rancher/k3s - networks: - - local-net - - remote-net - - k3s-kubeconfig: - image: python:3.11-alpine - container_name: k3s-kubeconfig - depends_on: - - k3s - volumes: - - k3s-config:/input:ro - - k3s-kubeconfig:/output - - ../../../../../OP_Automation/docker-local-deployment/prepare_kubeconfig.py:/prepare_kubeconfig.py:ro - command: ["python", "/prepare_kubeconfig.py"] - - mongodb-local: - image: mongo - container_name: mongodb-local - restart: unless-stopped - ports: - - "27017:27017" - environment: - MONGO_INITDB_DATABASE: federation-manager - MONGODB_DATA_DIR: /data/db - MONDODB_LOG_DIR: /dev/null - volumes: - - smdbdata-local:/data/db - networks: - - local-net - - mongodb-remote: - image: mongo - container_name: mongodb-remote - restart: unless-stopped - ports: - - "27018:27017" - environment: - MONGO_INITDB_DATABASE: federation-manager - MONGODB_DATA_DIR: /data/db - MONDODB_LOG_DIR: /dev/null - volumes: - - smdbdata-remote:/data/db - networks: - - remote-net - - keycloak-local: - image: quay.io/keycloak/keycloak:26.1.4 - container_name: keycloak-local - environment: - - KC_BOOTSTRAP_ADMIN_USERNAME=admin - - KC_BOOTSTRAP_ADMIN_PASSWORD=admin - - KC_IMPORT=/opt/keycloak/data/import/realm-import.json - ports: - - "8080:8080" - command: ["start-dev", "--import-realm"] - volumes: - - ../../../keycloak/realm-import.json:/opt/keycloak/data/import/realm-import.json - networks: - - local-net - - keycloak-remote: - image: quay.io/keycloak/keycloak:26.1.4 - container_name: keycloak-remote - environment: - - KC_BOOTSTRAP_ADMIN_USERNAME=admin - - KC_BOOTSTRAP_ADMIN_PASSWORD=admin - - KC_IMPORT=/opt/keycloak/data/import/realm-import.json - ports: - - "8081:8080" - command: ["start-dev", "--import-realm"] - volumes: - - ../../../keycloak/realm-import.json:/opt/keycloak/data/import/realm-import.json - networks: - - remote-net - - federation-manager-remote: - build: - context: ../../../ - dockerfile: Dockerfile - container_name: federation-manager-remote - restart: unless-stopped - ports: - - "30990:8989" - volumes: - - ../../conf/config-fm-remote.cfg:/usr/app/src/conf/config.cfg - - depends_on: - - mongodb-remote - - keycloak-remote - - srm-remote - networks: - - federation-net - - remote-net - - federation-manager-local: - build: - context: ../../../ - dockerfile: Dockerfile - container_name: federation-manager-local - restart: unless-stopped - ports: - - "8989:8989" - environment: - - KUBECONFIG=/kubeconfig/kubeconfig.yaml - volumes: - - ../../conf/config-fm-local.cfg:/usr/app/src/conf/config.cfg - - k3s-kubeconfig:/kubeconfig:ro - depends_on: - - mongodb-local - - keycloak-local - - srm-local - networks: - - federation-net - - local-net - - srm-local: - build: - context: ../../../../../service-resource-manager/service-resource-manager-implementation/service-resource-manager-implementation - dockerfile: Dockerfile - container_name: srm-local - restart: unless-stopped - ports: - - "8082:8080" - environment: - EDGE_CLOUD_ADAPTER_NAME: lite2edge - ADAPTER_BASE_URL: http://lite2edge-local:8080 - PLATFORM_PROVIDER: lite2edge - ARTIFACT_MANAGER_ADDRESS: http://artefact-manager:8000 - KUBECONFIG: /kubeconfig/kubeconfig.yaml - PYTHONPATH: /workspace/tf-sdk/src:/workspace/lite2edge - volumes: - - ../../../../../tf-sdk/src:/workspace/tf-sdk/src - - ../../../../../lite2edge:/workspace/lite2edge - - k3s-kubeconfig:/kubeconfig:ro - depends_on: - - lite2edge-local - - k3s-kubeconfig - networks: - - local-net - - srm-remote: - build: - context: ../../../../../service-resource-manager/service-resource-manager-implementation/service-resource-manager-implementation - dockerfile: Dockerfile - container_name: srm-remote - restart: unless-stopped - ports: - - "8083:8080" - environment: - EDGE_CLOUD_ADAPTER_NAME: lite2edge - ADAPTER_BASE_URL: http://lite2edge-remote:8080 - PLATFORM_PROVIDER: lite2edge - ARTIFACT_MANAGER_ADDRESS: http://artefact-manager:8000 - KUBECONFIG: /kubeconfig/kubeconfig.yaml - PYTHONPATH: /workspace/tf-sdk/src:/workspace/lite2edge - volumes: - - ../../../../../tf-sdk/src:/workspace/tf-sdk/src - - ../../../../../lite2edge:/workspace/lite2edge - - k3s-kubeconfig:/kubeconfig:ro - depends_on: - - lite2edge-remote - - k3s-kubeconfig - networks: - - remote-net - - lite2edge-local: - build: - context: ../../../../../lite2edge - dockerfile: Dockerfile - container_name: lite2edge-local - restart: unless-stopped - ports: - - "8752:8080" - environment: - - KUBECONFIG=/kubeconfig/kubeconfig.yaml - - LOG_LEVEL=INFO - volumes: - - k3s-kubeconfig:/kubeconfig:ro - depends_on: - - k3s-kubeconfig - networks: - - local-net - - lite2edge-remote: - build: - context: ../../../../../lite2edge - dockerfile: Dockerfile - container_name: lite2edge-remote - restart: unless-stopped - ports: - - "8751:8080" - environment: - - KUBECONFIG=/kubeconfig/kubeconfig.yaml - - LOG_LEVEL=INFO - volumes: - - k3s-kubeconfig:/kubeconfig:ro - depends_on: - - k3s-kubeconfig - networks: - - remote-net - -volumes: - k3s-data: - driver: local - k3s-config: - driver: local - k3s-kubeconfig: - driver: local - smdbdata-local: - driver: local - smdbdata-remote: - driver: local - -networks: - federation-net: - driver: bridge - local-net: - driver: bridge - remote-net: - driver: bridge diff --git a/src/test/run_all_tests.py b/src/test/run_all_tests.py deleted file mode 100644 index 4a95727062e28fae17f14f6779c0e72a23003665..0000000000000000000000000000000000000000 --- a/src/test/run_all_tests.py +++ /dev/null @@ -1,320 +0,0 @@ -#!/usr/bin/env python3 -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -""" -Comprehensive Test Runner for Federation Manager - -This script runs all tests for the Federation Manager application - -Dual Role Testing: -The integration tests validate both operational modes: -- Partner OP mode (external requests without X-Internal header) -- Originating OP mode (internal requests with X-Internal header + X-Partner-API-Root) - -This ensures the entire stack (API + adapter + client + external integration) -works correctly for both roles in the Federation Manager's dual role architecture. - -Usage: - python run_all_tests.py [--verbose] [--coverage] - -Options: - --verbose: Enable verbose test output - --coverage: Generate code coverage report -""" - -import unittest -import sys -import os -import argparse -import time -from io import StringIO - - -class ColoredTestResult(unittest.TextTestResult): - """Custom test result class with colored output""" - - def __init__(self, stream, descriptions, verbosity, use_colors=True): - super().__init__(stream, descriptions, verbosity) - self.verbosity = verbosity # Store verbosity as instance variable - self.use_colors = use_colors and hasattr(stream, 'isatty') and stream.isatty() - - def _color(self, color_code, text): - if self.use_colors: - return f"\033[{color_code}m{text}\033[0m" - return text - - def addSuccess(self, test): - super().addSuccess(test) - if self.verbosity > 1: - self.stream.writeln(self._color("32", f"✓ {test._testMethodName}")) - - def addError(self, test, err): - super().addError(test, err) - if self.verbosity > 1: - self.stream.writeln(self._color("31", f"✗ {test._testMethodName} (ERROR)")) - - def addFailure(self, test, err): - super().addFailure(test, err) - if self.verbosity > 1: - self.stream.writeln(self._color("31", f"✗ {test._testMethodName} (FAIL)")) - - def addSkip(self, test, reason): - super().addSkip(test, reason) - if self.verbosity > 1: - self.stream.writeln(self._color("33", f"- {test._testMethodName} (SKIPPED)")) - - -class ColoredTestRunner(unittest.TextTestRunner): - """Custom test runner with colored output""" - - def __init__(self, **kwargs): - kwargs['resultclass'] = ColoredTestResult - super().__init__(**kwargs) - - -class TestSuiteManager: - """Manages different test suites and their execution""" - - def __init__(self, verbosity=1, use_coverage=False): - self.verbosity = verbosity - self.use_coverage = use_coverage - self.results = {} - - if use_coverage: - try: - import coverage - self.cov = coverage.Coverage() - self.cov.start() - except ImportError: - print("Warning: coverage module not found. Install with: pip install coverage") - self.use_coverage = False - - def discover_integration_tests(self): - """Discover integration tests in the specified order""" - loader = unittest.TestLoader() - suite = unittest.TestSuite() - - # Define the specific order for running tests - ordered_test_modules = [ - 'test_federation_management', - 'test_availability_zone_info_synchronization', - 'test_artefact_management', - 'test_application_onboarding_management', - 'test_application_deployment_management' - ] - - print(f"Running integration tests in specified order: {ordered_test_modules}") - - for test_module in ordered_test_modules: - try: - tests = loader.loadTestsFromName(f'test.{test_module}') - suite.addTests(tests) - print(f"✓ Loaded tests from {test_module}") - except Exception as e: - print(f"⚠️ Warning: Could not load {test_module}: {e}") - - # Check for any additional test files not in the ordered list - test_dir = os.path.dirname(__file__) - all_test_files = [f[:-3] for f in os.listdir(test_dir) - if f.startswith('test_') and f.endswith('.py')] - - additional_tests = [t for t in all_test_files if t not in ordered_test_modules] - if additional_tests: - print(f"ℹ️ Found additional test modules (will run after ordered tests): {additional_tests}") - for test_module in additional_tests: - try: - tests = loader.loadTestsFromName(f'test.{test_module}') - suite.addTests(tests) - print(f"✓ Loaded additional tests from {test_module}") - except Exception as e: - print(f"⚠️ Warning: Could not load {test_module}: {e}") - - return suite - - def run_suite(self, name, suite): - """Run a specific test suite""" - print(f"\n{'='*60}") - print(f"Running {name}") - print("(Dual Role Integration Tests - Partner OP & Originating OP modes)") - print(f"{'='*60}") - - if suite.countTestCases() == 0: - print(f"No tests found") - return None - - runner = ColoredTestRunner( - verbosity=self.verbosity, - stream=sys.stdout, - buffer=True - ) - - start_time = time.time() - result = runner.run(suite) - end_time = time.time() - - # Store results - self.results[name] = { - 'result': result, - 'duration': end_time - start_time, - 'tests_run': result.testsRun, - 'failures': len(result.failures), - 'errors': len(result.errors), - 'skipped': len(result.skipped) - } - - return result - - def print_summary(self): - """Print comprehensive test summary""" - print(f"\n{'='*60}") - print("TEST SUMMARY") - print(f"{'='*60}") - - total_tests = 0 - total_failures = 0 - total_errors = 0 - total_skipped = 0 - total_duration = 0 - - for suite_name, data in self.results.items(): - total_tests += data['tests_run'] - total_failures += data['failures'] - total_errors += data['errors'] - total_skipped += data['skipped'] - total_duration += data['duration'] - - status = "✓ PASS" - if data['failures'] > 0 or data['errors'] > 0: - status = "✗ FAIL" - - print(f"{suite_name:20} {status:8} {data['tests_run']:3d} tests, " - f"{data['failures']:2d} failures, {data['errors']:2d} errors, " - f"{data['skipped']:2d} skipped ({data['duration']:.2f}s)") - - print(f"{'-'*60}") - overall_status = "✓ ALL PASSED" if total_failures == 0 and total_errors == 0 else "✗ SOME FAILED" - print(f"{'TOTAL':20} {overall_status:8} {total_tests:3d} tests, " - f"{total_failures:2d} failures, {total_errors:2d} errors, " - f"{total_skipped:2d} skipped ({total_duration:.2f}s)") - - # Print dual role testing summary - if 'Integration Tests' in self.results: - print(f"\n🔄 Dual Role Integration Testing:") - print(f" ✓ Partner OP & Originating OP modes validated across full stack") - print(f" ✓ API → Adapter → Client → External System integration verified") - - if self.use_coverage: - self._print_coverage_report() - - return total_failures == 0 and total_errors == 0 - - def _print_coverage_report(self): - """Print code coverage report""" - try: - self.cov.stop() - self.cov.save() - - print(f"\n{'='*60}") - print("CODE COVERAGE REPORT") - print(f"{'='*60}") - - # Generate coverage report - coverage_stream = StringIO() - self.cov.report(file=coverage_stream, show_missing=True) - print(coverage_stream.getvalue()) - - # Generate HTML coverage report - self.cov.html_report(directory='htmlcov') - print("HTML coverage report generated in 'htmlcov/' directory") - - except Exception as e: - print(f"Error generating coverage report: {e}") - - def run_all(self): - """Run all tests""" - print("Federation Manager - Comprehensive Test Suite") - print("Dual Role Architecture Validation") - print(f"Python version: {sys.version}") - print(f"Test directory: {os.path.dirname(__file__)}") - - if self.use_coverage: - print("Code coverage: ENABLED") - - # Discover and run integration tests - integration_suite = self.discover_integration_tests() - self.run_suite("Integration Tests", integration_suite) - - # Print summary - return self.print_summary() - - -def main(): - """Main entry point""" - parser = argparse.ArgumentParser( - description="Run Federation Manager test suites with dual role validation", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -Test Suite: - integration - Dual role integration tests (Partner OP & Originating OP) - -Dual Role Testing: -The integration tests validate both operational modes by sending requests: - • Without X-Internal header → tf_adapter (Partner OP mode) - • With X-Internal + X-Partner-API-Root → fm_adapter (Originating OP mode) - -This ensures complete validation of the dual role architecture across -the entire stack: API → Adapter → Client → External System - -Examples: - python run_all_tests.py # Run all integration tests - python run_all_tests.py --verbose # Run with verbose output - python run_all_tests.py --coverage # Run with coverage report - """ - ) - - parser.add_argument( - '--verbose', '-v', - action='store_true', - help='Enable verbose test output' - ) - - parser.add_argument( - '--coverage', '-c', - action='store_true', - help='Generate code coverage report' - ) - - args = parser.parse_args() - - # Set verbosity level - verbosity = 2 if args.verbose else 1 - - # Add current directory to Python path - current_dir = os.path.dirname(os.path.abspath(__file__)) - parent_dir = os.path.dirname(current_dir) - sys.path.insert(0, parent_dir) - - # Create and run test manager - test_manager = TestSuiteManager(verbosity=verbosity, use_coverage=args.coverage) - success = test_manager.run_all() - - # Exit with appropriate code - sys.exit(0 if success else 1) - - -if __name__ == '__main__': - main() diff --git a/src/test/test_application_deployment_management.py b/src/test/test_application_deployment_management.py deleted file mode 100644 index 46ec42b703762dc40bffae1ec9072aaf33dc9cbe..0000000000000000000000000000000000000000 --- a/src/test/test_application_deployment_management.py +++ /dev/null @@ -1,554 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import -import time -from test import BaseTestCase -from clients import srm - - -class TestApplicationDeploymentManagementController(BaseTestCase): - """ApplicationDeploymentManagementController integration test stubs""" - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.token = "" - BaseTestCase.instances_partner = [] - BaseTestCase.instances_originating = [] - BaseTestCase.zone_partner = "" - BaseTestCase.zone_originating = "" - BaseTestCase.flavour_partner = "" - BaseTestCase.flavour_originating = "" - - def run(self, result=None): - """ Stop after first error """ - try: - # Check if there is connection with Edge Cloud Platform. Otherwise stop the test - try: - srm.get_zones() - except Exception: - self.skipTest("Edge Cloud Platform connection not available") - - # Check if there is connection with keycloak. Otherwise stop the test - try: - BaseTestCase.token = self.get_access_token() - except Exception: - self.skipTest("Keycloak connection not available") - - # Check if there is connection with FM. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'partner_op') - except Exception: - self.skipTest("FM Partner OP connection not available") - - # Check if there is connection with FM Originating OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'originating_op') - except Exception: - self.skipTest("FM Originating OP connection not available") - - super(TestApplicationDeploymentManagementController, self).run(result) - except Exception as error: - raise Exception(f"Test failed. Reason: {error}") - - def test_00_setup(self): - """Setup federation contexts for both Partner OP and Originating OP roles""" - self.cleanup_fm_test_state() - self.cleanup_ecp_test_state() - self.cleanup_remote_partner_test_state(BaseTestCase.token) - - try: - # Create federation context for Partner OP role - BaseTestCase.federation_context_id_partner = self.post_federation(BaseTestCase.token, 'partner_op') - - # Create federation context for Originating OP role - BaseTestCase.federation_context_id_originating = self.post_federation(BaseTestCase.token, 'originating_op') - - # Get zone id from Edge Cloud Platform for Partner OP role - BaseTestCase.zone_partner = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_partner, - BaseTestCase.token, 'partner_op') - if BaseTestCase.zone_partner == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Get zone id from Edge Cloud Platform for Originating OP role - BaseTestCase.zone_originating = self.get_zone_from_partner_details( - BaseTestCase.federation_context_id_originating, - BaseTestCase.token, 'originating_op') - if BaseTestCase.zone_originating == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Setup zones for both roles - self.post_availability_zones(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, - BaseTestCase.token, 'partner_op') - self.post_availability_zones(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Get flavour from zone for Partner OP role - BaseTestCase.flavour_partner = self.get_flavour_from_zone_details( - BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, BaseTestCase.token, - 'partner_op') - if BaseTestCase.flavour_partner == "": - raise Exception("Test Failed. Unable to retrieve flavour from Edge Cloud Platform") - - # Get flavour from zone for Originating OP role - BaseTestCase.flavour_originating = self.get_flavour_from_zone_details( - BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, BaseTestCase.token, - 'originating_op') - if BaseTestCase.flavour_originating == "": - raise Exception("Test Failed. Unable to retrieve flavour from Edge Cloud Platform") - - # Create artefacts for both roles with different app providers - self.post_artefact(BaseTestCase.federation_context_id_partner, self.artefact_id_pop, self.artefact_name_pop, - self.artefact_repo_pop, BaseTestCase.token, 'partner_op') - # Reuse a known-good public Helm chart for originating deployment validation. - self.post_artefact(BaseTestCase.federation_context_id_originating, self.artefact_id_oop, - self.deployable_artefact_name, self.deployable_artefact_repo, BaseTestCase.token, - 'originating_op') - - # Create application onboarding for both roles with different app configurations - self.post_onboarding(BaseTestCase.federation_context_id_partner, self.app_id_pop, BaseTestCase.zone_partner, - self.artefact_id_pop, BaseTestCase.token, 'partner_op') - self.post_onboarding(BaseTestCase.federation_context_id_originating, self.app_id_oop, BaseTestCase.zone_originating, - self.artefact_id_oop, BaseTestCase.token, 'originating_op') - except Exception as error: - raise Exception(f"Test setup failed. Reason: {error}") - - def test_01_install_app(self): - """Test case for install_app in both Partner OP and Originating OP modes""" - - def test_install_app(role): - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - app_id = self.app_id_pop - zone = BaseTestCase.zone_partner - flavour = BaseTestCase.flavour_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - app_id = self.app_id_oop - zone = BaseTestCase.zone_originating - flavour = BaseTestCase.flavour_originating - - body = { - "appId": app_id, - "appVersion": "0.1.0", - "appProviderId": self.app_provider, - "zoneInfo": { - "zoneId": zone, - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - if response.status_code == 202: - BaseTestCase.instances_originating.append(response.json()) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - if response.status_code == 202: - BaseTestCase.instances_partner.append(response.json()) - - return response - - # Test both roles with different app configurations - partner_response = test_install_app('partner_op') - originating_response = test_install_app('originating_op') - - # Both should succeed (202) or have consistent behavior - self.assertIn(partner_response.status_code, [202, 422]) - self.assertIn(originating_response.status_code, [202, 422]) - - def test_02_install_duplicate_app(self): - """Test case for install_app when deployed app already exists - dual role""" - - def test_instance_exists(role): - # Use different app configurations for each role (same as test_01) - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - app_id = self.app_id_pop - zone = BaseTestCase.zone_partner - flavour = BaseTestCase.flavour_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - app_id = self.app_id_oop - zone = BaseTestCase.zone_originating - flavour = BaseTestCase.flavour_originating - - body = { - "appId": app_id, - "appVersion": "0.1.0", - "appProviderId": self.app_provider, - "zoneInfo": { - "zoneId": zone, - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles with different app configurations - partner_response = test_instance_exists('partner_op') - originating_response = test_instance_exists('originating_op') - - # Both should reject duplicate version - self.assertIn(partner_response.status_code, [409, 422]) - self.assertIn(originating_response.status_code, [409, 422]) - - def test_03_install_app_invalid_federation(self): - """Test case for install_app with invalid federation ID - dual role""" - - def test_invalid_federation(role): - # Use different app configurations for each role - if role == 'partner_op': - app_id = self.app_id_pop - zone = BaseTestCase.zone_partner - flavour = BaseTestCase.flavour_partner - else: - app_id = self.app_id_oop - zone = BaseTestCase.zone_originating - flavour = BaseTestCase.flavour_originating - - body = { - "appId": app_id, - "appVersion": "0.1.1", - "appProviderId": self.app_provider, - "zoneInfo": { - "zoneId": zone, - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/invalid-federation-id/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_federation('partner_op') - originating_response = test_invalid_federation('originating_op') - - # Both should return error for invalid federation - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_04_get_all_app_instances(self): - """Test case for get_all_app_instances - dual role""" - - def test_get_instances(role): - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - app_id = self.app_id_pop - else: - federation_id = BaseTestCase.federation_context_id_originating - app_id = self.app_id_oop - - url = f"http://{self.base_url}/{federation_id}/application/lcm/app/{app_id}/appProvider/{self.app_provider}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_instances('partner_op') - originating_response = test_get_instances('originating_op') - - # Both should succeed or fail consistently - self.assertIn(partner_response.status_code, [200, 404, 422]) - self.assertIn(originating_response.status_code, [200, 404, 422]) - - def test_05_get_app_instance_details(self): - """Test case for get_app_instance_details - dual role""" - - def test_get_details(role): - - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - instances = BaseTestCase.instances_partner - app_id = self.app_id_pop - else: - federation_id = BaseTestCase.federation_context_id_originating - instances = BaseTestCase.instances_originating - app_id = self.app_id_oop - - if not instances: - return None # No instances to test - - instance = instances[0] - instance_id = instance.get("appInstIdentifier") - zone_id = instance.get("zoneId") - - url = f"http://{self.base_url}/{federation_id}/application/lcm/app/{app_id}/instance/{instance_id}/zone/{zone_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_details('partner_op') - originating_response = test_get_details('originating_op') - - # Check responses if instances exist - if partner_response: - self.assertIn(partner_response.status_code, [200, 404, 422]) - if originating_response: - self.assertIn(originating_response.status_code, [200, 404, 422]) - - def test_06_remove_app(self): - """Test case for remove_app - dual role""" - - def test_remove_app(role): - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - instances = BaseTestCase.instances_partner - app_id = self.app_id_pop - else: - federation_id = BaseTestCase.federation_context_id_originating - instances = BaseTestCase.instances_originating - app_id = self.app_id_oop - - if not instances: - return None # No instances to remove - - instance = instances[0] - instance_id = instance.get("appInstIdentifier") - zone_id = instance.get("zoneId") - - url = f"http://{self.base_url}/{federation_id}/application/lcm/app/{app_id}/instance/{instance_id}/zone/{zone_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("DELETE", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_remove_app('partner_op') - originating_response = test_remove_app('originating_op') - - # Check responses if instances exist - if partner_response: - self.assertEqual(partner_response.status_code, 200) - if originating_response: - self.assertEqual(originating_response.status_code, 200) - - def test_07_error_scenarios(self): - """Test various error scenarios in dual role mode""" - - def test_invalid_app_id(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - flavour = BaseTestCase.flavour_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - flavour = BaseTestCase.flavour_originating - - body = { - "appId": "invalid_app_id", - "appVersion": "0.1.1", - "appProviderId": self.app_provider, - "zoneInfo": { - "zoneId": zone, - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test invalid app ID for both roles - partner_response = test_invalid_app_id('partner_op') - originating_response = test_invalid_app_id('originating_op') - - # Both should fail with consistent error codes - self.assertIn(partner_response.status_code, [404, 422]) - self.assertIn(originating_response.status_code, [404, 422]) - - def test_08_invalid_zone(self): - """Test deployment with invalid zone - dual role""" - - def test_invalid_zone(role): - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - app_id = self.app_id_pop - flavour = BaseTestCase.flavour_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - app_id = self.app_id_oop - flavour = BaseTestCase.flavour_originating - - body = { - "appId": app_id, - "appVersion": "0.1.2", - "appProviderId": self.app_provider, - "zoneInfo": { - "zoneId": "invalid-zone-id", - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_zone('partner_op') - originating_response = test_invalid_zone('originating_op') - - # Both should fail due to invalid zone - self.assertEqual(partner_response.status_code, 422) - self.assertEqual(originating_response.status_code, 422) - - def test_09_invalid_provider(self): - """Test deployment with invalid provider - dual role""" - - def test_invalid_provider(role): - # Use different app configurations for each role - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - app_id = self.app_id_pop - zone = BaseTestCase.zone_partner - flavour = BaseTestCase.flavour_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - app_id = self.app_id_oop - zone = BaseTestCase.zone_originating - flavour = BaseTestCase.flavour_originating - - body = { - "appId": app_id, - "appVersion": "0.1.3", - "appProviderId": "invalid_provider", - "zoneInfo": { - "zoneId": zone, - "flavourId": flavour, - "resourceConsumption": "RESERVED_RES_AVOID", - "resPool": "fdfddfdfdffdfdfd" - }, - "appInstCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/lcm" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_provider('partner_op') - originating_response = test_invalid_provider('originating_op') - - # Both should fail due to invalid provider - self.assertIn(partner_response.status_code, [404, 422]) - self.assertIn(originating_response.status_code, [404, 422]) - - def test_99_cleanup(self): - """Cleanup resources for both roles""" - try: - # Delete instances for both roles - for instance in BaseTestCase.instances_partner: - self.delete_deployments(BaseTestCase.federation_context_id_partner, self.app_id_pop, - instance.get("appInstIdentifier"), instance.get("zoneId"), - BaseTestCase.token, 'partner_op') - - for instance in BaseTestCase.instances_originating: - self.delete_deployments(BaseTestCase.federation_context_id_originating, self.app_id_oop, - instance.get("appInstIdentifier"), instance.get("zoneId"), - BaseTestCase.token, 'originating_op') - - # Delete onboarding for both roles - self.delete_onboarding(BaseTestCase.federation_context_id_partner, self.app_id_pop, BaseTestCase.token, - 'partner_op') - self.delete_onboarding(BaseTestCase.federation_context_id_originating, self.app_id_oop, BaseTestCase.token, - 'originating_op') - - # Delete artefacts for both roles - self.delete_artefact(BaseTestCase.federation_context_id_partner, self.artefact_id_pop, BaseTestCase.token, - 'partner_op') - self.delete_artefact(BaseTestCase.federation_context_id_originating, self.artefact_id_oop, BaseTestCase.token, - 'originating_op') - - # Delete zones for both roles - self.delete_zone(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, BaseTestCase.token, - 'partner_op') - self.delete_zone(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Delete federations for both roles - self.delete_federation(BaseTestCase.federation_context_id_partner, BaseTestCase.token, 'partner_op') - self.delete_federation(BaseTestCase.federation_context_id_originating, BaseTestCase.token, 'originating_op') - - except Exception as error: - print(f"Cleanup failed: {error}") - - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/src/test/test_application_onboarding_management.py b/src/test/test_application_onboarding_management.py deleted file mode 100644 index 8e4f54b14fa37bea5d3fabee373f61501d9649df..0000000000000000000000000000000000000000 --- a/src/test/test_application_onboarding_management.py +++ /dev/null @@ -1,524 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import - -from test import BaseTestCase -from clients import srm -import unittest - - -class TestApplicationOnboardingManagementController(BaseTestCase): - """ApplicationOnboardingManagementController integration test stubs""" - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.token = "" - BaseTestCase.zone_partner = "" - BaseTestCase.zone_originating = "" - - def run(self, result=None): - """ Stop after first error """ - try: - # Check if there is connection with Edge Cloud Platform. Otherwise stop the test - try: - srm.get_zones() - except Exception: - self.skipTest("Edge Cloud Platform connection not available") - - # Check if there is connection with keycloak. Otherwise stop the test - try: - BaseTestCase.token = self.get_access_token() - except Exception: - self.skipTest("Keycloak connection not available") - - # Check if there is connection with FM. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'partner_op') - except Exception: - self.skipTest("FM Partner OP connection not available") - - # Check if there is connection with FM Originating OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'originating_op') - except Exception: - self.skipTest("FM Originating OP connection not available") - - super(TestApplicationOnboardingManagementController, self).run(result) - except Exception as error: - raise Exception(f"Test failed. Reason: {error}") - - def test_00_setup(self): - """Setup federation contexts for both Partner OP and Originating OP roles""" - self.cleanup_fm_test_state() - self.cleanup_ecp_test_state() - self.cleanup_remote_partner_test_state(BaseTestCase.token) - - try: - # Create federation context for Partner OP role - BaseTestCase.federation_context_id_partner = self.post_federation(BaseTestCase.token, 'partner_op') - - # Create federation context for Originating OP role - BaseTestCase.federation_context_id_originating = self.post_federation(BaseTestCase.token, 'originating_op') - - # Get zone id from Edge Cloud Platform for Partner OP role - BaseTestCase.zone_partner = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_partner, - BaseTestCase.token, 'partner_op') - if BaseTestCase.zone_partner == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Get zone id from Edge Cloud Platform for Originating OP role - BaseTestCase.zone_originating = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_originating, - BaseTestCase.token, 'originating_op') - if BaseTestCase.zone_originating == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Assign Zones to both federation contexts - self.post_availability_zones(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, - BaseTestCase.token, 'partner_op') - self.post_availability_zones(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Create artefacts for both federation contexts - self.post_artefact(BaseTestCase.federation_context_id_partner, self.artefact_id_pop, self.artefact_name_pop, - self.artefact_repo_pop, BaseTestCase.token, 'partner_op') - self.post_artefact(BaseTestCase.federation_context_id_originating, self.artefact_id_oop, - self.artefact_name_oop, self.artefact_repo_oop, BaseTestCase.token, 'originating_op') - - # Get token from keycloak - BaseTestCase.token = self.get_access_token() - except Exception as error: - raise Exception(f"Test setup failed. Reason: {error}") - - def test_01_post_onboarding(self): - """Test case for post_onboarding in both Partner OP and Originating OP modes""" - - def test_post_onboarding(role, app_id, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - body = { - "appId": app_id, - "appProviderId": self.app_provider, - "appDeploymentZones": [ - zone - ], - "appMetaData": { - "appName": "dsdsdsdssdssdsdssd", - "version": "string", - "appDescription": "sdssdssdsdssdsdsdss", - "mobilitySupport": False, - "accessToken": "sdsddssddssdsssdsdsdsdsdsdsdsddsddsdsdsdsdsd", - "category": "IOT" - }, - "appQoSProfile": { - "latencyConstraints": "NONE", - "bandwidthRequired": 1, - "multiUserClients": "APP_TYPE_SINGLE_USER", - "noOfUsersPerAppInst": 1, - "appProvisioning": True - }, - "appComponentSpecs": [ - { - "serviceNameNB": "dsdsdsdsdsdsdsdsdsdds", - "serviceNameEW": "sdsdsdsdddsssdsdssdsd", - "componentName": "sdssssssssdsdsdsdsdss", - "artefactId": artefact_id - } - ], - "appStatusCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_post_onboarding('partner_op', self.app_id_pop, self.artefact_id_pop) - originating_response = test_post_onboarding('originating_op', self.app_id_oop, self.artefact_id_oop) - - # Both should succeed with 202 (accepted) - self.assertEqual(partner_response.status_code, 202) - self.assertEqual(originating_response.status_code, 202) - - def test_02_post_onboarding_duplicate(self): - """Test case for post_onboarding with duplicate app ID - dual role""" - - def test_duplicate_onboarding(role, app_id, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - # Same body as test_01 - should conflict - body = { - "appId": app_id, - "appProviderId": self.app_provider, - "appDeploymentZones": [ - zone - ], - "appMetaData": { - "appName": "duplicate_app", - "version": "string", - "appDescription": "duplicate description", - "mobilitySupport": False, - "accessToken": "sdsddssddssdsssdsdsdsdsdsdsdsddsddsdsdsdsdsd", - "category": "IOT" - }, - "appQoSProfile": { - "latencyConstraints": "NONE", - "bandwidthRequired": 1, - "multiUserClients": "APP_TYPE_SINGLE_USER", - "noOfUsersPerAppInst": 1, - "appProvisioning": True - }, - "appComponentSpecs": [ - { - "serviceNameNB": "duplicate_service", - "serviceNameEW": "duplicate_service_ew", - "componentName": "duplicate_component", - "artefactId": artefact_id - } - ], - "appStatusCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_duplicate_onboarding('partner_op', self.app_id_pop, self.artefact_id_pop) - originating_response = test_duplicate_onboarding('originating_op', self.app_id_oop, self.artefact_id_oop) - - # Both should reject duplicate with 409 or 422 - self.assertIn(partner_response.status_code, [409, 422]) - self.assertIn(originating_response.status_code, [409, 422]) - - def test_03_onboarding_invalid_federation(self): - """Test case for onboarding with invalid federation ID - dual role""" - - def test_invalid_federation(role, artefact_id): - if role == 'partner_op': - zone = BaseTestCase.zone_partner - else: - zone = BaseTestCase.zone_originating - - body = { - "appId": "test_app_invalid", - "appProviderId": self.app_provider, - "appDeploymentZones": [zone], - "appMetaData": { - "appName": "test_app_id", - "version": "V1", - "accessToken": "AAdfre567bngfgrgrrgrrrgredwwBBeeer3e" - }, - "appQoSProfile": { - "latencyConstraints": "NONE" - }, - "appComponentSpecs": [ - { - "artefactId": artefact_id - } - ], - "appStatusCallbackLink": "string" - } - - url = f"http://{self.base_url}/invalid-federation-id/application/onboarding" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_federation('partner_op', self.artefact_id_pop) - originating_response = test_invalid_federation('originating_op', self.artefact_id_oop) - - # Both should return error for invalid federation - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_04_onboarding_invalid_artefact(self): - """Test case for onboarding with invalid artefact ID - dual role""" - - def test_invalid_artefact(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - body = { - "appId": "test_app_invalid_artefact", - "appProviderId": self.app_provider, - "appDeploymentZones": [zone], - "appMetaData": { - "appName": "invalid_artefact_test", - "version": "1.0.0" - }, - "appComponentSpecs": [{ - "artefactId": "invalid_artefact_id", - "componentName": "test_component" - }] - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_artefact('partner_op') - originating_response = test_invalid_artefact('originating_op') - - # Both should return error for invalid artefact - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_05_onboarding_invalid_zone(self): - """Test case for onboarding with invalid zone - dual role""" - - def test_invalid_zone(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "appId": "test_app_invalid_zone", - "appProviderId": self.app_provider, - "appDeploymentZones": ["invalid-zone-id"], - "appMetaData": { - "appName": "invalid_zone_test", - "version": "1.0.0", - "accessToken": "AAdfre567bngfgrgrrgrrrgredwwBBeeer3e" - }, - "appQoSProfile": { - "latencyConstraints": "NONE" - }, - "appComponentSpecs": [ - { - "artefactId": artefact_id - } - ], - "appStatusCallbackLink": "string" - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_zone('partner_op', self.artefact_id_pop) - originating_response = test_invalid_zone('originating_op', self.artefact_id_oop) - - # Both should return error for invalid zone - self.assertIn(partner_response.status_code, [404, 422]) - self.assertIn(originating_response.status_code, [404, 422]) - - def test_06_get_onboarding(self): - """Test case for get_onboarding in both Partner OP and Originating OP modes""" - - def test_get_onboarding(role): - if role == 'originating_op': - federation_id = BaseTestCase.federation_context_id_originating - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/{self.app_id_oop}" - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - federation_id = BaseTestCase.federation_context_id_partner - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/{self.app_id_pop}" - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_onboarding('partner_op') - originating_response = test_get_onboarding('originating_op') - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - # Verify response content contains app ID - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertEqual(partner_data.get("appId"), self.app_id_pop) - self.assertEqual(originating_data.get("appId"), self.app_id_oop) - - def test_07_get_nonexistent_onboarding(self): - """Test case for getting non-existent onboarding - dual role""" - - def test_get_nonexistent(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/nonexistent_app_id" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_nonexistent('partner_op') - originating_response = test_get_nonexistent('originating_op') - - # Both should return 404 for non-existent app - self.assertEqual(partner_response.status_code, 404) - self.assertEqual(originating_response.status_code, 404) - - def test_08_update_onboarding(self): - """Test case for update_onboarding in both Partner OP and Originating OP modes""" - - def test_update_onboarding(role, artefact_id, app_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "appUpdQoSProfile": { - "latencyConstraints": "LOW", - "bandwidthRequired": 100, - "mobilitySupport": True, - "multiUserClients": "APP_TYPE_MULTI_USER", - "noOfUsersPerAppInst": 10, - "appProvisioning": True - }, - "appComponentSpecs": [ - { - "serviceNameNB": "updated_service_nb", - "serviceNameEW": "updated_service_ew", - "componentName": "updated_component", - "artefactId": artefact_id - } - ] - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/{app_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_onboarding('partner_op', self.artefact_id_pop, self.app_id_pop) - originating_response = test_update_onboarding('originating_op', self.artefact_id_oop, self.app_id_oop) - - # Both should succeed with 202 (accepted) - self.assertEqual(partner_response.status_code, 202) - self.assertEqual(originating_response.status_code, 202) - - def test_09_update_nonexistent_onboarding(self): - """Test case for updating non-existent onboarding - dual role""" - - def test_update_nonexistent(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "appComponentSpecs": [{ - "serviceNameNB": "updated_service", - "artefactId": artefact_id - }] - } - - url = f"http://{self.base_url}/{federation_id}/application/onboarding/app/nonexistent_app_id" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_nonexistent('partner_op', self.artefact_id_pop) - originating_response = test_update_nonexistent('originating_op', self.artefact_id_oop) - - # Both should return 404 for non-existent app - self.assertEqual(partner_response.status_code, 404) - self.assertEqual(originating_response.status_code, 404) - - def test_99_cleanup(self): - """Cleanup resources for both roles""" - try: - # Delete onboarding for both roles - self.delete_onboarding(BaseTestCase.federation_context_id_partner, self.app_id_pop, BaseTestCase.token, - 'partner_op') - self.delete_onboarding(BaseTestCase.federation_context_id_originating, self.app_id_oop, BaseTestCase.token, - 'originating_op') - - # Delete artefacts for both roles - self.delete_artefact(BaseTestCase.federation_context_id_partner, self.artefact_id_pop, BaseTestCase.token, - 'partner_op') - self.delete_artefact(BaseTestCase.federation_context_id_originating, self.artefact_id_oop, - BaseTestCase.token, 'originating_op') - - # Delete zones for both roles - self.delete_zone(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, BaseTestCase.token, - 'partner_op') - self.delete_zone(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Delete federations for both roles - self.delete_federation(BaseTestCase.federation_context_id_partner, BaseTestCase.token, 'partner_op') - self.delete_federation(BaseTestCase.federation_context_id_originating, BaseTestCase.token, 'originating_op') - - except Exception as error: - print(f"Cleanup failed: {error}") - - -if __name__ == '__main__': - unittest.main() diff --git a/src/test/test_artefact_management.py b/src/test/test_artefact_management.py deleted file mode 100644 index dfcfdfb9efa04e6fe1c29322bf40090443c35212..0000000000000000000000000000000000000000 --- a/src/test/test_artefact_management.py +++ /dev/null @@ -1,526 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import - -from test import BaseTestCase -from clients import srm -import util - - -class TestArtefactManagementController(BaseTestCase): - """ArtefactManagementController integration test stubs""" - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.token = "" - BaseTestCase.zone_partner = "" - BaseTestCase.zone_originating = "" - BaseTestCase.artefact_public = "3fa85f64-5717-4562-b3fc-2c963f66afa7" - BaseTestCase.artefact_private = "3fa85f64-5717-4562-b3fc-2c963f66afa8" - BaseTestCase.artefact_name_private = "orchestrator" - - def run(self, result=None): - """ Stop after first error """ - try: - # Check if there is connection with Edge Cloud Platform. Otherwise stop the test - try: - srm.get_zones() - except Exception: - self.skipTest("Edge Cloud Platform connection not available") - - # Check if there is connection with keycloak. Otherwise stop the test - try: - BaseTestCase.token = self.get_access_token() - except Exception: - self.skipTest("Keycloak connection not available") - - # Check if there is connection with FM. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'partner_op') - except Exception: - self.skipTest("FM Partner OP connection not available") - - # Check if there is connection with FM Originating OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'originating_op') - except Exception: - self.skipTest("FM Originating OP connection not available") - - super(TestArtefactManagementController, self).run(result) - except Exception as error: - raise Exception(f"Test failed. Reason: {error}") - - def test_00_setup(self): - """Setup federation contexts for both Partner OP and Originating OP roles""" - - # Check if the artefacts id of this test have been created previously at Edge Cloud Platform and remains there due - # to a possible issue of the same test - try: - srm.delete_artefact(BaseTestCase.artefact_public) - except Exception: - pass - - try: - srm.delete_artefact(BaseTestCase.artefact_private) - except Exception: - pass - - try: - # Create federation context for Partner OP role - BaseTestCase.federation_context_id_partner = self.post_federation(BaseTestCase.token, 'partner_op') - - # Create federation context for Originating OP role - BaseTestCase.federation_context_id_originating = self.post_federation(BaseTestCase.token, 'originating_op') - - # Get zone id from Edge Cloud Platform for Partner OP role - BaseTestCase.zone_partner = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_partner, - BaseTestCase.token, 'partner_op') - if BaseTestCase.zone_partner == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Get zone id from Edge Cloud Platform for Originating OP role - BaseTestCase.zone_originating = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_originating, - BaseTestCase.token, 'originating_op') - if BaseTestCase.zone_originating == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Assign Zones to both federation contexts - self.post_availability_zones(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, - BaseTestCase.token, 'partner_op') - self.post_availability_zones(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - except Exception as error: - raise Exception(f"Test setup failed. Reason: {error}") - - def test_01_upload_public_artefact(self): - """Test case for uploading public artefact - dual role""" - - def test_upload_public(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "artefactId": artefact_id, - "appProviderId": self.app_provider, - "artefactName": "ollama", - "artefactVersionInfo": "1.0.0", - "artefactDescription": "Public artefact for dual role testing", - "artefactVirtType": "CONTAINER_TYPE", - "artefactFileName": "public_artefact.tar", - "artefactFileFormat": "TAR", - "artefactDescriptorType": "HELM", - "repoType": util.RepoType.PUBLIC.value, - "artefactRepoLocation": { - "repoURL": "https://otwld.github.io/ollama-helm/", - "userName": "", - "password": "", - "token": "" - }, - "componentSpec": [ - { - "componentName": f"public_component_{role}", - "images": ["nginx:latest"], - "numOfInstances": 1, - "restartPolicy": "RESTART_POLICY_ALWAYS", - "computeResourceProfile": { - "cpuArchType": "ISA_X86_64", - "numCPU": "1", - "memory": 1024, - "diskStorage": 10240 - } - } - ] - } - - url = f"http://{self.base_url}/{federation_id}/artefact" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_upload_public('partner_op', BaseTestCase.artefact_public) - originating_response = test_upload_public('originating_op', BaseTestCase.artefact_public) - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - def test_02_upload_private_artefact(self): - """Test case for uploading private artefact - dual role""" - - def test_upload_private(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "artefactId": artefact_id, - "appProviderId": self.app_provider, - "artefactName": BaseTestCase.artefact_name_private, - "artefactVersionInfo": "1.0.0", - "artefactDescription": "string", - "artefactVirtType": "VM_TYPE", - "artefactFileFormat": "WINZIP", - "artefactDescriptorType": "HELM", - "repoType": util.RepoType.PRIVATE.value, - "artefactRepoLocation": { - "repoURL": "https://gitlab.i2cat.net/api/v4/projects/1458/packages/helm/stable", - "userName": "i2edge", - "password": "3wZztr7cLvypoCCCdwJt", - "token": "" - }, - "artefactFile": "", - "componentSpec": [ - { - "componentName": "string", - "images": [ - "3fa85f64-5717-4562-b3fc-2c963f66afa6" - ], - "numOfInstances": 0, - "restartPolicy": "RESTART_POLICY_ALWAYS", - "commandLineParams": { - "command": [ - "string" - ], - "commandArgs": [ - "string" - ] - }, - "exposedInterfaces": [ - { - "interfaceId": "a123456789012345678901234567890b", - "commProtocol": "TCP", - "commPort": 1, - "visibilityType": "VISIBILITY_EXTERNAL", - "network": "a123456789012345678901234567890b", - "InterfaceName": "abcd" - } - ], - "computeResourceProfile": { - "cpuArchType": "ISA_X86_64", - "numCPU": "1", - "memory": 0, - "diskStorage": 0, - "gpu": [ - { - "gpuVendorType": "GPU_PROVIDER_NVIDIA", - "gpuModeName": "string", - "gpuMemory": 0, - "numGPU": 0 - } - ], - "vpu": 0, - "fpga": 0, - "hugepages": [ - { - "pageSize": "2MB", - "number": 0 - } - ], - "cpuExclusivity": True - }, - "compEnvParams": [ - { - "envVarName": "a123456789012345678901234567890b", - "envValueType": "USER_DEFINED", - "envVarValue": "a123456789012345678901234567890b", - "envVarSrc": "string" - } - ], - "deploymentConfig": { - "configType": "DOCKER_COMPOSE", - "contents": "string" - }, - "persistentVolumes": [ - { - "volumeSize": "10Gi", - "volumeMountPath": "string", - "volumeName": "string", - "ephemeralType": False, - "accessMode": "RW", - "sharingPolicy": "EXCLUSIVE" - } - ] - } - ] - } - - url = f"http://{self.base_url}/{federation_id}/artefact" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_upload_private('partner_op', BaseTestCase.artefact_private) - originating_response = test_upload_private('originating_op', BaseTestCase.artefact_private) - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - def test_03_get_artefact(self): - """Test case for get_artefact in both Partner OP and Originating OP modes""" - - def test_get_artefact(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - url = f"http://{self.base_url}/{federation_id}/artefact/{artefact_id}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test get artefact for both roles and all artefact types - artefacts_to_test = [ - BaseTestCase.artefact_public, - BaseTestCase.artefact_private - ] - - for artefact_id in artefacts_to_test: - partner_response = test_get_artefact('partner_op', artefact_id) - originating_response = test_get_artefact('originating_op', artefact_id) - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200, f"Failed to get artefact {artefact_id} for partner_op") - self.assertEqual(originating_response.status_code, 200, f"Failed to get artefact {artefact_id} for originating_op") - - # Verify response contains artefact ID - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertEqual(partner_data.get("artefactId"), artefact_id) - self.assertEqual(originating_data.get("artefactId"), artefact_id) - - def test_04_upload_duplicate_artefact(self): - """Test case for uploading duplicate artefact - dual role""" - - def test_duplicate_upload(role, artefact_id): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - # Same artefact ID as already uploaded - body = { - "artefactId": artefact_id, - "appProviderId": self.app_provider, - "artefactName": "ollama", - "artefactVersionInfo": "1.0.0", - "artefactDescription": "Public artefact for dual role testing", - "artefactVirtType": "CONTAINER_TYPE", - "artefactFileName": "public_artefact.tar", - "artefactFileFormat": "TAR", - "artefactDescriptorType": "HELM", - "repoType": util.RepoType.PUBLIC.value, - "artefactRepoLocation": { - "repoURL": "https://otwld.github.io/ollama-helm/", - "userName": "", - "password": "", - "token": "" - }, - "componentSpec": [ - { - "componentName": f"public_component_{role}", - "images": ["nginx:latest"], - "numOfInstances": 1, - "restartPolicy": "RESTART_POLICY_ALWAYS", - "computeResourceProfile": { - "cpuArchType": "ISA_X86_64", - "numCPU": "1", - "memory": 1024, - "diskStorage": 10240 - } - } - ] - } - - url = f"http://{self.base_url}/{federation_id}/artefact" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test duplicate upload for both roles - partner_response = test_duplicate_upload('partner_op', BaseTestCase.artefact_public) - originating_response = test_duplicate_upload('originating_op', BaseTestCase.artefact_public) - - # Both should reject duplicate with 409 or 422 - self.assertIn(partner_response.status_code, [409, 422]) - self.assertIn(originating_response.status_code, [409, 422]) - - def test_05_upload_artefact_invalid_federation(self): - """Test case for uploading artefact with invalid federation ID - dual role""" - - def test_invalid_federation(role): - - body = { - "artefactId": BaseTestCase.artefact_public, - "appProviderId": self.app_provider, - "artefactName": "ollama", - "artefactVersionInfo": "1.0.0", - "artefactDescription": "Public artefact for dual role testing", - "artefactVirtType": "CONTAINER_TYPE", - "artefactFileName": "public_artefact.tar", - "artefactFileFormat": "TAR", - "artefactDescriptorType": "HELM", - "repoType": util.RepoType.PUBLIC.value, - "artefactRepoLocation": { - "repoURL": "https://otwld.github.io/ollama-helm/", - "userName": "", - "password": "", - "token": "" - }, - "componentSpec": [ - { - "componentName": f"public_component_{role}", - "images": ["nginx:latest"], - "numOfInstances": 1, - "restartPolicy": "RESTART_POLICY_ALWAYS", - "computeResourceProfile": { - "cpuArchType": "ISA_X86_64", - "numCPU": "1", - "memory": 1024, - "diskStorage": 10240 - } - } - ] - } - - url = f"http://{self.base_url}/invalid-federation-id/artefact" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_federation('partner_op') - originating_response = test_invalid_federation('originating_op') - - # Both should return error for invalid federation - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_06_get_nonexistent_artefact(self): - """Test case for getting non-existent artefact - dual role""" - - def test_get_nonexistent(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - url = f"http://{self.base_url}/{federation_id}/artefact/nonexistent_artefact_id" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_nonexistent('partner_op') - originating_response = test_get_nonexistent('originating_op') - - # Both should return 404 for non-existent artefact - self.assertEqual(partner_response.status_code, 404) - self.assertEqual(originating_response.status_code, 404) - - def test_07_upload_artefact_invalid_body(self): - """Test case for uploading artefact with invalid body - dual role""" - - def test_invalid_body(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - # Missing required fields - body = { - "invalidField": "invalid_value" - } - - url = f"http://{self.base_url}/{federation_id}/artefact" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_body('partner_op') - originating_response = test_invalid_body('originating_op') - - # Both should return validation error - self.assertIn(partner_response.status_code, [400, 422]) - self.assertIn(originating_response.status_code, [400, 422]) - - def test_99_cleanup(self): - """Cleanup resources for both roles""" - try: - # Delete artefacts for both roles - artefacts_to_delete = [ - BaseTestCase.artefact_public, - BaseTestCase.artefact_private - ] - - for artefact_id in artefacts_to_delete: - self.delete_artefact(BaseTestCase.federation_context_id_partner, artefact_id, BaseTestCase.token, 'partner_op') - self.delete_artefact(BaseTestCase.federation_context_id_originating, artefact_id, BaseTestCase.token, 'originating_op') - - # Delete zones for both roles - self.delete_zone(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, BaseTestCase.token, - 'partner_op') - self.delete_zone(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Delete federations for both roles - self.delete_federation(BaseTestCase.federation_context_id_partner, BaseTestCase.token, 'partner_op') - self.delete_federation(BaseTestCase.federation_context_id_originating, BaseTestCase.token, 'originating_op') - - except Exception as error: - print(f"Cleanup failed: {error}") - - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/src/test/test_availability_zone_info_synchronization.py b/src/test/test_availability_zone_info_synchronization.py deleted file mode 100644 index ec239d6ed2768a633258f17c78bd84f4c5382592..0000000000000000000000000000000000000000 --- a/src/test/test_availability_zone_info_synchronization.py +++ /dev/null @@ -1,431 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import - -from test import BaseTestCase -from clients import srm - - -class TestAvailabilityZoneInfoSynchronizationController(BaseTestCase): - """AvailabilityZoneInfoSynchronizationController integration test stubs""" - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.token = "" - BaseTestCase.zone_partner = "" - BaseTestCase.zone_originating = "" - - def run(self, result=None): - """ Stop after first error """ - try: - # Check if there is connection with Edge Cloud Platform. Otherwise stop the test - try: - srm.get_zones() - except Exception: - self.skipTest("Edge Cloud Platform connection not available") - - # Check if there is connection with keycloak. Otherwise stop the test - try: - BaseTestCase.token = self.get_access_token() - except Exception: - self.skipTest("Keycloak connection not available") - - # Check if there is connection with FM. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'partner_op') - except Exception: - self.skipTest("FM Partner OP connection not available") - - # Check if there is connection with FM Originating OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'originating_op') - except Exception: - self.skipTest("FM Originating OP connection not available") - - super(TestAvailabilityZoneInfoSynchronizationController, self).run(result) - except Exception as error: - raise Exception(f"Test failed. Reason: {error}") - - def test_00_setup(self): - """Setup federation contexts for both Partner OP and Originating OP roles""" - try: - # Create federation context for Partner OP role - BaseTestCase.federation_context_id_partner = self.post_federation(BaseTestCase.token, 'partner_op') - - # # Create federation context for Originating OP role - BaseTestCase.federation_context_id_originating = self.post_federation(BaseTestCase.token, 'originating_op') - - # Get zone id from Edge Cloud Platform for Partner OP role - BaseTestCase.zone_partner = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_partner, - BaseTestCase.token, 'partner_op') - if BaseTestCase.zone_partner == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - # Get zone id from Edge Cloud Platform for Originating OP role - BaseTestCase.zone_originating = self.get_zone_from_partner_details(BaseTestCase.federation_context_id_originating, - BaseTestCase.token, 'originating_op') - if BaseTestCase.zone_originating == "": - raise Exception("Test Failed. Unable to retrieve zone from Edge Cloud Platform") - - except Exception as error: - raise Exception(f"Test setup failed. Reason: {error}") - - def test_01_zone_subscribe(self): - """Test case for zone_subscribe in both Partner OP and Originating OP modes""" - - def test_zone_subscribe(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - body = { - "acceptedAvailabilityZones": [ - zone - ], - "availZoneNotifLink": f"https://{role}.notification.example.com/zones" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_zone_subscribe('partner_op') - originating_response = test_zone_subscribe('originating_op') - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - # Verify response contains zone registration data - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertIn("acceptedZoneResourceInfo", partner_data) - self.assertIn("acceptedZoneResourceInfo", originating_data) - - def test_02_zone_subscribe_duplicate(self): - """Test case for duplicate zone subscription - dual role""" - - def test_duplicate_subscription(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - # Same zone as test_01 - should be already subscribed - body = { - "acceptedAvailabilityZones": [ - zone - ], - "availZoneNotifLink": f"https://{role}.duplicate.example.com/zones" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_duplicate_subscription('partner_op') - originating_response = test_duplicate_subscription('originating_op') - - # May succeed (update) or reject duplicate - both are valid behaviors - self.assertIn(partner_response.status_code, [200, 409, 422]) - self.assertIn(originating_response.status_code, [200, 409, 422]) - - def test_03_get_zone_data(self): - """Test case for get_zone_data in both Partner OP and Originating OP modes""" - - def test_get_zone_data(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - url = f"http://{self.base_url}/{federation_id}/zones/{zone}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_zone_data('partner_op') - originating_response = test_get_zone_data('originating_op') - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - # Verify response contains zone data - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertEqual(partner_data.get("zoneId"), BaseTestCase.zone_partner) - self.assertEqual(originating_data.get("zoneId"), BaseTestCase.zone_originating) - - def test_04_get_zone_data_nonexistent(self): - """Test case for getting non-existent zone data - dual role""" - - def test_get_nonexistent_zone(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - url = f"http://{self.base_url}/{federation_id}/zones/nonexistent-zone-id" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_nonexistent_zone('partner_op') - originating_response = test_get_nonexistent_zone('originating_op') - - # Both should return error for non-existent zone - self.assertIn(partner_response.status_code, [404, 422]) - self.assertIn(originating_response.status_code, [404, 422]) - - def test_05_zone_subscribe_invalid_federation(self): - """Test case for zone subscription with invalid federation ID - dual role""" - - def test_invalid_federation(role): - if role == 'partner_op': - zone = BaseTestCase.zone_partner - else: - zone = BaseTestCase.zone_originating - - body = { - "acceptedAvailabilityZones": [zone], - "availZoneNotifLink": f"https://{role}.invalid.example.com/zones" - } - - url = f"http://{self.base_url}/invalid-federation-id/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_federation('partner_op') - originating_response = test_invalid_federation('originating_op') - - # Both should return error for invalid federation - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_06_zone_subscribe_invalid_zone(self): - """Test case for zone subscription with invalid zone ID - dual role""" - - def test_invalid_zone(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "acceptedAvailabilityZones": ["invalid-zone-id"], - "availZoneNotifLink": f"https://{role}.invalid-zone.example.com/zones" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_zone('partner_op') - originating_response = test_invalid_zone('originating_op') - - # Both should return error for invalid zone - self.assertIn(partner_response.status_code, [404, 422]) - self.assertIn(originating_response.status_code, [404, 422]) - - def test_07_zone_subscribe_empty_zones(self): - """Test case for zone subscription with empty zones list - dual role""" - - def test_empty_zones(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - body = { - "acceptedAvailabilityZones": [], # Empty list - "availZoneNotifLink": f"https://{role}.empty.example.com/zones" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_empty_zones('partner_op') - originating_response = test_empty_zones('originating_op') - - # May succeed (unsubscribe all) or return validation error - self.assertIn(partner_response.status_code, [200, 400, 422]) - self.assertIn(originating_response.status_code, [200, 400, 422]) - - def test_08_zone_subscribe_invalid_body(self): - """Test case for zone subscription with invalid body - dual role""" - - def test_invalid_body(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - # Missing required fields - body = { - "invalidField": "invalid_value" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_body('partner_op') - originating_response = test_invalid_body('originating_op') - - # Both should return validation error - self.assertIn(partner_response.status_code, [400, 422]) - self.assertIn(originating_response.status_code, [400, 422]) - - def test_09_zone_subscribe_multiple_zones(self): - """Test case for zone subscription with multiple zones - dual role""" - - def test_multiple_zones(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - zone = BaseTestCase.zone_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - zone = BaseTestCase.zone_originating - - # Try to subscribe to multiple zones (may not all be available) - body = { - "acceptedAvailabilityZones": [ - zone, - "additional-zone-1", - "additional-zone-2" - ], - "availZoneNotifLink": f"https://{role}.multiple.example.com/zones" - } - - url = f"http://{self.base_url}/{federation_id}/zones" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_multiple_zones('partner_op') - originating_response = test_multiple_zones('originating_op') - - # May succeed (partial subscription) or fail due to invalid zones - self.assertIn(partner_response.status_code, [200, 404, 422]) - self.assertIn(originating_response.status_code, [200, 404, 422]) - - def test_10_get_zone_data_invalid_federation(self): - """Test case for getting zone data with invalid federation ID - dual role""" - - def test_get_invalid_federation(role): - if role == 'partner_op': - zone = BaseTestCase.zone_partner - else: - zone = BaseTestCase.zone_originating - - url = f"http://{self.base_url}/invalid-federation-id/zones/{zone}" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_invalid_federation('partner_op') - originating_response = test_get_invalid_federation('originating_op') - - # Both should return error for invalid federation - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_99_cleanup(self): - """Cleanup resources for both roles""" - try: - # Delete zone subscriptions for both roles - self.delete_zone(BaseTestCase.federation_context_id_partner, BaseTestCase.zone_partner, BaseTestCase.token, - 'partner_op') - self.delete_zone(BaseTestCase.federation_context_id_originating, BaseTestCase.zone_originating, - BaseTestCase.token, 'originating_op') - - # Delete federations for both roles - self.delete_federation(BaseTestCase.federation_context_id_partner, BaseTestCase.token, 'partner_op') - self.delete_federation(BaseTestCase.federation_context_id_originating, BaseTestCase.token, 'originating_op') - - except Exception as error: - print(f"Cleanup failed: {error}") - - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/src/test/test_federation_management.py b/src/test/test_federation_management.py deleted file mode 100644 index f9b02cd9ae91d5e8c72b9d8cc7291a3c55e8a84e..0000000000000000000000000000000000000000 --- a/src/test/test_federation_management.py +++ /dev/null @@ -1,521 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -from __future__ import absolute_import - -import time -from test import BaseTestCase -from clients import srm - - -class TestFederationManagementController(BaseTestCase): - """FederationManagementController integration test stubs""" - - BaseTestCase.federation_context_id_partner = "" - BaseTestCase.federation_context_id_originating = "" - BaseTestCase.token = "" - - def run(self, result=None): - """ Stop after first error """ - try: - time.sleep(5) - - # Check if there is connection with Edge Cloud Platform. Otherwise stop the test - try: - srm.get_zones() - except Exception: - self.skipTest("Edge Cloud Platform connection not available") - - # Check if there is connection with keycloak. Otherwise stop the test - try: - BaseTestCase.token = self.get_access_token() - except Exception: - self.skipTest("Keycloak connection not available") - - # Check if there is connection with FM Partner OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'partner_op') - except Exception: - self.skipTest("FM Partner OP connection not available") - - # Check if there is connection with FM Originating OP. Otherwise stop the test - try: - self.get_federation_context(BaseTestCase.token, 'originating_op') - except Exception: - self.skipTest("FM Originating OP connection not available") - - super(TestFederationManagementController, self).run(result) - except Exception as error: - raise Exception(f"Test failed. Reason: {error}") - - def test_01_create_federation(self): - """Test case for create_federation in both Partner OP and Originating OP modes""" - - def test_create_federation(role): - body = { - "origOPFederationId": f"test-federation-{role}", - "origOPCountryCode": "US", - "origOPMobileNetworkCodes": { - "mcc": "111", - "mncs": [ - "11" - ] - }, - "origOPFixedNetworkCodes": [ - "string" - ], - "initialDate": "2024-02-26T11:05:07.925Z", - "partnerStatusLink": "string", - "partnerCallbackCredentials": { - "tokenUrl": "string", - "clientId": "string", - "clientSecret": "string" - } - } - - url = f"http://{self.base_url}/partner" - - if role == 'originating-op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - if response.status_code == 200: - federation_id = response.json().get("federationContextId") - if role == 'partner-op': - BaseTestCase.federation_context_id_partner = federation_id - else: - BaseTestCase.federation_context_id_originating = federation_id - - return response - - # Test both roles - partner_response = test_create_federation('partner-op') - originating_response = test_create_federation('originating-op') - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 200) - self.assertEqual(originating_response.status_code, 200) - - # Verify response contains federation context ID - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertIn("federationContextId", partner_data) - self.assertIn("federationContextId", originating_data) - - def test_02_create_federation_invalid_body(self): - """Test case for creating federation with invalid body - dual role""" - - def test_invalid_body(role): - # Missing required fields - body = { - "invalidField": "invalid_value" - } - - url = f"http://{self.base_url}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("POST", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("POST", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_body('partner_op') - originating_response = test_invalid_body('originating_op') - - # Both should return validation error - self.assertIn(partner_response.status_code, [400, 422]) - self.assertIn(originating_response.status_code, [400, 422]) - - def test_03_get_federation(self): - """Test case for get_federation in both Partner OP and Originating OP modes""" - - def test_get_federation(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - if not federation_id: - return None # Skip if federation not created - - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_federation('partner_op') - originating_response = test_get_federation('originating_op') - - # Both should succeed with 200 if federation exists - if partner_response: - self.assertEqual(partner_response.status_code, 200) - - if originating_response: - self.assertEqual(originating_response.status_code, 200) - - def test_04_get_nonexistent_federation(self): - """Test case for getting non-existent federation - dual role""" - - def test_get_nonexistent(role): - url = f"http://{self.base_url}/626bccb9697a12204fb22ea3/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_get_nonexistent('partner_op') - originating_response = test_get_nonexistent('originating_op') - - # Both should return 404 for non-existent federation - self.assertEqual(partner_response.status_code, 404) - self.assertEqual(originating_response.status_code, 404) - - def test_05_get_federation_invalid_format(self): - """Test case for getting federation with invalid ID format - dual role""" - - def test_invalid_format(role): - url = f"http://{self.base_url}/invalid_format_123/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_invalid_format('partner_op') - originating_response = test_invalid_format('originating_op') - - # Both should return error for invalid format - self.assertIn(partner_response.status_code, [400, 404, 422]) - self.assertIn(originating_response.status_code, [400, 404, 422]) - - def test_06_update_federation(self): - """Test case for updating federation - dual role""" - - def test_update_federation(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - if not federation_id: - return None # Skip if federation not created - - body = { - "objectType": "MOBILE_NETWORK_CODES", - "operationType": "ADD_CODES", - "addMobileNetworkIds": { - "mcc": "111", - "mncs": [ - "22" - ] - }, - "removeMobileNetworkIds": { - "mcc": "111", - "mncs": [ - "11" - ] - }, - "addFixedNetworkIds": [ - "string" - ], - "removeFixedNetworkIds": [ - "string" - ], - "modificationDate": "2024-03-18T14:47:17.054Z" - } - - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_federation('partner_op') - originating_response = test_update_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [200]) - if originating_response: - self.assertIn(originating_response.status_code, [200]) - - def test_07_update_federation_invalid_body(self): - """Test case for updating federation with invalid body - dual role""" - - def test_update_federation(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - if not federation_id: - return None # Skip if federation not created - - body = { - "objectType": "MOBILE_NETWORK_CODES", - "operationType": "ADD_CODES", - "addMobileNetworkIds": { - "mcc": "1111", - "mncs": [ - "22" - ] - }, - "removeMobileNetworkIds": { - "111": "string", - "mncs": [ - "11" - ] - }, - "addFixedNetworkIds": [ - "string" - ], - "removeFixedNetworkIds": [ - "string" - ], - "modificationDate": "2024-03-18T14:47:17.054Z" - } - - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_federation('partner_op') - originating_response = test_update_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [400]) - if originating_response: - self.assertIn(originating_response.status_code, [400]) - - def test_08_update_nonexistent_federation(self): - """Test case for updating nonexistent federation - dual role""" - - def test_update_federation(role): - body = { - "objectType": "MOBILE_NETWORK_CODES", - "operationType": "ADD_CODES", - "addMobileNetworkIds": { - "mcc": "111", - "mncs": [ - "22" - ] - }, - "removeMobileNetworkIds": { - "mcc": "111", - "mncs": [ - "11" - ] - }, - "addFixedNetworkIds": [ - "string" - ], - "removeFixedNetworkIds": [ - "string" - ], - "modificationDate": "2024-03-18T14:47:17.054Z" - } - - url = f"http://{self.base_url}/{'65b799f576063bc1ac9e6999'}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_federation('partner_op') - originating_response = test_update_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [404]) - if originating_response: - self.assertIn(originating_response.status_code, [404]) - - # test update a federation. Conflict with mcc - def test_09_update_federation_conflicting_body(self): - """Test case for updating federation with conflicting body - dual role""" - - def test_update_federation(role): - if role == 'partner_op': - federation_id = BaseTestCase.federation_context_id_partner - else: - federation_id = BaseTestCase.federation_context_id_originating - - if not federation_id: - return None # Skip if federation not created - - body = { - "objectType": "MOBILE_NETWORK_CODES", - "operationType": "ADD_CODES", - "addMobileNetworkIds": { - "mcc": "222", - "mncs": [ - "22" - ] - }, - "removeMobileNetworkIds": { - "mcc": "111", - "mncs": [ - "11" - ] - }, - "addFixedNetworkIds": [ - "string" - ], - "removeFixedNetworkIds": [ - "string" - ], - "modificationDate": "2024-03-18T14:47:17.054Z" - } - - url = f"http://{self.base_url}/{federation_id}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("PATCH", url, body, BaseTestCase.token) - else: - response = self.make_request_partner_op("PATCH", url, body, BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_update_federation('partner_op') - originating_response = test_update_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [409]) - if originating_response: - self.assertIn(originating_response.status_code, [409]) - - def test_10_delete_federation_invalid_format(self): - """Test case for deleting federation with invalid ID format - dual role""" - - def test_delete_federation(role): - url = f"http://{self.base_url}/{3232222232323232}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("DELETE", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_delete_federation('partner_op') - originating_response = test_delete_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [422]) - if originating_response: - self.assertIn(originating_response.status_code, [422]) - - def test_11_delete_nonexistent_federation(self): - """Test case for deleting not existing federation - dual role""" - - def test_delete_federation(role): - url = f"http://{self.base_url}/{'65b799f576063bc1ac9e6999'}/partner" - - if role == 'originating_op': - response = self.make_request_originating_op("DELETE", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("DELETE", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_delete_federation('partner_op') - originating_response = test_delete_federation('originating_op') - - # Check responses if federations exist - if partner_response: - self.assertIn(partner_response.status_code, [422]) - if originating_response: - self.assertIn(originating_response.status_code, [422]) - - def test_12_get_federation_context_not_found(self): - """Test case for getting federation context not found - dual role""" - - def test_federation_context(role): - url = f"http://{self.base_url}/fed-context-id" - - if role == 'originating_op': - response = self.make_request_originating_op("GET", url, token=BaseTestCase.token) - else: - response = self.make_request_partner_op("GET", url, token=BaseTestCase.token) - - return response - - # Test both roles - partner_response = test_federation_context('partner_op') - originating_response = test_federation_context('originating_op') - - # Both should succeed with 200 - self.assertEqual(partner_response.status_code, 404) - self.assertEqual(originating_response.status_code, 404) - - # Verify response contains resource information - partner_data = partner_response.json() - originating_data = originating_response.json() - self.assertIsInstance(partner_data, (dict, list)) - self.assertIsInstance(originating_data, (dict, list)) - - def test_99_cleanup(self): - """Cleanup resources for both roles""" - try: - # Delete federations for both roles - if BaseTestCase.federation_context_id_partner: - self.delete_federation(BaseTestCase.federation_context_id_partner, BaseTestCase.token, 'partner_op') - - if BaseTestCase.federation_context_id_originating: - self.delete_federation(BaseTestCase.federation_context_id_originating, BaseTestCase.token, 'originating_op') - - except Exception as error: - print(f"Cleanup failed: {error}") - - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/src/type_util.py b/src/type_util.py deleted file mode 100644 index 4ba794318819fc67d74127b302316332cecb722e..0000000000000000000000000000000000000000 --- a/src/type_util.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -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/src/util.py b/src/util.py deleted file mode 100644 index 405fe0851043665574534979480ef6c43928f71a..0000000000000000000000000000000000000000 --- a/src/util.py +++ /dev/null @@ -1,186 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -import datetime - -import six -import type_util -from enum import Enum - - -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)} - - -def get_token_from_request(connection): - bearer_token = "" - - # Access the Authorization header - authorization_header = connection.request.headers.get('Authorization') - - # Check if the header is present and starts with 'Bearer' - if authorization_header and authorization_header.startswith('Bearer '): - # Extract the token from the header - bearer_token = authorization_header.split(' ')[1] - - return bearer_token - - -def get_header_from_request(connection): - - # Access the Partner-API-Root header - partner_api_root = connection.request.headers.get('X-Partner-API-Root') - - return partner_api_root - - -class RepoType(Enum): - PRIVATE = "PRIVATEREPO" - PUBLIC = "PUBLICREPO" - UPLOAD = "UPLOAD" diff --git a/src/validator.py b/src/validator.py deleted file mode 100644 index d7404ecd31a75c9959d3492ac6e330ab4627a1b6..0000000000000000000000000000000000000000 --- a/src/validator.py +++ /dev/null @@ -1,38 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -import json -from urllib.request import urlopen - -from authlib.oauth2.rfc7523 import JWTBearerTokenValidator -from authlib.jose.rfc7517.jwk import JsonWebKey - - -class Auth0JWTBearerTokenValidator(JWTBearerTokenValidator): - def __init__(self, domain, audience): - issuer = f"https://{domain}/" - jsonurl = urlopen(f"{issuer}.well-known/jwks.json") - public_key = JsonWebKey.import_key_set( - json.loads(jsonurl.read()) - ) - super(Auth0JWTBearerTokenValidator, self).__init__( - public_key - ) - self.claims_options = { - "exp": {"essential": True}, - "aud": {"essential": True, "value": audience}, - "iss": {"essential": True, "value": issuer}, - } diff --git a/src/wsgi.py b/src/wsgi.py deleted file mode 100644 index faa7b0e5310b4d4ec06f2c95baa729903dcee4a4..0000000000000000000000000000000000000000 --- a/src/wsgi.py +++ /dev/null @@ -1,25 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2025-present, Federation Manager, by Software Networks, i2CAT # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# -------------------------------------------------------------------------- # - -""" -Federation Manager main entrypoint -""" -from main import app - - -if __name__ == "__main__": - - app.run(host="0.0.0.0", port=8989)