diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..58553b0aaa1ab674beb5e5d81bcfa45299c30a6e Binary files /dev/null and b/.DS_Store differ diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..413eaf95a4862852a1601d2febfe734b88291219 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git/ +.gitignore + +**/__pycache__ +.mypy_cache +.pytest_cache +*~ + +*.code-workspace +.vscode diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000000000000000000000000000000000000..96934b5574c705386e3e71b26cd55f6827351de5 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,33 @@ +name: Docker Image CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - + name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/doml-model-checker:latest diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000000000000000000000000000000000000..59eb89be2e3ed040f5303fa138d814bd90fcb4d7 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,22 @@ +name: Pages +on: + push: + branches: + - master +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-python@v2 + - uses: actions/checkout@master + with: + fetch-depth: 0 # otherwise, you will failed to push refs to dest repo + - name: Build and Commit + uses: sphinx-notes/pages@v2 + with: + requirements_path: ./docs/requirements.txt + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: gh-pages \ No newline at end of file diff --git a/.gitignore b/.gitignore index fc6f6f49ab8833ad839524e8eb13e52b9e1e1043..6769e21d99a63338394e47bc4c7d0aba1e88d5a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,160 @@ -*~ -*__pycache__* -.vscode -docs/_build +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..ec70a1bd1d504f2770f92b4316a7b016964148c1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,91 @@ +include: + - project: piacere/private/t23-ci-setup + ref: main + file: + - gitlab-ci-scripts/utils.gitlab-ci.yml + + # Image tag variables generation job ------------- + # Stage: variable-generation --------------------- + - gitlab-ci-scripts/generate-variables.gitlab-ci.yml + + # Downstream t23-ci-setup pipeline trigger job --- + # Stage: integration-tests-publish-deploy -------- + - gitlab-ci-scripts/trigger-downstream.gitlab-ci.yml + +variables: + # ------------------------ + # Component image tag data + # ------------------------ + COMPONENT_WP: wp4 + DMC_IMAGE_NAME: dmc + + # ------------------------------------------ + # Space-separated component image abbreviation list + # used to generate image tags and related variables. + # It is also passed to the downstream integration tests, + # publication and deployment pipeline + # ------------------------------------------ + IMAGE_NAMES: "$DMC_IMAGE_NAME" + +stages: + - variable-generation + - build + - security + - functional-tests + - integration-tests-publish-deploy + +# Build jobs ---------------------- + +build-temp-dmc: + stage: build + variables: + TMP_IMAGE: "$TMP_IMAGE_DMC" + DOCKERFILE_PATH: "." + trigger: !reference [.trigger-build] + rules: + - if: $CI_COMMIT_BRANCH =~ /^y3/ + +# Security job ------------------------ + +security-trivy-dmc: + stage: security + variables: + TMP_IMAGE: "$TMP_IMAGE_DMC" + trigger: !reference [.trigger-security-trivy] + needs: + - job: build-temp-dmc + - job: generate-variables + artifacts: true + rules: + - if: $CI_COMMIT_BRANCH =~ /^y3/ + +# functional tests job ------------------------ + +run-functional-tests: + image: $DOCKER_IMAGE + stage: functional-tests + services: + - $DOCKER_DIND_IMAGE + variables: + TESTS_CONTAINER_NAME: functional-tester + before_script: + - !reference [.artifactory-login] + script: + # Tests assume port 8080, while the Dockerfile CMD runs the server on port 80. + # Thus, we need to override the command so that the server is run on port 8080. + - docker run --name $TESTS_CONTAINER_NAME -d -e "UVICORN_PORT=8080" $TMP_IMAGE_DMC + # Install everything required for the tests. + - docker exec -i $TESTS_CONTAINER_NAME /bin/bash -c + "pip install -r requirements.txt" + # Run the tests. + - docker exec -i $TESTS_CONTAINER_NAME /bin/bash -c "python -m pytest tests/test_mc_openapi.py -n auto" + # Stop the tests container. + - docker stop $TESTS_CONTAINER_NAME + needs: + - job: build-temp-dmc + - job: generate-variables + artifacts: true + tags: + - docker + rules: + - if: $CI_COMMIT_BRANCH =~ /^y3/ diff --git a/.gitlab/issue_templates/issue.md b/.gitlab/issue_templates/issue.md new file mode 100644 index 0000000000000000000000000000000000000000..c681b7c9a99b18734f7b375e6c530a27cac8142d --- /dev/null +++ b/.gitlab/issue_templates/issue.md @@ -0,0 +1,15 @@ +# Issue Title + +- [ ] The model is satisfied when it shouldn't (or viceversa) +- [ ] There's an issue with the model checker +- [ ] There's an error with the DOMLR (DSL for requirements) + +## Files +To investigate your issue, I need: +- The DOML version you're targeting +- The PIACERE IDE version you are using +- A link to DOML model in question +- The error message (screenshot or copy-n-paste it) +- Any other information you think it's useful + +## Description diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000000000000000000000000000000000..cc65e73eb882dcfc036c5cda2f27f06747bb1254 --- /dev/null +++ b/.python-version @@ -0,0 +1,2 @@ +piacere-dmc +3.11.6 \ No newline at end of file diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a83fae56dc39d959ba8ba3a020cf158ab586b0bd --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,29 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# If using Sphinx, optionally build your docs in additional formats such as PDF +# formats: +# - pdf + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3f83f94a033475b1d6d3596ab5926b41ad973b88..8e20c0bcceab6f848cb5eddc60b28db6a8ee34d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,14 @@ -FROM python:3.9.12-bullseye +FROM python:3.11.3-buster AS requirements-stage -COPY . /opt/mc_openapi +WORKDIR /code -RUN useradd -mU mc -USER mc -ENV PATH="/home/mc/.local/bin:${PATH}" -RUN pip install -r /opt/mc_openapi/requirements.txt -WORKDIR /opt/mc_openapi +COPY ./requirements.txt /code/requirements.txt -CMD ["uwsgi", "--http", ":80", "--yaml", "uwsgi_config.yaml"] +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +COPY ./mc_openapi /code/mc_openapi +COPY ./tests /code/tests + +EXPOSE 80 + +CMD ["uvicorn", "mc_openapi.api:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] diff --git a/README.md b/README.md index b70a04893e3328e3681c6954da4fcba190484f13..f98b83f477237d5d7631be8c463b9818d36276c9 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,46 @@ -# PIACERE Model Checker REST API server +# DOML Model Checker +[](https://piacere-model-checker.readthedocs.io/en/latest/?badge=latest) -This project is packaged with [Poetry](https://python-poetry.org/). +## Description of the component -## Build and Run +The DOML Model Checker is a component of the [PIACERE](https://www.piacere-project.eu/) framework in charge of checking the correctness and consistency of [DOML](https://www.piacere-doml.deib.polimi.it/) models. -Build with +It consists of a web server exposing a REST API that receives a DOML model in XMI format (also called DOMLX) and provides as output a result detailing whether the model satisfies a set of internal requirements, and in case of negative results, what elements are in violation and how to fix the issue. + +It also bundles a Cloud Service Provider (CSP) Compatibility tool that can provide the compatibility results of a model against common Cloud Service Providers. + +## Installation + +### Setup + +Activate the Python Virtual Environment with: ```sh -poetry install +source .venv/bin/activate ``` -then run with +Install the required packages with: ```sh -poetry run python -m mc_openapi +pip install -r requirements.txt ``` -Run tests with: +### Run the model checker web server ```sh -poetry run python -m pytest +python -m mc_openapi ``` -## Run with uWSGI +### Run with Uvicorn + +The project may be run with [Uvicorn](https://www.uvicorn.org/) as follows: +```sh +uvicorn --port 8080 --host 0.0.0.0 --interface wsgi --workers 2 mc_openapi.app_config:app +``` +### Run tests -The project may be run with [uWSGI](https://uwsgi-docs.readthedocs.io/) as follows: +Run tests with: ```sh -uwsgi --http :8080 --yaml uwsgi_config.yaml +python -m pytest ``` -## Run with Docker +### Run with Docker First, build the docker image with the usual ```sh @@ -35,17 +50,33 @@ And then run it with ```sh docker run -d wp4/dmc ``` -The uWSGI server will be running and listening on port 80 of the container. +The Uvicorn server will be running and listening on port `8080` of the container. +To use it locally, you may bind it with port `8080` of `localhost` +by adding `-p 127.0.0.1:8080:8080/tcp` to the `docker run` command. + +## Documentation +You can read the latest version at [readthedocs.io](https://piacere-model-checker.readthedocs.io/en/latest/) + +### Building the Documentation +The documentation has been written in [Sphinx](https://www.sphinx-doc.org/) +and covers both usage through the PIACERE IDE and the REST APIs. + +If you want to build the documentation manually, run: +```sh +cd docs +make html +``` -## REST APIs +The documentation will be generated in `docs/_build`. -The OpenAPI definition of the REST APIs is in `mc_openapi/openapi/model_checker.yaml`. +## License +This work is licensed under the Apache License 2.0. -The APIs can also be browsed with [Swagger UI](https://swagger.io/tools/swagger-ui/) by appending `/ui/` to the API HTTP address. +## Contact -For APIs usage examples, you may look into the tests, in `tests/test_mc_openapi.py`. -Two DOML examples in XMI format are sent to the server. -One of them is correct (`tests/doml/nginx-openstack_v2.domlx`), and the server answers with `"sat"` (meaning the requirements are satisfied), and the other one contains an error (`tests/doml/nginx-openstack_v2_wrong.domlx`), so the server answers with `"unsat"`. +andrea.franchini@polimi.it -**Note:** for the time being, the `model` field of the POST request's body accepts any XML object. This will be changed to the DOML XMI schema when possible. +## Acknowledgement +This project has received funding from the European Union’s Horizon 2020 research and innovation programme under Grant +Agreement No. 101000162 (PIACERE). diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 1c35a4f6033527881ced5891a73e4798e0b5c1ad..0000000000000000000000000000000000000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,49 +0,0 @@ -appnope==0.1.3 ; python_version >= "3.9" and python_version < "4.0" and platform_system == "Darwin" or python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin" -asttokens==2.0.5 ; python_version >= "3.9" and python_version < "4.0" -atomicwrites==1.4.1 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32" -attrs==22.1.0 ; python_version >= "3.9" and python_version < "4.0" -backcall==0.2.0 ; python_version >= "3.9" and python_version < "4.0" -certifi==2022.6.15 ; python_version >= "3.9" and python_version < "4" -cffi==1.15.1 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy" -charset-normalizer==2.1.0 ; python_version >= "3.9" and python_version < "4" -colorama==0.4.5 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.9" and python_version < "4.0" and platform_system == "Windows" -colorful==0.5.4 ; python_version >= "3.9" and python_version < "4.0" -debugpy==1.6.2 ; python_version >= "3.9" and python_version < "4.0" -decorator==5.1.1 ; python_version >= "3.9" and python_version < "4.0" -entrypoints==0.4 ; python_version >= "3.9" and python_version < "4.0" -executing==0.9.1 ; python_version >= "3.9" and python_version < "4.0" -idna==3.3 ; python_version >= "3.9" and python_version < "4" -iniconfig==1.1.1 ; python_version >= "3.9" and python_version < "4.0" -ipykernel==6.15.1 ; python_version >= "3.9" and python_version < "4.0" -ipython==8.4.0 ; python_version >= "3.9" and python_version < "4.0" -jedi==0.18.1 ; python_version >= "3.9" and python_version < "4.0" -jupyter-client==7.3.4 ; python_version >= "3.9" and python_version < "4.0" -jupyter-core==4.11.1 ; python_version >= "3.9" and python_version < "4.0" -matplotlib-inline==0.1.3 ; python_version >= "3.9" and python_version < "4.0" -nest-asyncio==1.5.5 ; python_version >= "3.9" and python_version < "4.0" -packaging==21.3 ; python_version >= "3.9" and python_version < "4.0" -parso==0.8.3 ; python_version >= "3.9" and python_version < "4.0" -pexpect==4.8.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32" -pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "4.0" -pluggy==1.0.0 ; python_version >= "3.9" and python_version < "4.0" -prettyprinter==0.18.0 ; python_version >= "3.9" and python_version < "4.0" -prompt-toolkit==3.0.30 ; python_version >= "3.9" and python_version < "4.0" -psutil==5.9.1 ; python_version >= "3.9" and python_version < "4.0" -ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32" -pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "4.0" -py==1.11.0 ; python_version >= "3.9" and python_version < "4.0" -pycparser==2.21 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy" -pygments==2.12.0 ; python_version >= "3.9" and python_version < "4.0" -pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "4.0" -pytest==6.2.5 ; python_version >= "3.9" and python_version < "4.0" -python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "4.0" -pywin32==304 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "4.0" -pyzmq==23.2.0 ; python_version >= "3.9" and python_version < "4.0" -requests==2.28.1 ; python_version >= "3.9" and python_version < "4" -six==1.16.0 ; python_version >= "3.9" and python_version < "4.0" -stack-data==0.3.0 ; python_version >= "3.9" and python_version < "4.0" -toml==0.10.2 ; python_version >= "3.9" and python_version < "4.0" -tornado==6.2 ; python_version >= "3.9" and python_version < "4.0" -traitlets==5.3.0 ; python_version >= "3.9" and python_version < "4.0" -urllib3==1.26.11 ; python_version >= "3.9" and python_version < "4" -wcwidth==0.2.5 ; python_version >= "3.9" and python_version < "4.0" diff --git a/docs/PIACERE_logo.png b/docs/PIACERE_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8225ccc44d7c081e988f3de5e93695d155e8a919 Binary files /dev/null and b/docs/PIACERE_logo.png differ diff --git a/docs/conf.py b/docs/conf.py index a611a3023e830e145b161e91470bd0da8bcc8e47..eef39638ef132ca57af783eaa43e5d5ca024d8b6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,17 +13,17 @@ # import os # import sys # sys.path.insert(0, os.path.abspath('.')) -import sphinx_rtd_theme +# import sphinx_rtd_theme # -- Project information ----------------------------------------------------- project = 'DOML Model Checker' -copyright = '2022, Michele Chiari and Michele De Pascalis' -author = 'Michele Chiari and Michele De Pascalis' +copyright = '2022, Michele Chiari, Michele De Pascalis, Andrea Franchini' +author = 'Michele Chiari, Michele De Pascalis, Andrea Franchini' # The full version, including alpha/beta/rc tags -release = '1.0.0' +release = '2.5.2' # -- General configuration --------------------------------------------------- @@ -32,7 +32,7 @@ release = '1.0.0' # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx_rtd_theme' + # 'sphinx_rtd_theme' ] # Add any paths that contain templates here, relative to this directory. @@ -41,7 +41,7 @@ templates_path = [] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'requirements.txt'] # -- Options for HTML output ------------------------------------------------- @@ -49,8 +49,9 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' - +# html_theme = 'sphinx_rtd_theme' +html_theme = 'furo' +html_logo = "PIACERE_logo.png" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". diff --git a/docs/index.rst b/docs/index.rst index ec8ef513ffa8ae204f1b6e2847034e325e90bd0b..61192c2eafb2647b10f088aee325397520e3676e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -DOML Model Checker's documentation +DOML Model Checker Documentation ================================== The DOML Model Checker is a component of the `PIACERE`_ framework @@ -15,9 +15,12 @@ in charge of checking the correctness and consistency of `DOML`_ models. :caption: Contents: installation + tests usage + writing-requirements requirements restapis + reference_index .. Indices and tables @@ -28,8 +31,8 @@ in charge of checking the correctness and consistency of `DOML`_ models. * :ref:`search` -This project has received funding from the European Union's Horizon 2020 -research and innovation programme under grant agreement No. 101000162. +*This project has received funding from the European Union's Horizon 2020 +research and innovation programme under grant agreement No. 101000162.* .. _PIACERE: https://www.piacere-project.eu/ diff --git a/docs/installation.rst b/docs/installation.rst index 623056d937437b2dec0c519733f80da9d76fad28..b06dcae153e8cc0fdcc77c563b58a112b26649b0 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -1,44 +1,46 @@ Installation -============ +************ -The DOML Model Checker receives user inputs through its REST APIs. -In this guide we illuestrate saveral ways of setting up the server for these APIs. +The model checker can be run in two configurations, *REST API* and *CLI*. +First, you'll need to install the dependencies to run this tool. -Build and run locally for testing ---------------------------------- +Installing the dependencies +=========================== +1. Clone/download the model checker repository. -This project is packaged with `Poetry`_, which we assume you have already -`installed <https://python-poetry.org/docs/#installation>`_ into your system. +2. Setting up a Python virtual environment is recommended. You can run the following command to create it:: + python -m venv .venv -Build with:: + # Remember to activate it! e.g.: + source .venv/bin/activate + +3. Install the dependencies with:: - poetry install + pip install -r requirements.txt -then run with:: +Run locally for testing +----------------------- +Run with:: - poetry run python -m mc_openapi + python -m mc_openapi -this command serves the APIs through a `Flask`_ instance, +This command serves the APIs through a `Flask`_ instance, which is suitable for testing, but not recommended for production. -You may read the API specification generated by `Swagger-UI`_ by -pointing your browser to http://127.0.0.1:8080/ui/. +Run locally with Uvicorn +------------------------ -Then, run tests with:: - - poetry run python -m pytest - - -Run locally with uWSGI ----------------------- - -The project may be run with `uWSGI`_, +The project may be run with `Uvicorn`_, which is better-suited for production environments, as follows:: - uwsgi --http :8080 -w mc_openapi.app_config -p 4 + uvicorn --port 8080 --host 0.0.0.0 --interface wsgi --workers 2 mc_openapi.app_config:app +You may also configure Uvicorn using environment variables +with the prefix ``UVICORN_``. +For example, if you want to run the server with 4 workers, +set the environment variable ``UVICORN_WORKERS`` to ``4``. Run with Docker --------------- @@ -53,19 +55,21 @@ And then run it with:: docker run -d wp4/dmc -The uWSGI server will be running and listening on port 80 of the container. +The Uvicorn server will be running and listening on port 80 of the container. +To use it locally, you may e.g. bind it with port 8080 of ``localhost`` +by adding ``-p 127.0.0.1:8080:80/tcp`` to the ``docker run`` command. +REST API Endpoints +================== + +You may read the API specification generated by `Swagger-UI`_ at http://127.0.0.1:8080/ui/. Building the Documentation --------------------------- +========================== The documentation has been written in `Sphinx`_. -To build it, type:: - - poetry shell - -and then:: +To build it manually, run:: cd docs make html @@ -73,9 +77,8 @@ and then:: The documentation will be generated in ``docs/_build``. -.. _Poetry: https://python-poetry.org/ .. _Flask: https://flask.palletsprojects.com/ .. _Swagger-UI: https://swagger.io/tools/swagger-ui/ -.. _uWSGI: https://uwsgi-docs.readthedocs.io/ +.. _Uvicorn: https://www.uvicorn.org/ .. _Docker: https://www.docker.com/ .. _Sphinx: https://www.sphinx-doc.org/ diff --git a/docs/reference_index.rst b/docs/reference_index.rst new file mode 100644 index 0000000000000000000000000000000000000000..2d27fe271987ba543e7a96d578911e3e3fe54f89 --- /dev/null +++ b/docs/reference_index.rst @@ -0,0 +1,19 @@ +DOML Reference +============== + +For a comprehensive list of all the classes, attributes and associations supported in the DOML Model Checker and DOMLR, please consult one of the following pages. + +:doc:`Reference for DOML v2.0 <reference_v2.0>` +----------------------------------------------- +:doc:`Reference for DOML v2.1 <reference_v2.1>` +----------------------------------------------- +:doc:`Reference for DOML v2.2 <reference_v2.2>` +----------------------------------------------- +:doc:`Reference for DOML v2.2.1 <reference_v2.2.1>` +--------------------------------------------------- +:doc:`Reference for DOML v2.3 <reference_v2.3>` +----------------------------------------------- +:doc:`Reference for DOML v3.0 <reference_v3.0>` +----------------------------------------------- +:doc:`Reference for DOML v3.1 <reference_v3.1>` +----------------------------------------------- diff --git a/docs/reference_v2.0.rst b/docs/reference_v2.0.rst new file mode 100644 index 0000000000000000000000000000000000000000..5d59dc06766198c6f51eb611511f6ff1b31ad8e3 --- /dev/null +++ b/docs/reference_v2.0.rst @@ -0,0 +1,530 @@ +DOML v2.0 Reference +============================= + + +commons +^^^^^^^ + +.. _v2.0_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v2.0_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v2.0_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v2.0_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v2.0_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → ApplicationComponent [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v2.0_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v2.0_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.0_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v2.0_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v2.0_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v2.0_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v2.0_commons_Property>` + +* Attributes: + * ``value`` [String] + +application +^^^^^^^^^^^ + +.. _v2.0_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + + +.. _v2.0_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v2.0_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v2.0_application_SoftwareComponent>` + + +.. _v2.0_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v2.0_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v2.0_application_SaaS>` + + +.. _v2.0_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + * ``configFile`` [String] + +.. _v2.0_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v2.0_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v2.0_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``deploymentNetwork`` → Network [0..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v2.0_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v2.0_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + +.. _v2.0_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v2.0_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``hosts`` → ComputingNode [0..*] + +.. _v2.0_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.0_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v2.0_infrastructure_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + + +.. _v2.0_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>` + + +.. _v2.0_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``cost`` [Integer] + +.. _v2.0_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + + +.. _v2.0_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + +.. _v2.0_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`NetworkInterface <v2.0_infrastructure_NetworkInterface>` + + +.. _v2.0_infrastructure_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v2.0_infrastructure_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v2.0_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v2.0_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``igws`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``address_lb`` [Integer] + * ``address_ub`` [Integer] + +.. _v2.0_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v2.0_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>` + + +.. _v2.0_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v2.0_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.0_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v2.0_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v2.0_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..1] + +.. _v2.0_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v2.0_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v2.0_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v2.0_infrastructure_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v2.0_infrastructure_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +.. _v2.0_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.0_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v2.0_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v2.0_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v2.0_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Attributes: + * ``configurationScript`` [String] + +.. _v2.0_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v2.0_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v2.0_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v2.0_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] + +.. _v2.0_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>` + +* Associations: + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v2.0_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v2.0_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] + +.. _v2.0_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v2.1.rst b/docs/reference_v2.1.rst new file mode 100644 index 0000000000000000000000000000000000000000..ec6b8d8453142bb870d15d7f9f161b382319f832 --- /dev/null +++ b/docs/reference_v2.1.rst @@ -0,0 +1,544 @@ +DOML v2.1 Reference +============================= + + +commons +^^^^^^^ + +.. _v2.1_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v2.1_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v2.1_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v2.1_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v2.1_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → ApplicationComponent [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v2.1_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v2.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.1_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v2.1_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v2.1_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v2.1_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v2.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +application +^^^^^^^^^^^ + +.. _v2.1_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + + +.. _v2.1_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v2.1_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v2.1_application_SoftwareComponent>` + + +.. _v2.1_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v2.1_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v2.1_application_SaaS>` + + +.. _v2.1_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + * ``configFile`` [String] + +.. _v2.1_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v2.1_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v2.1_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v2.1_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v2.1_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + +.. _v2.1_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v2.1_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``configs`` → ContainerConfig [0..*] + +.. _v2.1_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``host`` → ComputingNode [0..1] + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v2.1_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v2.1_infrastructure_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + + +.. _v2.1_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>` + + +.. _v2.1_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``cost`` [Integer] + +.. _v2.1_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + + +.. _v2.1_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + +.. _v2.1_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`NetworkInterface <v2.1_infrastructure_NetworkInterface>` + + +.. _v2.1_infrastructure_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v2.1_infrastructure_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v2.1_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v2.1_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``igws`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + * ``cidr`` [Integer] + +.. _v2.1_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v2.1_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>` + + +.. _v2.1_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v2.1_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.1_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v2.1_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v2.1_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..1] + +.. _v2.1_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v2.1_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v2.1_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v2.1_infrastructure_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v2.1_infrastructure_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +.. _v2.1_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v2.1_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v2.1_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v2.1_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Attributes: + * ``configurationScript`` [String] + +.. _v2.1_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v2.1_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v2.1_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v2.1_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] +* Attributes: + * ``address`` [Integer] + +.. _v2.1_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>` + +* Associations: + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v2.1_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v2.1_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] + +.. _v2.1_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v2.2.1.rst b/docs/reference_v2.2.1.rst new file mode 100644 index 0000000000000000000000000000000000000000..3fe713a1e1d66ec784453e6ad46317cd86b6d6ac --- /dev/null +++ b/docs/reference_v2.2.1.rst @@ -0,0 +1,588 @@ +DOML v2.2.1 Reference +============================= + + +commons +^^^^^^^ + +.. _v2.2.1_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v2.2.1_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v2.2.1_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v2.2.1_commons_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + + +.. _v2.2.1_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v2.2.1_commons_DeployableElement: + +DeployableElement +""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + + +.. _v2.2.1_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → DeployableElement [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v2.2.1_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v2.2.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.2.1_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v2.2.1_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v2.2.1_commons_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v2.2.1_commons_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v2.2.1_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v2.2.1_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v2.2.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.2.1_commons_Source: + +Source +"""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Attributes: + * ``entry`` [String] + * ``backend`` [String] + +.. _v2.2.1_commons_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v2.2.1_commons_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +application +^^^^^^^^^^^ + +.. _v2.2.1_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.2.1_commons_DeployableElement>` + + +.. _v2.2.1_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v2.2.1_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v2.2.1_application_SoftwareComponent>` + + +.. _v2.2.1_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v2.2.1_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v2.2.1_application_SaaS>` + + +.. _v2.2.1_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] + * ``src`` → Source [0..1] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + +.. _v2.2.1_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v2.2.1_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v2.2.1_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v2.2.1_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v2.2.1_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + * ``disabledMonitorings`` [String] + +.. _v2.2.1_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v2.2.1_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``configs`` → ContainerConfig [0..*] + +.. _v2.2.1_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``host`` → ComputingNode [0..1] + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v2.2.1_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.2.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v2.2.1_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>` + + +.. _v2.2.1_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``cost`` [Integer] + +.. _v2.2.1_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.2.1_commons_DeployableElement>` + + +.. _v2.2.1_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + * ``rules`` → MonitoringRule [0..*] + +.. _v2.2.1_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`NetworkInterface <v2.2.1_infrastructure_NetworkInterface>` + +* Attributes: + * ``address`` [String] + +.. _v2.2.1_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v2.2.1_infrastructure_MonitoringRule: + +MonitoringRule +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Attributes: + * ``condition`` [String] + * ``strategy`` [String] + * ``strategyConfigurationString`` [String] + +.. _v2.2.1_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``gateways`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + * ``cidr`` [Integer] + +.. _v2.2.1_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v2.2.1_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>` + + +.. _v2.2.1_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v2.2.1_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.2.1_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v2.2.1_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v2.2.1_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..*] + +.. _v2.2.1_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v2.2.1_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v2.2.1_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v2.2.1_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.2.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v2.2.1_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v2.2.1_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v2.2.1_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``refs`` → ConcreteElement [0..*] +* Attributes: + * ``configurationScript`` [String] + * ``preexisting`` [Boolean] + +.. _v2.2.1_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v2.2.1_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v2.2.1_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v2.2.1_concrete_GenericResource: + +GenericResource +""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Attributes: + * ``type`` [String] + * ``gname`` [String] + +.. _v2.2.1_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] + +.. _v2.2.1_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>` + +* Associations: + * ``resources`` → GenericResource [0..*] + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v2.2.1_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v2.2.1_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] + +.. _v2.2.1_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v2.2.rst b/docs/reference_v2.2.rst new file mode 100644 index 0000000000000000000000000000000000000000..8fd6ec64526f4792d54f5572a2b670d8afd3122f --- /dev/null +++ b/docs/reference_v2.2.rst @@ -0,0 +1,573 @@ +DOML v2.2 Reference +============================= + + +commons +^^^^^^^ + +.. _v2.2_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v2.2_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v2.2_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v2.2_commons_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + + +.. _v2.2_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v2.2_commons_DeployableElement: + +DeployableElement +""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + + +.. _v2.2_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → DeployableElement [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v2.2_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v2.2_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.2_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v2.2_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v2.2_commons_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v2.2_commons_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v2.2_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v2.2_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v2.2_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.2_commons_Source: + +Source +"""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``entry`` [String] + * ``backend`` [String] + +.. _v2.2_commons_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v2.2_commons_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +application +^^^^^^^^^^^ + +.. _v2.2_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.2_commons_DeployableElement>` + + +.. _v2.2_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v2.2_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v2.2_application_SoftwareComponent>` + + +.. _v2.2_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v2.2_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v2.2_application_SaaS>` + + +.. _v2.2_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] + * ``src`` → Source [0..1] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + +.. _v2.2_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v2.2_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v2.2_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v2.2_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v2.2_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + * ``disabledMonitorings`` [String] + +.. _v2.2_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v2.2_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``configs`` → ContainerConfig [0..*] + +.. _v2.2_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``host`` → ComputingNode [0..1] + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v2.2_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.2_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v2.2_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>` + + +.. _v2.2_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``cost`` [Integer] + +.. _v2.2_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.2_commons_DeployableElement>` + + +.. _v2.2_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + * ``rules`` → MonitoringRule [0..*] + +.. _v2.2_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`NetworkInterface <v2.2_infrastructure_NetworkInterface>` + + +.. _v2.2_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v2.2_infrastructure_MonitoringRule: + +MonitoringRule +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``condition`` [String] + * ``strategy`` [String] + * ``strategyConfigurationString`` [String] + +.. _v2.2_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``igws`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + * ``cidr`` [Integer] + +.. _v2.2_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v2.2_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>` + + +.. _v2.2_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v2.2_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.2_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v2.2_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v2.2_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..*] + +.. _v2.2_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v2.2_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v2.2_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v2.2_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.2_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v2.2_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v2.2_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v2.2_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Attributes: + * ``configurationScript`` [String] + * ``preexisting`` [Boolean] + +.. _v2.2_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v2.2_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v2.2_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v2.2_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] + +.. _v2.2_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>` + +* Associations: + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v2.2_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v2.2_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] + +.. _v2.2_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v2.3.rst b/docs/reference_v2.3.rst new file mode 100644 index 0000000000000000000000000000000000000000..bf2031e2447840584c72ed2a4ebe30c73bf740b3 --- /dev/null +++ b/docs/reference_v2.3.rst @@ -0,0 +1,594 @@ +DOML v2.3 Reference +============================= + + +commons +^^^^^^^ + +.. _v2.3_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v2.3_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v2.3_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v2.3_commons_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + + +.. _v2.3_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v2.3_commons_DeployableElement: + +DeployableElement +""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + + +.. _v2.3_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → DeployableElement [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v2.3_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v2.3_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.3_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v2.3_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v2.3_commons_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v2.3_commons_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v2.3_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v2.3_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v2.3_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v2.3_commons_Source: + +Source +"""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Attributes: + * ``entry`` [String] + * ``backend`` [String] + +.. _v2.3_commons_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v2.3_commons_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +application +^^^^^^^^^^^ + +.. _v2.3_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.3_commons_DeployableElement>` + + +.. _v2.3_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v2.3_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v2.3_application_SoftwareComponent>` + + +.. _v2.3_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v2.3_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v2.3_application_SaaS>` + + +.. _v2.3_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] + * ``src`` → Source [0..1] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + +.. _v2.3_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v2.3_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v2.3_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v2.3_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v2.3_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`Node <v2.3_infrastructure_Node>` + +* Associations: + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + * ``disabledMonitorings`` [String] + +.. _v2.3_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v2.3_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``configs`` → ContainerConfig [0..*] + +.. _v2.3_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``host`` → ComputingNode [0..1] + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v2.3_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.3_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v2.3_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>` + + +.. _v2.3_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>` + +* Attributes: + * ``cost`` [Integer] + +.. _v2.3_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v2.3_commons_DeployableElement>` + + +.. _v2.3_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + * ``rules`` → MonitoringRule [0..*] + +.. _v2.3_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`Node <v2.3_infrastructure_Node>` + +* Attributes: + * ``address`` [String] + +.. _v2.3_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v2.3_infrastructure_MonitoringRule: + +MonitoringRule +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Attributes: + * ``condition`` [String] + * ``strategy`` [String] + * ``strategyConfigurationString`` [String] + +.. _v2.3_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``gateways`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + * ``cidr`` [Integer] + +.. _v2.3_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v2.3_infrastructure_Node: + +Node +"""" +*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.3_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>` + + +.. _v2.3_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v2.3_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v2.3_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`Node <v2.3_infrastructure_Node>` + +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v2.3_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v2.3_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..*] + +.. _v2.3_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v2.3_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v2.3_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v2.3_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v2.3_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v2.3_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v2.3_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v2.3_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``refs`` → ConcreteElement [0..*] +* Attributes: + * ``configurationScript`` [String] + * ``preexisting`` [Boolean] + +.. _v2.3_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v2.3_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v2.3_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v2.3_concrete_GenericResource: + +GenericResource +""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Attributes: + * ``type`` [String] + * ``gname`` [String] + +.. _v2.3_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] + +.. _v2.3_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>` + +* Associations: + * ``resources`` → GenericResource [0..*] + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v2.3_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v2.3_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] +* Attributes: + * ``image_name`` [String] + +.. _v2.3_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v3.0.rst b/docs/reference_v3.0.rst new file mode 100644 index 0000000000000000000000000000000000000000..096c738f9709f24e21b5a6089dc8c737d712d575 --- /dev/null +++ b/docs/reference_v3.0.rst @@ -0,0 +1,595 @@ +DOML v3.0 Reference +============================= + + +commons +^^^^^^^ + +.. _v3.0_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v3.0_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v3.0_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v3.0_commons_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + + +.. _v3.0_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v3.0_commons_DeployableElement: + +DeployableElement +""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + + +.. _v3.0_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → DeployableElement [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v3.0_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v3.0_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v3.0_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v3.0_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v3.0_commons_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v3.0_commons_Credentials>` + +* Attributes: + * ``user`` [String] + * ``keyfile`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v3.0_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v3.0_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v3.0_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v3.0_commons_Source: + +Source +"""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Attributes: + * ``entry`` [String] + * ``backend`` [String] + +.. _v3.0_commons_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v3.0_commons_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +application +^^^^^^^^^^^ + +.. _v3.0_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v3.0_commons_DeployableElement>` + + +.. _v3.0_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v3.0_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v3.0_application_SoftwareComponent>` + + +.. _v3.0_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v3.0_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v3.0_application_SaaS>` + + +.. _v3.0_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] + * ``src`` → Source [0..1] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + +.. _v3.0_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v3.0_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v3.0_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] + * ``securityGroup`` → SecurityGroup [0..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v3.0_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v3.0_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`Node <v3.0_infrastructure_Node>` + +* Associations: + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] + * ``nodeSpecificMonitoring`` → MonitoringRule [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [String] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + * ``disabledMonitorings`` [String] + +.. _v3.0_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v3.0_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``configs`` → ContainerConfig [0..*] + +.. _v3.0_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``host`` → ComputingNode [0..1] + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v3.0_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v3.0_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v3.0_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>` + + +.. _v3.0_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>` + +* Attributes: + * ``cost`` [Integer] + +.. _v3.0_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v3.0_commons_DeployableElement>` + + +.. _v3.0_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + * ``rules`` → MonitoringRule [0..*] + +.. _v3.0_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`Node <v3.0_infrastructure_Node>` + +* Attributes: + * ``address`` [String] + +.. _v3.0_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v3.0_infrastructure_MonitoringRule: + +MonitoringRule +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Attributes: + * ``condition`` [String] + * ``strategy`` [String] + * ``strategyConfigurationString`` [String] + +.. _v3.0_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``gateways`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + * ``cidr`` [Integer] + +.. _v3.0_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v3.0_infrastructure_Node: + +Node +"""" +*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + +.. _v3.0_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>` + + +.. _v3.0_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v3.0_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v3.0_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`Node <v3.0_infrastructure_Node>` + +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v3.0_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v3.0_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..*] + +.. _v3.0_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v3.0_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v3.0_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v3.0_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v3.0_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v3.0_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v3.0_concrete_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ComputingGroup [1..1] + +.. _v3.0_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``refs`` → ConcreteElement [0..*] +* Attributes: + * ``configurationScript`` [String] + * ``preexisting`` [Boolean] + +.. _v3.0_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v3.0_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v3.0_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v3.0_concrete_GenericResource: + +GenericResource +""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Attributes: + * ``type`` [String] + * ``gname`` [String] + +.. _v3.0_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Network [0..1] + +.. _v3.0_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>` + +* Associations: + * ``resources`` → GenericResource [0..*] + * ``vms`` → VirtualMachine [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``group`` → ComputingGroup [0..*] + +.. _v3.0_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v3.0_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] +* Attributes: + * ``image_name`` [String] + +.. _v3.0_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] + + + diff --git a/docs/reference_v3.1.rst b/docs/reference_v3.1.rst new file mode 100644 index 0000000000000000000000000000000000000000..5fcd3814cd7eb584c3ce417cee2d80ca39d517b2 --- /dev/null +++ b/docs/reference_v3.1.rst @@ -0,0 +1,696 @@ +DOML v3.1 Reference +============================= + + +commons +^^^^^^^ + +.. _v3.1_commons_BProperty: + +BProperty +""""""""" +*Inherits from* :ref:`Property <v3.1_commons_Property>` + +* Attributes: + * ``value`` [Boolean] + +.. _v3.1_commons_Configuration: + +Configuration +""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``deployments`` → Deployment [0..*] + +.. _v3.1_commons_Credentials: + +Credentials +""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + + +.. _v3.1_commons_DOMLElement: + +DOMLElement +""""""""""" +* Associations: + * ``annotations`` → Property [0..*] +* Attributes: + * ``name`` [String] + * ``description`` [String] + +.. _v3.1_commons_DeployableElement: + +DeployableElement +""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + + +.. _v3.1_commons_Deployment: + +Deployment +"""""""""" +* Associations: + * ``component`` → DeployableElement [1..1] + * ``node`` → InfrastructureElement [1..1] + +.. _v3.1_commons_FProperty: + +FProperty +""""""""" +*Inherits from* :ref:`Property <v3.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v3.1_commons_IProperty: + +IProperty +""""""""" +*Inherits from* :ref:`Property <v3.1_commons_Property>` + +* Attributes: + * ``value`` [Integer] + +.. _v3.1_commons_KeyPair: + +KeyPair +""""""" +*Inherits from* :ref:`Credentials <v3.1_commons_Credentials>` + +* Attributes: + * ``user`` [String] + * ``key`` [String] + * ``algorithm`` [String] + * ``bits`` [Integer] + +.. _v3.1_commons_ListProperty: + +ListProperty +"""""""""""" +*Inherits from* :ref:`Property <v3.1_commons_Property>` + +* Associations: + * ``values`` → Property [0..*] + +.. _v3.1_commons_Property: + +Property +"""""""" +* Associations: + * ``reference`` → DOMLElement [0..1] +* Attributes: + * ``key`` [String] + +.. _v3.1_commons_SProperty: + +SProperty +""""""""" +*Inherits from* :ref:`Property <v3.1_commons_Property>` + +* Attributes: + * ``value`` [String] + +.. _v3.1_commons_Source: + +Source +"""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``entry`` [String] + * ``inventory`` [String] + * ``backend`` [String] + +.. _v3.1_commons_UserPass: + +UserPass +"""""""" +*Inherits from* :ref:`Credentials <v3.1_commons_Credentials>` + +* Attributes: + * ``username`` [String] + * ``password`` [String] + +application +^^^^^^^^^^^ + +.. _v3.1_application_ApplicationComponent: + +ApplicationComponent +"""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v3.1_commons_DeployableElement>` + + +.. _v3.1_application_ApplicationLayer: + +ApplicationLayer +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``components`` → ApplicationComponent [0..*] + +.. _v3.1_application_DBMS: + +DBMS +"""" +*Inherits from* :ref:`SoftwareComponent <v3.1_application_SoftwareComponent>` + + +.. _v3.1_application_SaaS: + +SaaS +"""" +*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] +* Attributes: + * ``licenseCost`` [String] + +.. _v3.1_application_SaaSDBMS: + +SaaSDBMS +"""""""" +*Inherits from* :ref:`SaaS <v3.1_application_SaaS>` + +* Attributes: + * ``databaseName`` [String] + * ``engine`` [String] + * ``engineVersion`` [String] + +.. _v3.1_application_SoftwareComponent: + +SoftwareComponent +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>` + +* Associations: + * ``exposedInterfaces`` → SoftwareInterface [0..*] + * ``consumedInterfaces`` → SoftwareInterface [0..*] + * ``src`` → Source [0..1] +* Attributes: + * ``isPersistent`` [Boolean] + * ``licenseCost`` [String] + +.. _v3.1_application_SoftwareInterface: + +SoftwareInterface +""""""""""""""""" +*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>` + +* Attributes: + * ``endPoint`` [String] + +infrastructure +^^^^^^^^^^^^^^ + +.. _v3.1_infrastructure_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>` + +* Associations: + * ``machineDefinition`` → VirtualMachine [1..1] +* Attributes: + * ``min`` [Integer] + * ``max`` [Integer] + * ``loadBalancer`` [String] + +.. _v3.1_infrastructure_ComputingGroup: + +ComputingGroup +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``groupedNodes`` → ComputingNode [0..*] + +.. _v3.1_infrastructure_ComputingNode: + +ComputingNode +""""""""""""" +*Inherits from* :ref:`Node <v3.1_infrastructure_Node>` + +* Associations: + * ``location`` → Location [0..1] + * ``credentials`` → Credentials [0..1] + * ``group`` → ComputingGroup [0..1] + * ``nodeSpecificMonitoring`` → MonitoringRule [0..1] +* Attributes: + * ``architecture`` [String] + * ``os`` [String] + * ``memory_mb`` [Integer] + * ``memory_kb`` [Integer] + * ``storage`` [Integer] + * ``cpu_count`` [Integer] + * ``cost`` [Integer] + * ``disabledMonitorings`` [String] + +.. _v3.1_infrastructure_ComputingNodeGenerator: + +ComputingNodeGenerator +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``uri`` [String] + * ``kind`` [GeneratorKind] + +.. _v3.1_infrastructure_Container: + +Container +""""""""" +*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → ContainerImage [0..1] + * ``hostConfigs`` → ContainerHostConfig [0..*] + * ``networks`` → ContainerNetwork [0..*] + * ``volumes`` → ContainerVolume [0..*] + * ``dependsOn`` → Container [0..*] + +.. _v3.1_infrastructure_ContainerConfig: + +ContainerConfig +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``iface`` → NetworkInterface [0..1] +* Attributes: + * ``container_port`` [Integer] + * ``vm_port`` [Integer] + +.. _v3.1_infrastructure_ContainerGroup: + +ContainerGroup +"""""""""""""" +*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>` + +* Associations: + * ``services`` → Container [1..*] + * ``networks`` → ContainerNetwork [0..*] + * ``volumes`` → ContainerVolume [0..*] + +.. _v3.1_infrastructure_ContainerHostConfig: + +ContainerHostConfig +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``environment_variables`` → SProperty [0..*] + * ``host`` → ComputingNode [0..1] + * ``configurations`` → ContainerConfig [0..*] + +.. _v3.1_infrastructure_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v3.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedContainers`` → Container [0..*] + +.. _v3.1_infrastructure_ContainerNetwork: + +ContainerNetwork +"""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``containerNetworkName`` [String] + +.. _v3.1_infrastructure_ContainerVolume: + +ContainerVolume +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``containerVolumeName`` [String] + * ``path`` [String] + +.. _v3.1_infrastructure_ExecutionEnvironment: + +ExecutionEnvironment +"""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``location`` → Location [0..1] + * ``network`` → Network [0..1] + * ``securityGroups`` → SecurityGroup [0..*] +* Attributes: + * ``size`` [Integer] + * ``maxSize`` [Integer] + +.. _v3.1_infrastructure_ExtInfrastructureElement: + +ExtInfrastructureElement +"""""""""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>` + + +.. _v3.1_infrastructure_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>` + +* Attributes: + * ``cost`` [Integer] + +.. _v3.1_infrastructure_InfrastructureElement: + +InfrastructureElement +""""""""""""""""""""" +*Inherits from* :ref:`DeployableElement <v3.1_commons_DeployableElement>` + + +.. _v3.1_infrastructure_InfrastructureLayer: + +InfrastructureLayer +""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] + * ``generators`` → ComputingNodeGenerator [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``credentials`` → Credentials [0..*] + * ``groups`` → ComputingGroup [0..*] + * ``securityGroups`` → SecurityGroup [0..*] + * ``networks`` → Network [0..*] + * ``rules`` → MonitoringRule [0..*] + * ``executionEnvironments`` → ExecutionEnvironment [0..*] + +.. _v3.1_infrastructure_InternetGateway: + +InternetGateway +""""""""""""""" +*Inherits from* :ref:`Node <v3.1_infrastructure_Node>` + +* Attributes: + * ``address`` [String] + +.. _v3.1_infrastructure_Location: + +Location +"""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``region`` [String] + * ``zone`` [String] + +.. _v3.1_infrastructure_MonitoringRule: + +MonitoringRule +"""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``condition`` [String] + * ``strategy`` [String] + * ``strategyConfigurationString`` [String] + +.. _v3.1_infrastructure_Network: + +Network +""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``connectedIfaces`` → NetworkInterface [0..*] + * ``gateways`` → InternetGateway [0..*] + * ``subnets`` → Subnet [0..*] +* Attributes: + * ``protocol`` [String] + * ``cidr`` [Integer] + +.. _v3.1_infrastructure_NetworkInterface: + +NetworkInterface +"""""""""""""""" +*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``belongsTo`` → Network [0..1] + * ``associated`` → SecurityGroup [0..1] +* Attributes: + * ``endPoint`` [Integer] + * ``speed`` [String] + +.. _v3.1_infrastructure_Node: + +Node +"""" +*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>` + +* Associations: + * ``ifaces`` → NetworkInterface [0..*] + +.. _v3.1_infrastructure_PhysicalComputingNode: + +PhysicalComputingNode +""""""""""""""""""""" +*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>` + +* Associations: + * ``configInterface`` → NetworkInterface [0..1] + +.. _v3.1_infrastructure_Rule: + +Rule +"""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Attributes: + * ``kind`` [String] + * ``protocol`` [String] + * ``fromPort`` [Integer] + * ``toPort`` [Integer] + * ``cidr`` [String] + +.. _v3.1_infrastructure_SecurityGroup: + +SecurityGroup +""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``rules`` → Rule [0..*] + * ``ifaces`` → NetworkInterface [0..*] + +.. _v3.1_infrastructure_Storage: + +Storage +""""""" +*Inherits from* :ref:`Node <v3.1_infrastructure_Node>` + +* Attributes: + * ``label`` [String] + * ``size_gb`` [Integer] + * ``cost`` [Integer] + +.. _v3.1_infrastructure_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v3.1_infrastructure_Network>` + +* Associations: + * ``connectedTo`` → Network [0..*] + +.. _v3.1_infrastructure_Swarm: + +Swarm +""""" +*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>` + +* Associations: + * ``roles`` → SwarmRole [0..*] + +.. _v3.1_infrastructure_SwarmRole: + +SwarmRole +""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``nodes`` → ComputingNode [0..*] +* Attributes: + * ``kind`` [String] + +.. _v3.1_infrastructure_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ComputingNodeGenerator <v3.1_infrastructure_ComputingNodeGenerator>` + +* Associations: + * ``generatedVMs`` → VirtualMachine [0..*] + +.. _v3.1_infrastructure_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>` + +* Associations: + * ``generatedFrom`` → VMImage [0..1] + * ``configInterface`` → NetworkInterface [0..1] +* Attributes: + * ``sizeDescription`` [String] + +concrete +^^^^^^^^ + +.. _v3.1_concrete_AutoScalingGroup: + +AutoScalingGroup +"""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → AutoScalingGroup [0..1] +* Attributes: + * ``vm_type`` [String] + +.. _v3.1_concrete_ConcreteElement: + +ConcreteElement +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``refs`` → ConcreteElement [0..*] +* Attributes: + * ``resourceName`` [String] + * ``configurationScript`` [String] + * ``preexisting`` [Boolean] + +.. _v3.1_concrete_ConcreteInfrastructure: + +ConcreteInfrastructure +"""""""""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``providers`` → RuntimeProvider [0..*] + +.. _v3.1_concrete_ContainerImage: + +ContainerImage +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ContainerImage [0..1] + +.. _v3.1_concrete_ExecutionEnvironment: + +ExecutionEnvironment +"""""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → ExecutionEnvironment [0..1] +* Attributes: + * ``instance_type`` [String] + * ``storage_type`` [String] + +.. _v3.1_concrete_FunctionAsAService: + +FunctionAsAService +"""""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → FunctionAsAService [0..1] + +.. _v3.1_concrete_GenericResource: + +GenericResource +""""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Attributes: + * ``type`` [String] + +.. _v3.1_concrete_Network: + +Network +""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``subnets`` → Subnet [0..*] + * ``maps`` → Network [0..1] +* Attributes: + * ``protocol`` [String] + * ``addressRange`` [String] + +.. _v3.1_concrete_RuntimeProvider: + +RuntimeProvider +""""""""""""""" +*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>` + +* Associations: + * ``resources`` → GenericResource [0..*] + * ``vms`` → VirtualMachine [0..*] + * ``executionEnvironments`` → ExecutionEnvironment [0..*] + * ``vmImages`` → VMImage [0..*] + * ``containerImages`` → ContainerImage [0..*] + * ``networks`` → Network [0..*] + * ``storages`` → Storage [0..*] + * ``faas`` → FunctionAsAService [0..*] + * ``autoScalingGroups`` → AutoScalingGroup [0..*] + +.. _v3.1_concrete_Storage: + +Storage +""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → Storage [0..1] + +.. _v3.1_concrete_Subnet: + +Subnet +"""""" +*Inherits from* :ref:`Network <v3.1_concrete_Network>` + + +.. _v3.1_concrete_VMImage: + +VMImage +""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VMImage [0..1] +* Attributes: + * ``image_name`` [String] + +.. _v3.1_concrete_VirtualMachine: + +VirtualMachine +"""""""""""""" +*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>` + +* Associations: + * ``maps`` → VirtualMachine [0..1] +* Attributes: + * ``vm_type`` [String] + + + diff --git a/docs/requirements.rst b/docs/requirements.rst index f5197401f11658bfe1162dc45eecfd9751506c16..913bbc05e493da6f30c9852d9a5fb3a131caaf4f 100644 --- a/docs/requirements.rst +++ b/docs/requirements.rst @@ -1,16 +1,20 @@ -Checked Requirements -==================== +Built-in Requirements +===================== The DOML Model Checker verifies DOML models against a collection of requirements devised to highlight the most common mistakes made by users when specifying cloud deployments. Here we list and describe such requirements. +You may find examples of violations for each one of these requirements under the ``tests/doml`` directory. + VM Network Interfaces --------------------- All virtual machines must be connected to at least one network interface. +ID: ``vm_has_iface`` + Virtual machines can communicate with other components of a deployment or with external clients only through an appropriately configured network. this check makes sure no virtual machines are isolated. @@ -21,6 +25,8 @@ Concretization of Software Interfaces All software packages can see the interfaces they need through a common network. +ID: ``software_package_iface_net`` + This check makes sure all exposed and consumed software interfaces at the application layer level have been actually concretized through a network connection that allows the involved components to communicate. @@ -31,7 +37,9 @@ Duplicated Interfaces There are no duplicated interfaces. -Checks whether two or more interfaces have been assigned the same IP address in the same network. +ID: ``iface_uniq`` + +Checks whether two or more interfaces have been assigned the same IP address. Deployed Software Components @@ -39,6 +47,8 @@ Deployed Software Components All software components have been deployed to some node. +ID: ``all_software_components_deployed`` + Makes sure that all software components specified in the application layer have been associated to at least one node in the abstract infrastructure layer through the currently active deployment. @@ -49,4 +59,57 @@ Concretization of Abstract Infrastructure All abstract infrastructure elements are mapped to an element in the active concretization. -Makes sure all abstract infrastructure are concretized by the currently active concretization layer. +ID: ``all_infrastructure_elements_deployed`` + +Makes sure all abstract infrastructure nodes are concretized by the currently active concretization layer. + + +Concrete Infrastructure Elements have a maps Association +-------------------------------------------------------- + + All elements in the active concretization are mapped to some abstract infrastructure element. + +ID: ``all_concrete_map_something`` + +Makes sure each concrete infrastructure element is mapped to a node in the Abstract Infrastructure Layer. + + +Network Interfaces belong to a Security Group +--------------------------------------------- + + All network interfaces belong to a security group. + +ID: ``security_group_must_have_iface`` + +Makes sure all network interfaces have been configured to belong to a security group. +This way, the user will be reminded to configure adequate rules for each network. + + +Virtual Machines in AutoScaleGroup should not be present in Concretization +-------------------------------------------------------------------------- + +ID: ``concrete_asg_no_vm`` + +*Available from DOML v2.2+* + +Makes sure a VM present inside an AutoScaleGroup in the Infrastructure Layer is not present +and mapped in the Concretization layer. + +Virtual Machines that host a container need an OS +------------------------------------------------- + +*Available from DOML v2.2+* + +Makes sure a VM hosting a container has the OS field present. + +.. Deprecated + +.. External Services are reached through HTTPS +.. ------------------------------------------- + +.. All external SaaS can be reached only through a secure connection. + +.. ID: ``external_services_must_have_https`` + +.. Makes sure that an HTTPS rule is enforced for a Network Interface of a Software Component that interfaces with a SaaS. + diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..9e279e79d32427f119426d5f3ec50ce026c4daa9 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +furo \ No newline at end of file diff --git a/docs/tests.rst b/docs/tests.rst new file mode 100644 index 0000000000000000000000000000000000000000..e212c3790a33ad7c99dbee46c21feda903846461 --- /dev/null +++ b/docs/tests.rst @@ -0,0 +1,12 @@ +Testing +======= + +To run the tests with *PyTest* you'll need to setup the server:: + + python -m mc_openapi + +and then run separately:: + + python -m pytest + +Currently, a few tests are run for each supported DOML version. \ No newline at end of file diff --git a/docs/usage.rst b/docs/usage.rst index 0b9c29f39340dc9a2f19c0f639740bd4c4f8000e..0d0478bd24785447bd89fe271474f2acb7e8ff39 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,9 +1,9 @@ -Usage through the PIACERE IDE -============================= +Usage +***** -Invoking the DOML Model Checker from the PIACERE IDE ------------------------------------------------------ +Through the PIACERE IDE +======================= The DOML Model Checker is usually invoked from the PIACERE IDE. It expects a DOML file in XMI format as its input, @@ -48,3 +48,62 @@ and then choose *Piacere* -> *Model Checker Preferences*. Here you may enter the endpoint address and port, which is useful in case you want to run the DOML Model Checker locally, instead of using the official deployment. + +Through the Command Line Interface +================================== + +Another way to use the model checker is through the CLI. +It provides additional options that are not available in the IDE at +the moment, such as support for a separate user requirement file +and synthesis of DOMLX. + +You can run it with:: + + python -m mc_openapi [options] + +To display all the available flags, run:: + + python -m mc_openapi -h + +Options +------- + +Please note that not all flags work with eachother. In most cases, some won't have +any effect in certain CLI flags combinations. + +There are **3 Modes** in which the CLI can run: + +- REST API (**R**) +- Model Checker (**C**) +- Model Synthesis (**S**) + +====== ========================= ========= ================= +Flags Mode Description +--------------------------------- --------- ----------------- +Short Long +====== ========================= ========= ================= +``-h`` ``--help`` C, S, R Print the all the available flags with an explanation +``-v`` ``--verbose`` C, S, R Print a detailed human-readable output of everything going on. Helpful for debugging +``-p`` ``--port`` R The port that will expose the REST API (default: 8080) +``-d`` ``--doml`` C, S The DOMLX file to check with the model checker +``-V`` ``--doml-version`` C, S The DOML version in which the DOMLX file is written in +``-r`` ``--requirements`` C, S A text file containing the user-defined requirements written in :doc:`DOMLR <writing-requirements>`. +``-S`` ``--skip-common-checks`` C Skips :doc:`build-in requirements <requirements>` checks +``-c`` ``--check-consistency`` C Perform additional consistency checks (legacy) +``-t`` ``--threads`` C, R The number of threads used by the model checker (default: 2) +``-s`` ``--synth`` S Synthetize a new DOMLX file from requirements +``-m`` ``--max-tries`` S Max number of tries to solve a model during synthesis (default: 10) +====== ========================= ========= ================= + +*If you do not provide the ``--doml`` option or the ``--synth`` option it will start the web server hosting the REST API!* + +Examples +-------- + +To check a DOMLX file with user-provided custom requirements, you may run:: + + python -m mc_openapi -d ./path/to/myModel.domlx -r ./path/to/myRequirements.domlr -V V2_0 + +To synthetize a new DOMLX file with 4 threads and a maximum of 15 tries, you may run:: + + python -m mc_openapi -d ./path/to/myModel.domlx --synth -m 15 \ No newline at end of file diff --git a/docs/writing-requirements.rst b/docs/writing-requirements.rst new file mode 100644 index 0000000000000000000000000000000000000000..a9d87d7493bf4a0a9e21816be1decf89f10e390b --- /dev/null +++ b/docs/writing-requirements.rst @@ -0,0 +1,191 @@ +Writing Requirements +******************** + +A feature of the DOML Model Checker is a Domain Specific Language (DSL) +called **DOMLR** (the R stands for requirements). + +It will be integrated in the DOML in a future release. +For now, it can be provided to the Model Checker through the CLI. + +Getting Started +=============== + +At the moment, you can integrate the requirements inside DOML using the ``functional_requirements`` field:: + + functional_requirements { + req_group_1 ``` + # Your DOMLR goes here. + ```; + req_group_2 ``` + # Other set of requirements + ```; + } + + +If you want to write a snippet of DOMLR using VS Code, there's a `Syntax Highlight`_ extension for it. + +Every DOMLR piece of code is a list of requirement:: + + + "All Virtual Machines have a Interface and at least 4 cpu cores" + forall vm ( + vm is class abstract.VirtualMachine + implies + exists iface ( + vm has abstract.ComputingNode.ifaces iface + and + vm has abstract.ComputingNode.cpu_count >= 4 + ) + ) + error: "A vm lacks an associated interface or has less than 4 CPUs" + +Rules in 1 minute +----------------- + +The language is *case-sensitive* but it's not indentation-based, so you are free to write it as you prefer. + +1. A requirement must **start** with a ``+`` or ``-`` character. + + - ``+`` means that the requirement is in **positive form**: the requirement is satisfied when its logic expression is satisfied. + + - ``-`` means that the requirement is in **negative form**: the requirement is satisfied when its logic expression **is not** satisfied. + +2. After the ``+`` or ``-`` there's the **name** of the requirement, which is a string between double quotes ``"..."``. + Single quotes ``'...'`` won't work. + +3. Following the requirement name, there's the **logic expression** which is the core of the requirement. + It is written in `First Order Logic`_, so it will evaluate to either true or false. See the `Syntax`_ for details. + +4. Last, following ``error:``, there is the **error message** that is printed when the requirement is not satisfied. + If you have a free variable, which means a variable that is not quantified, you can print its value by putting it in the + string between curly brackets like this: ``{myVar}``. You'll get a warning if the Model Checker can't assign a value to that variable. + +A note on positive and negative form +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The difference is that in **positive form** you would generally use a *for all* quantifier at the beginning, +which doesn't allow you to know which specific element didn't satisfy the requirement, while in **negative form** +you'll have some variables that are not quantified, meaning that it's usually possible to retrieve the names of the +elements associated to those variables that do not satisfy the requirement. **Negative form** is usually faster, you +can convert an expression into it using :math:numref:`logicconv`, where :math:`P(x)` is a statement containing quantified variable :math:`x`. + +.. math:: \forall x P(x) \iff \neg\exists x \neg P(x) + :label: logicconv + +.. `Syntax`: + +Syntax +====== + +The syntax is the following: + +- Unary operators: ``not`` + - Example: ``not <expression>`` +- Binary operators: ``or``, ``and``, ``implies``, ``iff`` (if and only if, AKA double implication) + - Example: ``<expression> and <expression>`` +- Quantifiers: ``forall``, ``exists`` + - Example: ``forall x, y ( <expression> )`` + - After the quantifier keywork (``forall``, ``exists``) you must specify a list of quantified variables + (separated by a comma ``,`` if there's more than one). + - Between the mandatory pair of parenthesis, you'll be able to use the quantified variables in a logic expression. +- Parenthesis: ``(`` ... ``)`` + - Useful when you have doubts about the precedence of operators, or want to increase legibility in certain situations. +- Elements (variables): + - Begin with a lowercase letter. + - Example: ``virtualMachine`` or ``vm`` +- Values (constants): + - Strings are delimited by double quotes ``"..."`` + - Numbers are integers. + - Booleans are either ``:true`` or ``:false`` + - Example: ``56``, ``"linux"``, ``:true`` +- Relationships: ``<elem> has <relationship> <elem/value>`` + - There are two types of relationships: + - **Associations** are a relationship between two elements (variables). + - **Attributes** are a relationship between an element (variable) and a value (variable or constant). + - Relationships follow this naming structure ``<package>.<class>.<relationship>``. + - Example: + - ``vm has abstract.ComputingNode.ifaces iface`` is an **Association**, as it puts in relationship the element ``vm`` with the element ``iface``. + + - ``vm has abstract.ComputingNode.cpu_count >= 4`` is an **Attribute** Relationship, as it compares a property (``cpu_count``) of the element ``vm`` with a constant number. +- Classes: ``class <class name>`` + - They represent a kind of element in the architecture. + - Classes follow this naming structure ``<package>.<class>`` +- Equality: ``is``, ``is not`` + - Used to set an equality (or inequality) constraint on an element variable. You can use it to assign a class to an element. + - Example: ``vm is class abstract.VirtualMachine`` +- Comparisons: ``>``, ``>=``, ``<``, ``<=``, ``==``, ``!=`` + - You can compare attributes with constants, or attributes with attributes. + - Example: + - ``vm has abstract.ComputingNode.cpu_count >= 4`` compares attribute ``cpu_count`` with a numeric constant. + - ``vm1 has abstract.ComputingNode.cpu_count >= vm2 abstract.ComputingNode.cpu_count`` compares attribute ``cpu_count`` of ``vm1`` with the one of ``vm2``. + + + +Operator Precedence +------------------- + +``exists``/``forall`` > ``not`` > ``or`` > ``and`` > ``implies`` > ``iff`` + +Examples +======== + +1. State that an element must be of a certain class:: + + saas is class application.SaaS + +2. Check that an element has a certain relationship with another:: + + vm has infrastructure.ComputingNode.ifaces iface + +Note that in the above example we haven't said anything about the nature of ``vm``. +We get that ``iface`` is of class ``NetworkInterface`` for free since the association ``infrastructure.ComputingNode.ifaces`` requires it. +If you want ``vm`` to be a `VirtualMachine` you should specify it as:: + + vm is class infrastructure.VirtualMachine + and + vm has infrastructure.ComputingNode.ifaces iface + +3. State that all VMs have to use less than 1 GB of memory:: + + forall vm ( + vm is class infrastructure.VirtualMachine + implies + vm has infrastructure.ComputingNode.memory_mb <= 1024 + ) + +We use ``forall`` to say that all ``vm``, **if** (that's what ``implies`` does) ``vm`` that are ``VirtualMachine``, +then it should have less than 1024 MB (memory here is expressed in MB). + +If we want to rewrite this requirement in negative form, it becomes *'There is a VM that has more than 1 GB'*. If there exists such VM, then it means that +the expression is *true*, therefore the requirement is *false*:: + + exists vm ( + vm is class infrastructure.VirtualMachine + and + vm has infrastructure.ComputingNode.memory_mb > 1024 + # we can also write it as a negation + or not vm has infrastructure.ComputingNode.memory <= 1024 + ) + +4. Compare two attributes of two elements. Let's say that you have two different containers, ``c1`` and ``c2``, and you want to require +that the memory used by ``c1`` is less than the one used by ``c2`` (note that we don't put another ``has`` in the expression in right hand side of ``<``):: + + c1 has infrastructure.ComputingNode.memory_mb < c2 infrastructure.ComputingNode.memory_mb + +Flags +===== +You can alter the behaviour of the model checker through flags, which are simple parameters you can put at the beginnning of DOMLR. + +They are the following: + - ``%IGNORE <id of requirement>`` skips a specific built-in requirement. + - ``%IGNORE_BUILTIN`` skips all built-in requirements. + - ``%CHECK <id of requirement>`` enables an optional requirement. + - ``%CHECK_CONSISTENCY`` enables optional consistency checks. + - ``%CSP`` enables a Cloud Service Provider compatibility report, that is appended to the results. + +Grammar +======= +See the `grammar.lark`_ file on GitHub, it's written in a EBNF-like form. + + +.. _`Syntax Highlight`: https://marketplace.visualstudio.com/items?itemName=andreafra.piacere-domlr +.. _`First Order Logic`: https://en.wikipedia.org/wiki/First-order_logic +.. _`grammar.lark`: https://github.com/andreafra/piacere-model-checker/blob/main/mc_openapi/doml_mc/domlr_parser/grammar.lark \ No newline at end of file diff --git a/gen_domlr_reference.py b/gen_domlr_reference.py new file mode 100644 index 0000000000000000000000000000000000000000..336e1299b7d1360c37f962bbfea68fa4f01de43a --- /dev/null +++ b/gen_domlr_reference.py @@ -0,0 +1,52 @@ +from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion, MetaModels +from pprint import pprint +from itertools import groupby + +DOCS_PATH = lambda version: f"docs/reference_{version}.rst" + +DOML_VERSIONS = [v for v in DOMLVersion] + +with open(DOCS_PATH('index'), 'w') as findex: + print("DOML Reference", file=findex) + print("==============\n", file=findex) + print("For a comprehensive list of all the classes, attributes and associations supported in the DOML Model Checker and DOMLR, please consult one of the following pages.\n", file=findex) + + for version in DOML_VERSIONS: + v_name = f':doc:`Reference for DOML {version.value} <reference_{version.value}>`' + print(v_name, file=findex) + print('-'*len(v_name), file=findex) + + with open(DOCS_PATH(version.value), 'w') as f: + print(f"DOML {version.value} Reference", file=f) + print("=============================\n", file=f) + + MM = MetaModels[version] + # ITEM => (package, class, assoc, attrs) + ITEMS = [(*(k.split("_", 1)), v.superclass, v.associations, v.attributes) for k, v in MM.items()] + # PKG => CLASS => {ASSOC, ATTRS} + ITEMS = {k: [dict(zip(("name", "superclass", "assocs", "attrs"), (x[1], x[2], x[3], x[4]))) for x in v] for k, v in groupby(ITEMS, key=lambda x: x[0])} + + for pkg, clss in ITEMS.items(): + print(f'\n{pkg}', file=f) + print('^'*(len(pkg)), file=f) + for cls in sorted(clss, key=lambda x: x.get('name')): + name = cls.get('name') + supcls = cls.get('superclass') + print(f'\n.. _{version.value}_{pkg}_{name}:', file=f) + print(f'\n{name}', file=f) + print('"'*(len(name)), file=f) + if supcls: + supcls_name = supcls.split("_", 1)[1] + print(f'*Inherits from* :ref:`{supcls_name} <{version.value}_{supcls}>`\n', file=f) + if (cls.get('assocs')): + print(f'* Associations:', file=f) + for assoc_k, assoc_v in cls.get('assocs').items(): + dest_cls = assoc_v.class_.split("_", 1)[1] + print(f'\t* ``{assoc_k}`` → {dest_cls} [{assoc_v.multiplicity[0]}..{assoc_v.multiplicity[1]}]', file=f) + if (cls.get('attrs')): + print(f'* Attributes:', file=f) + for attr_k, attr_v in cls.get('attrs').items(): + print(f'\t* ``{attr_k}`` [{attr_v.type}]', file=f) + print("\n\n", file=f) + + print(f"Generated new reference for DOML {version.value} in {DOCS_PATH(version.value)}") \ No newline at end of file diff --git a/mc_openapi/.DS_Store b/mc_openapi/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..01112e0e1922d230be7ee15c2e102e5c89780591 Binary files /dev/null and b/mc_openapi/.DS_Store differ diff --git a/mc_openapi/__init__.py b/mc_openapi/__init__.py index 7fd229a32b5eefeffa54b9c187302d2c03a0a680..dc0a25b72c93dd2fc3e20ee0638423e5037c330a 100644 --- a/mc_openapi/__init__.py +++ b/mc_openapi/__init__.py @@ -1 +1 @@ -__version__ = '0.2.0' +__version__ = '3.1.3' diff --git a/mc_openapi/__main__.py b/mc_openapi/__main__.py index 4289b5dfd801aafbfdaced9b7877ca948fda7523..7b91937b4b38b5b12bc986b33eae6790d7e13528 100644 --- a/mc_openapi/__main__.py +++ b/mc_openapi/__main__.py @@ -1,5 +1,139 @@ #!/usr/bin/env python3 +import argparse +import logging +from logging.config import dictConfig +import re +import traceback -from mc_openapi.app_config import app +from tabulate import tabulate +import uvicorn -app.run(port=8080) +from mc_openapi.api import app +from mc_openapi.doml_mc import DOMLVersion, init_model, verify_csp_compatibility, verify_model, synthesize_model +from mc_openapi.doml_mc.domlr_parser.exceptions import RequirementException +from mc_openapi.doml_mc.mc_result import MCResult + +from . import __version__ + +parser = argparse.ArgumentParser() + +parser.add_argument("-d", "--doml", dest="doml", help="the DOMLX file to check") +parser.add_argument("-V", "--doml-version", dest="doml_version", help="(optional) the version used by the DOMLX file") +parser.add_argument("-r", "--requirements", dest="requirements", help="the user-specified requirements file to check") +parser.add_argument("-p", "--port", dest="port", type=int, default=8080, help="the port exposing the model checker REST API (default: 8080)") +parser.add_argument("-v", "--verbose", dest="verbose", action='store_true', help="print a detailed human-readable output of everything going on. Helpful for debugging.") +# Model Checker +parser.add_argument("-c", "--check-consistency", dest="consistency", action='store_true', help="check on additional built-in consistency requirements") +parser.add_argument("-S", "--skip-builtin-checks", dest="skip_builtin", action='store_true', help="skip check on built-in requirements") +parser.add_argument("-C", "--csp", dest="csp", action='store_true', help="check compatibility with supported CSPs") +parser.add_argument("-t", "--threads", dest="threads", type=int, default=2, help="number of threads used by the model checker") + +# Synthesis +parser.add_argument("-s", "--synth", dest="synth", action='store_true', help="synthetize a new DOMLX file from requirements") +parser.add_argument("-m", "--max-tries", dest="tries", type=int, default=8, help="max number of iteration while trying to solve the model with unbounded variables") + +args = parser.parse_args() + +def print_csp_results(results): + for csp_k, csp_v in results.items(): + # Format items in minreq + if csp_k == 'minreq': + for row in csp_v: + for index, col in enumerate(row): + if index > 0 and isinstance(col, list): + row[index] = "\n".join(col) + + print(tabulate(csp_v, headers='firstrow', tablefmt='fancy_grid')) + +if not args.doml and not args.synth: + dictConfig({ + 'version': 1, + 'formatters': {'default': { + 'format': '[%(asctime)s] %(levelname)s: %(message)s', + }}, + 'root': { + 'level': 'DEBUG', + } + }) + logging.info(f"DOML Model Checker v{__version__}") + + # Start the webserver + uvicorn.run(app, port=args.port) + # No actions allowed after uvicorn startup point +else: + logging.basicConfig(level=logging.DEBUG, format='* %(message)s') + logging.info(f"DOML Model Checker v{__version__}") + + doml_path = args.doml + domlr_path = args.requirements + + # Validate user-provided DOML version + doml_ver = None + if args.doml_version is not None: + try: + doml_ver = DOMLVersion.get(args.doml_version) + except: + # Suggest valid DOML versions + print(f"Unknown DOML version '{args.doml_version}'") + versions = [ ver.name for ver in list(DOMLVersion)] + print(f"Available DOML versions = {versions}") + exit(1) + + # Read DOMLX from path + with open(doml_path, "rb") as xmif: + # Read DOML file from path + doml_xmi = xmif.read() + + try: + # Read DOMLR from path + domlr_src = None + if domlr_path: + with open(domlr_path, "r") as domlr_file: + # Read the user requirements written in DSL + domlr_src = domlr_file.read() + + # Config the model checker + dmc = init_model(doml_xmi, doml_ver) + ####### END OF INIT STEP ####### + if not args.synth: # Verify Model/CSP Compatibility + + # Check CSP Compatibility + if args.csp: + csp = verify_csp_compatibility(dmc) + print_csp_results(csp) + else: + + res = verify_model(dmc, domlr_src, args.threads, args.consistency, args.skip_builtin) + + print("[RESULT]") + if res['result'] == MCResult.sat.name: + print(res['description']) + + print("[STATS]") + for result in res['all_reqs']: + print(f"\t{result['id']} - {result['time']} - {result['result']}") + else: + print(res['result']) + print("[ERRORS]") + print("\033[91m{}\033[00m".format(res['description'])) + + print("[STATS]") + for result in res['all_reqs']: + print(f"\t{result['id']} - {result['time']} - {result['result']}") + + csp_res = res.get('csp') + if csp_res: + print("[CSP COMPATIBILITY RESULTS]") + print_csp_results(csp_res) + else: # Synthesis + synthesize_model(dmc, domlr_src, args.tries) + # TODO: Do something with the results + + except Exception as e: + MSG_ERR_GENERIC = "An unknown error has occurred!\nTry with '-t 1' to get more detailed logs!\n\n" + err_msg = (e.message + if hasattr(e, 'message') + else MSG_ERR_GENERIC + traceback.format_exc()) + print(f"\033[91m[ERROR]\n{err_msg}\033[00m") + + \ No newline at end of file diff --git a/mc_openapi/api.py b/mc_openapi/api.py new file mode 100644 index 0000000000000000000000000000000000000000..435f36a480fa4ade358d4988ba84bb2f6e328e5f --- /dev/null +++ b/mc_openapi/api.py @@ -0,0 +1,110 @@ +import logging +from logging.config import dictConfig +import os +import sys +import traceback +from importlib.resources import files + +from fastapi import FastAPI, Request +from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from fastapi.encoders import jsonable_encoder +from fastapi.logger import logger + +import mc_openapi.assets as ASSETS +from mc_openapi.doml_mc import (init_model, verify_csp_compatibility, + verify_model) +from mc_openapi.doml_mc.exceptions import * +from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion +from mc_openapi.doml_mc.mc import ModelChecker +import time + +assets = files(ASSETS) +static_path = assets / "static" +templates_path = assets / "templates" +app = FastAPI() + +print(">>> FastAPI+Uvicorn is incredibly asinine when it comes to logs, so lines prefixed with '>>>' are actually print(...)") +print(">>> API starting up...") + +app.mount("/static", StaticFiles(directory=static_path), name="static") + +templates = Jinja2Templates(directory=templates_path) + +@app.get("/", response_class=HTMLResponse) +async def root(request: Request): + return templates.TemplateResponse("home.html", {"request": request}) + +def handleDOMLX(doml_xmi: bytes, callback) -> dict: + doml_version_str: str = None + doml_version: DOMLVersion = None + start_time = time.time() + + print(">>> Received DOMLX. Beginning validation...") + + try: + # First try to infer DOML version from ENV, then query params + doml_version_str = os.environ.get("DOML_VERSION") + + if doml_version_str: + doml_version = DOMLVersion.get(doml_version_str) + print(f">>> Forcing DOML {doml_version.value}") + + dmc = init_model(doml_xmi, doml_version) + + res = callback(dmc) + + elapsed_time_in_seconds = f"{time.time() - start_time:.4f}" + + print(f">>> Validation complete. It took {elapsed_time_in_seconds}s.") + res['elapsed_time'] = elapsed_time_in_seconds + + return res + except KeyError as e: + ERR_MSG = f"Error: Key '{e.args[0]}' not found.\nVery likely, in the Model Checker requirements, the relationship '{e.args[0]}' is unknown.\nPerhaps this was parsed with the wrong DOML version, otherwise the DOML version you're using is currently unsupported." + logging.exception(e) + return { + "type": "error", + "message": ERR_MSG, + "debug_message": traceback.format_exc() + } + except (RuntimeError, Exception) as e: + ERR_MSG = "An error has occurred.\nIt could be an error within your DOML file.\nIf it persist, try specifying DOML version manually." + logging.exception(e) + return { + "type": "error", + "message": e.message if hasattr(e, 'message') else ERR_MSG, + "debug_message": traceback.format_exc() + } + +@app.post("/modelcheck") +async def mc(request: Request): + doml_xmi = await request.body() + return handleDOMLX(doml_xmi, verify_model) + +@app.post("/csp") +async def csp(request: Request): + doml_xmi = await request.body() + return handleDOMLX(doml_xmi, verify_csp_compatibility) + +@app.post("/modelcheck_html") +async def mc_html(request: Request): + doml_xmi = await request.body() + res = handleDOMLX(doml_xmi, verify_model) + print(res) + if res.get("type") == "error": + return templates.TemplateResponse("error.html", {"request": request, **res}) + else: + return templates.TemplateResponse("mc.html", {"request": request, **res}) + + +@app.post("/csp_html") +async def csp_html(request: Request): + doml_xmi = await request.body() + res = handleDOMLX(doml_xmi, verify_csp_compatibility) + if res.get("type") == "error": + return templates.TemplateResponse("error.html", {"request": request, **res}) + else: + return templates.TemplateResponse("csp.html", {"request": request, **res}) + \ No newline at end of file diff --git a/mc_openapi/app_config.py b/mc_openapi/app_config.py deleted file mode 100644 index e60da49a058797b966cf9de426f0000d98daa4e3..0000000000000000000000000000000000000000 --- a/mc_openapi/app_config.py +++ /dev/null @@ -1,6 +0,0 @@ -import connexion - -app = connexion.App(__name__, specification_dir='openapi/') -app.add_api('model_checker.yaml') - -application = app.app diff --git a/mc_openapi/assets/csp/arch.yml b/mc_openapi/assets/csp/arch.yml new file mode 100644 index 0000000000000000000000000000000000000000..bfdc5f2611d9b7d1676fad1d337a398df10c38a8 --- /dev/null +++ b/mc_openapi/assets/csp/arch.yml @@ -0,0 +1,16 @@ +# CSP Name +aws: + - x86 + - x86_64 + - ARM64 + +gcp: + - x86 + - ARM + +azure: + - x86 + - ARM + +# bad_csp: +# - PowerPC diff --git a/mc_openapi/assets/csp/keypair.yml b/mc_openapi/assets/csp/keypair.yml new file mode 100644 index 0000000000000000000000000000000000000000..b9083df88b50130dc3bd1362223cb0e50f4db2a5 --- /dev/null +++ b/mc_openapi/assets/csp/keypair.yml @@ -0,0 +1,24 @@ +# CSP Name +aws: + - RSA + - ED25519 + - ECDSA + + +azure: + - RSA + - RSA1_5 + - RSA-OAEP + - RSA-OAEP-256 + - EC + - P-256 + - P-256K + - P-384 + - P-521 +gcp: + - Elliptic Curve + - RSA + - ECDSA + +# bad_csp: +# - OLD_ALGO diff --git a/mc_openapi/assets/csp/minimum_setup.yml b/mc_openapi/assets/csp/minimum_setup.yml new file mode 100644 index 0000000000000000000000000000000000000000..05448f3eb52dace7f685f17d2a57cc53a80dc360 --- /dev/null +++ b/mc_openapi/assets/csp/minimum_setup.yml @@ -0,0 +1,16 @@ +aws: + - infrastructure_ComputingNode::os # AMI + # - an Instance Type + # - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::associated] # NetworkInterface + - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::belongsTo] # NetworkInterface + - infrastructure_ComputingNode::credentials # KeyPair + +azure: + - infrastructure_ComputingNode::os # OS Image + - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::belongsTo] # NetworkInterface + - infrastructure_ComputingNode::storage # Storage/VMSize + +gcp: + # - infrastructure_ComputingNode::location + - infrastructure_ComputingNode::os # OS Image + - infrastructure_ComputingNode::architecture \ No newline at end of file diff --git a/mc_openapi/assets/csp/os.yml b/mc_openapi/assets/csp/os.yml new file mode 100644 index 0000000000000000000000000000000000000000..9a5060edfbe201a900bab603f44ba74a1f5a52bf --- /dev/null +++ b/mc_openapi/assets/csp/os.yml @@ -0,0 +1,41 @@ +aws: + Linux: + - Amazon Linux + - Amazon Linux 2 + - Bottlerocket + - CentOS + - Debian Server + - Oracle Linux + - Red Hat Enterprise Linux (RHEL) + - Rocky Linux + - SUSE Linux Enterprise Server (SLES) + - Ubuntu Server + macOS: + - macOS + Windows Server: + - Windows Server + +azure: + Linux: + - Red Hat Enterprise Linux + - CentOS + - CoreOS + - Debian + - Oracle Linux + - SUSE Linux Enterprise + - openSUSE + - Ubuntu + Windows Server: + - Windows Server + +gcp: + Linux: + - Amazon Linux + - Amazon Linux 2 + - CentOS + - Debian + - Red Hat Enterprise Linux (RHEL) + - SUSE Linux Enterprise + - Ubuntu + Windows Server: + - Windows Server \ No newline at end of file diff --git a/mc_openapi/assets/csp/region.yml b/mc_openapi/assets/csp/region.yml new file mode 100644 index 0000000000000000000000000000000000000000..8b9e1d62578265a61dd0eb2130c04bd6d5548b54 --- /dev/null +++ b/mc_openapi/assets/csp/region.yml @@ -0,0 +1,174 @@ +aws: + - us-east-2 + - us-east-1 + - us-west-1 + - us-west-2 + - af-south-1 + - ap-east-1 + - ap-south-2 + - ap-southeast-3 + - ap-southeast-4 + - ap-south-1 + - ap-northeast-3 + - ap-northeast-2 + - ap-southeast-1 + - ap-southeast-2 + - ap-northeast-1 + - ca-central-1 + - eu-central-1 + - eu-west-1 + - eu-west-2 + - eu-south-1 + - eu-west-3 + - eu-south-2 + - eu-north-1 + - eu-central-2 + - me-south-1 + - me-central-1 + - sa-east-1 + - us-gov-east-1 + - us-gov-west-1 + +gcp: + - asia-east1-a + - asia-east1-b + - asia-east1-c + - asia-east2-a + - asia-east2-b + - asia-east2-c + - asia-northeast1-a + - asia-northeast1-b + - asia-northeast1-c + - asia-northeast2-a + - asia-northeast2-b + - asia-northeast2-c + - asia-northeast3-a + - asia-northeast3-b + - asia-northeast3-c + - asia-south1-a + - asia-south1-b + - asia-south1-c + - asia-south2-a + - asia-south2-b + - asia-south2-c + - asia-southeast1-a + - asia-southeast1-b + - asia-southeast1-c + - asia-southeast2-a + - asia-southeast2-b + - asia-southeast2-c + - australia-southeast1-a + - australia-southeast1-b + - australia-southeast1-c + - australia-southeast2-a + - australia-southeast2-b + - australia-southeast2-c + - europe-central2-a + - europe-central2-b + - europe-central2-c + - europe-north1-a + - europe-north1-b + - europe-north1-c + - europe-southwest1-a + - europe-southwest1-b + - europe-southwest1-c + - europe-west1-b + - europe-west1-c + - europe-west1-d + - europe-west2-a + - europe-west2-b + - europe-west2-c + - europe-west3-a + - europe-west3-b + - europe-west3-c + - europe-west4-a + - europe-west4-b + - europe-west4-c + - europe-west6-a + - europe-west6-b + - europe-west6-c + - europe-west8-a + - europe-west8-b + - europe-west8-c + - europe-west9-a + - europe-west9-b + - europe-west9-c + - me-west1-a + - me-west1-b + - me-west1-c + - northamerica-northeast1-a + - northamerica-northeast1-b + - northamerica-northeast1-c + - northamerica-northeast2-a + - northamerica-northeast2-b + - northamerica-northeast2-c + - southamerica-east1-a + - southamerica-east1-b + - southamerica-east1-c + - southamerica-west1-a + - southamerica-west1-b + - southamerica-west1-c + - us-central1-a + - us-central1-b + - us-central1-c + - us-central1-f + - us-east1-b + - us-east1-c + - us-east1-d + - us-east4-a + - us-east4-b + - us-east4-c + - us-east5-a + - us-east5-b + - us-east5-c + - us-south1-a + - us-south1-b + - us-south1-c + - us-west1-a + - us-west1-b + - us-west1-c + - us-west2-a + - us-west2-b + - us-west2-c + - us-west3-a + - us-west3-b + - us-west3-c + - us-west4-a + - us-west4-b + - us-west4-c + +azure: + - eastasia + - southeastasia + - centralus + - eastus + - eastus2 + - westus + - northcentralus + - southcentralus + - northeurope + - westeurope + - japanwest + - japaneast + - brazilsouth + - australiaeast + - australiasoutheast + - southindia + - centralindia + - westindia + - canadacentral + - canadaeast + - uksouth + - ukwest + - westcentralus + - westus2 + - koreacentral + - koreasouth + - francecentral + - francesouth + - australiacentral + - australiacentral2 + - uaecentral + - uaenorth + - southafricanorth + - southafricawest \ No newline at end of file diff --git a/mc_openapi/assets/doml_meta.yaml b/mc_openapi/assets/metamodels/doml_meta_v1.0.yaml similarity index 100% rename from mc_openapi/assets/doml_meta.yaml rename to mc_openapi/assets/metamodels/doml_meta_v1.0.yaml diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml new file mode 100644 index 0000000000000000000000000000000000000000..08cc7176fbeda1681e86fbc37afa83080423522c --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml @@ -0,0 +1,485 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Deployment: + associations: + component: + class: application_ApplicationComponent + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DOMLElement + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + configFile: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: infrastructure_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + InfrastructureElement: + superclass: commons_DOMLElement + ComputingNode: + superclass: infrastructure_InfrastructureElement + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: infrastructure_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + hosts: + class: infrastructure_ComputingNode + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + deploymentNetwork: + class: infrastructure_Network + multiplicity: "0..1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_InfrastructureElement + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + address_lb: + type: Integer + multiplicity: "0..1" + address_ub: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + igws: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..1" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails + InternetGateway: + superclass: infrastructure_NetworkInterface + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + Credentials: + superclass: commons_DOMLElement + KeyPair: + superclass: infrastructure_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: infrastructure_Credentials + attributes: + username: + type: String + multiplicity: "1" + password: + type: String + multiplicity: "1" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + attributes: + configurationScript: + type: String + multiplicity: "0..1" + RuntimeProvider: + superclass: commons_DOMLElement + associations: + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cba1f52489abb62aa049084c03073473715d3b81 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml @@ -0,0 +1,502 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Deployment: + associations: + component: + class: application_ApplicationComponent + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DOMLElement + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + configFile: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: infrastructure_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + InfrastructureElement: + superclass: commons_DOMLElement + ComputingNode: + superclass: infrastructure_InfrastructureElement + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: infrastructure_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + configs: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_InfrastructureElement + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + igws: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..1" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails + InternetGateway: + superclass: infrastructure_NetworkInterface + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + Credentials: + superclass: commons_DOMLElement + KeyPair: + superclass: infrastructure_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: infrastructure_Credentials + attributes: + username: + type: String + multiplicity: "1" + password: + type: String + multiplicity: "1" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + attributes: + configurationScript: + type: String + multiplicity: "0..1" + RuntimeProvider: + superclass: commons_DOMLElement + associations: + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + attributes: + address: + type: Integer + multiplicity: "0..1" + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b30e3273d81c4f15e6acab16883d400a1e2ddbc6 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml @@ -0,0 +1,552 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Credentials: + abstract: true + superclass: commons_DOMLElement + DeployableElement: + abstract: true + superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks. + Deployment: + associations: + component: + class: commons_DeployableElement + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + KeyPair: + superclass: commons_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: commons_Credentials + attributes: + username: + type: String + multiplicity: "0..1" + password: + type: String + multiplicity: "0..1" + Source: + superclass: commons_DOMLElement + attributes: + entry: + type: String + multiplicity: "0..*" + backend: + type: String + multiplicity: "0..*" +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it. + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + src: + class: commons_Source + multiplicity: "0..1" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: commons_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + rules: + class: infrastructure_MonitoringRule + multiplicity: "0..*" + MonitoringRule: + superclass: commons_DOMLElement + attributes: + condition: + type: String + multiplicity: "1" + strategy: + type: String + multiplicity: "1" + strategyConfigurationString: + type: String + multiplicity: "0..1" + InfrastructureElement: + superclass: commons_DeployableElement + ComputingNode: + superclass: infrastructure_InfrastructureElement + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + disabledMonitorings: + type: String + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: commons_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + configs: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_InfrastructureElement + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + gateways: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..*" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails + InternetGateway: + superclass: infrastructure_NetworkInterface + attributes: + address: + type: String + multiplicity: "1" + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + associations: + refs: + class: concrete_ConcreteElement + multiplicity: "0..*" + attributes: + configurationScript: + type: String + multiplicity: "0..1" + preexisting: + multiplicity: "1" + type: Boolean + default: false + RuntimeProvider: + superclass: commons_DOMLElement + associations: + resources: + class: concrete_GenericResource + multiplicity: "0..*" + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" + GenericResource: + superclass: concrete_ConcreteElement + attributes: + type: + type: "String" + multiplicity: "1" + gname: + type: "String" + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0867657750bd7ed3027fe3e44ca306169dd27efb --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml @@ -0,0 +1,532 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Credentials: + abstract: true + superclass: commons_DOMLElement + DeployableElement: + abstract: true + superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks. + Deployment: + associations: + component: + class: commons_DeployableElement + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + KeyPair: + superclass: commons_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: commons_Credentials + attributes: + username: + type: String + multiplicity: "0..1" + password: + type: String + multiplicity: "0..1" + Source: + superclass: commons_DOMLElement + attributes: + entry: + type: String + multiplicity: "0..*" + backend: + type: String + multiplicity: "0..*" +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it. + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + src: + class: commons_Source + multiplicity: "0..1" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: commons_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + rules: + class: infrastructure_MonitoringRule + multiplicity: "0..*" + MonitoringRule: + superclass: commons_DOMLElement + attributes: + condition: + type: String + multiplicity: "1" + strategy: + type: String + multiplicity: "1" + strategyConfigurationString: + type: String + multiplicity: "0..1" + InfrastructureElement: + superclass: commons_DeployableElement + ComputingNode: + superclass: infrastructure_InfrastructureElement + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + disabledMonitorings: + type: String + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: commons_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + configs: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_InfrastructureElement + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + igws: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..*" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails + InternetGateway: + superclass: infrastructure_NetworkInterface + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + attributes: + configurationScript: + type: String + multiplicity: "0..1" + preexisting: + multiplicity: "1" + type: Boolean + default: false + RuntimeProvider: + superclass: commons_DOMLElement + associations: + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cda67949f57f16186ebf590c630783eefcf60316 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml @@ -0,0 +1,551 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Credentials: + abstract: true + superclass: commons_DOMLElement + DeployableElement: + abstract: true + superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks. + Deployment: + associations: + component: + class: commons_DeployableElement + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + KeyPair: + superclass: commons_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: commons_Credentials + attributes: + username: + type: String + multiplicity: "0..1" + password: + type: String + multiplicity: "0..1" + Source: + superclass: commons_DOMLElement + attributes: + entry: + type: String + multiplicity: "0..*" + backend: + type: String + multiplicity: "0..*" +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it. + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + src: + class: commons_Source + multiplicity: "0..1" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: commons_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + rules: + class: infrastructure_MonitoringRule + multiplicity: "0..*" + MonitoringRule: + superclass: commons_DOMLElement + attributes: + condition: + type: String + multiplicity: "1" + strategy: + type: String + multiplicity: "1" + strategyConfigurationString: + type: String + multiplicity: "0..1" + InfrastructureElement: + superclass: commons_DeployableElement + Node: + superclass: infrastructure_InfrastructureElement + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + ComputingNode: + superclass: infrastructure_Node + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + disabledMonitorings: + type: String + multiplicity: "0..1" + associations: + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: commons_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + configs: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_Node + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + gateways: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..*" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + InternetGateway: + superclass: infrastructure_Node + attributes: + address: + type: String + multiplicity: "1" + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + associations: + refs: + class: concrete_ConcreteElement + multiplicity: "0..*" + attributes: + configurationScript: + type: String + multiplicity: "0..1" + preexisting: + multiplicity: "1" + type: Boolean + default: false + RuntimeProvider: + superclass: commons_DOMLElement + associations: + resources: + class: concrete_GenericResource + multiplicity: "0..*" + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + attributes: + image_name: + type: String + multiplicity: "1" + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" + GenericResource: + superclass: concrete_ConcreteElement + attributes: + type: + type: "String" + multiplicity: "1" + gname: + type: "String" + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml b/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml new file mode 100644 index 0000000000000000000000000000000000000000..550ce647aaffc229c1ac8a89e7b32a44473d551e --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml @@ -0,0 +1,554 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Credentials: + abstract: true + superclass: commons_DOMLElement + DeployableElement: + abstract: true + superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks. + Deployment: + associations: + component: + class: commons_DeployableElement + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + KeyPair: + superclass: commons_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + keyfile: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: commons_Credentials + attributes: + username: + type: String + multiplicity: "0..1" + password: + type: String + multiplicity: "0..1" + Source: + superclass: commons_DOMLElement + attributes: + entry: + type: String + multiplicity: "0..*" + backend: + type: String + multiplicity: "0..*" +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it. + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + src: + class: commons_Source + multiplicity: "0..1" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: commons_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + rules: + class: infrastructure_MonitoringRule + multiplicity: "0..*" + MonitoringRule: + superclass: commons_DOMLElement + attributes: + condition: + type: String + multiplicity: "1" + strategy: + type: String + multiplicity: "1" + strategyConfigurationString: + type: String + multiplicity: "0..1" + InfrastructureElement: + superclass: commons_DeployableElement + Node: + superclass: infrastructure_InfrastructureElement + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + ComputingNode: + superclass: infrastructure_Node + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: String + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + disabledMonitorings: + type: String + multiplicity: "0..1" + associations: + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: commons_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + nodeSpecificMonitoring: + class: infrastructure_MonitoringRule + multiplicity: "0..1" + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + configs: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + securityGroup: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + Storage: + superclass: infrastructure_Node + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + gateways: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..*" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + InternetGateway: + superclass: infrastructure_Node + attributes: + address: + type: String + multiplicity: "1" + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + associations: + refs: + class: concrete_ConcreteElement + multiplicity: "0..*" + attributes: + configurationScript: + type: String + multiplicity: "0..1" + preexisting: + multiplicity: "1" + type: Boolean + default: false + RuntimeProvider: + superclass: commons_DOMLElement + associations: + resources: + class: concrete_GenericResource + multiplicity: "0..*" + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + group: + class: concrete_ComputingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + attributes: + image_name: + type: String + multiplicity: "1" + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Network + multiplicity: "0..1" + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + ComputingGroup: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ComputingGroup + multiplicity: "1" + GenericResource: + superclass: concrete_ConcreteElement + attributes: + type: + type: "String" + multiplicity: "1" + gname: + type: "String" + multiplicity: "1" diff --git a/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c2dd82b4935821cb9d105ca2a249726a4bcc4b3f --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml @@ -0,0 +1,677 @@ +commons: + DOMLElement: + attributes: + name: + type: String + multiplicity: "0..1" + description: + type: String + multiplicity: "0..1" + associations: + annotations: + class: commons_Property + multiplicity: "0..*" + Property: + attributes: + key: + type: String + multiplicity: "0..1" + associations: + reference: + class: commons_DOMLElement + multiplicity: "0..1" + ListProperty: + superclass: commons_Property + associations: + values: + class: commons_Property + multiplicity: "0..*" + IProperty: + superclass: commons_Property + attributes: + value: + type: Integer + multiplicity: "0..1" + SProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + FProperty: + superclass: commons_Property + attributes: + value: + type: String + multiplicity: "0..1" + BProperty: + superclass: commons_Property + attributes: + value: + type: Boolean + multiplicity: "0..1" + Configuration: + superclass: commons_DOMLElement + associations: + deployments: + class: commons_Deployment + multiplicity: "0..*" + Credentials: + abstract: true + superclass: commons_DOMLElement + DeployableElement: + abstract: true + superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks. + Deployment: + associations: + component: + class: commons_DeployableElement + multiplicity: "1" + node: + class: infrastructure_InfrastructureElement + multiplicity: "1" + KeyPair: + superclass: commons_Credentials + attributes: + user: + type: String + multiplicity: "0..1" + key: + type: String + multiplicity: "0..1" + algorithm: + type: String + multiplicity: "0..1" + bits: + type: Integer + multiplicity: "0..1" + UserPass: + superclass: commons_Credentials + attributes: + username: + type: String + multiplicity: "0..1" + password: + type: String + multiplicity: "0..1" + Source: + superclass: commons_DOMLElement + attributes: + entry: + type: String + multiplicity: "0..1" + inventory: + type: String + multiplicity: "0..1" + backend: + type: String + multiplicity: "0..1" +application: + ApplicationLayer: + superclass: commons_DOMLElement + associations: + components: + class: application_ApplicationComponent + multiplicity: "0..*" + ApplicationComponent: + superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it. + SoftwareComponent: + superclass: application_ApplicationComponent + attributes: + isPersistent: + type: Boolean + multiplicity: "1" + default: false + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + consumedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + src: + class: commons_Source + multiplicity: "0..1" + SaaS: + superclass: application_ApplicationComponent + attributes: + licenseCost: + type: String + multiplicity: "0..1" + associations: + exposedInterfaces: + class: application_SoftwareInterface + multiplicity: "0..*" + SoftwareInterface: + superclass: application_ApplicationComponent + attributes: + endPoint: + type: String + multiplicity: "0..1" + DBMS: + superclass: application_SoftwareComponent + SaaSDBMS: + superclass: application_SaaS + attributes: + databaseName: + type: String + multiplicity: "0..1" + engine: + type: String + multiplicity: "0..1" + engineVersion: + type: String + multiplicity: "0..1" +infrastructure: + InfrastructureLayer: + superclass: commons_DOMLElement + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + generators: + class: infrastructure_ComputingNodeGenerator + multiplicity: "0..*" + storages: + class: infrastructure_Storage + multiplicity: "0..*" + faas: + class: infrastructure_FunctionAsAService + multiplicity: "0..*" + credentials: + class: commons_Credentials + multiplicity: "0..*" + groups: + class: infrastructure_ComputingGroup + multiplicity: "0..*" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + networks: + class: infrastructure_Network + multiplicity: "0..*" + rules: + class: infrastructure_MonitoringRule + multiplicity: "0..*" + executionEnvironments: + class: infrastructure_ExecutionEnvironment + multiplicity: "0..*" + MonitoringRule: + superclass: commons_DOMLElement + attributes: + condition: + type: String + multiplicity: "1" + strategy: + type: String + multiplicity: "1" + strategyConfigurationString: + type: String + multiplicity: "0..1" + InfrastructureElement: + superclass: commons_DeployableElement + Node: + superclass: infrastructure_InfrastructureElement + associations: + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + ComputingNode: + superclass: infrastructure_Node + attributes: + architecture: + type: String + multiplicity: "0..1" + os: + type: String + multiplicity: "0..1" + memory_mb: + type: Integer + multiplicity: "0..1" + memory_kb: # Missing in official Ecore, added by parser + type: Integer + multiplicity: "0..1" + storage: + type: Integer + multiplicity: "0..1" + cpu_count: + type: Integer + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + disabledMonitorings: + type: String + multiplicity: "0..1" + associations: + location: + class: infrastructure_Location + multiplicity: "0..1" + credentials: + class: commons_Credentials + multiplicity: "0..1" + group: + class: infrastructure_ComputingGroup + multiplicity: "0..1" + inverse_of: infrastructure_ComputingGroup::groupedNodes + nodeSpecificMonitoring: + class: infrastructure_MonitoringRule + multiplicity: "0..1" + PhysicalComputingNode: + superclass: infrastructure_ComputingNode + associations: + configInterface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + VirtualMachine: + superclass: infrastructure_ComputingNode + attributes: + sizeDescription: + type: String + multiplicity: "0..1" + associations: + generatedFrom: + class: infrastructure_VMImage + multiplicity: "0..1" + configInterface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + Location: + superclass: commons_DOMLElement + attributes: + region: + type: String + multiplicity: "0..1" + zone: + type: String + multiplicity: "0..1" + ContainerConfig: + superclass: commons_DOMLElement + attributes: + container_port: + type: Integer + multiplicity: "0..1" + vm_port: + type: Integer + multiplicity: "0..1" + associations: + iface: + class: infrastructure_NetworkInterface + multiplicity: "0..1" + ContainerHostConfig: + superclass: commons_DOMLElement + associations: + environment_variables: + class: commons_SProperty + multiplicity: "0..*" + host: + class: infrastructure_ComputingNode + multiplicity: "0..1" + configurations: + class: infrastructure_ContainerConfig + multiplicity: "0..*" + Container: + superclass: infrastructure_ComputingNode + associations: + generatedFrom: + class: infrastructure_ContainerImage + multiplicity: "0..1" + hostConfigs: + class: infrastructure_ContainerHostConfig + multiplicity: "0..*" + networks: + class: infrastructure_ContainerNetwork + multiplicity: "0..*" + volumes: + class: infrastructure_ContainerVolume + multiplicity: "0..*" + dependsOn: + class: infrastructure_Container + multiplicity: "0..*" + ContainerGroup: + superclass: infrastructure_ComputingGroup + associations: + services: + class: infrastructure_Container + multiplicity: "1..*" + networks: + class: infrastructure_ContainerNetwork + multiplicity: "0..*" + volumes: + class: infrastructure_ContainerVolume + multiplicity: "0..*" + ContainerNetwork: + superclass: commons_DOMLElement + attributes: + containerNetworkName: + type: String + multiplicity: "0..1" + ContainerVolume: + superclass: commons_DOMLElement + attributes: + containerVolumeName: + type: String + multiplicity: "0..1" + path: + type: String + multiplicity: "0..1" + ExecutionEnvironment: + superclass: infrastructure_InfrastructureElement + attributes: + size: + type: Integer + multiplicity: "0..1" + maxSize: + type: Integer + multiplicity: "0..1" + associations: + location: + class: infrastructure_Location + multiplicity: "0..1" + network: + class: infrastructure_Network + multiplicity: "0..1" + securityGroups: + class: infrastructure_SecurityGroup + multiplicity: "0..*" + ComputingNodeGenerator: + superclass: commons_DOMLElement + attributes: + uri: + type: String + multiplicity: "0..1" + kind: + type: GeneratorKind # enum { SCRIPT, IMAGE } + VMImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedVMs: + class: infrastructure_VirtualMachine + multiplicity: "0..*" + inverse_of: infrastructure_VirtualMachine::generatedFrom + ContainerImage: + superclass: infrastructure_ComputingNodeGenerator + associations: + generatedContainers: + class: infrastructure_Container + multiplicity: "0..*" + inverse_of: infrastructure_Container::generatedFrom + AutoScalingGroup: + superclass: infrastructure_ComputingGroup + attributes: + min: + type: Integer + multiplicity: "0..1" + max: + type: Integer + multiplicity: "0..1" + loadBalancer: + type: String + multiplicity: "0..1" + associations: + machineDefinition: + class: infrastructure_VirtualMachine + multiplicity: "1" + Storage: + superclass: infrastructure_Node + attributes: + label: + type: String + multiplicity: "0..1" + size_gb: + type: Integer # in GBs + multiplicity: "0..1" + cost: + type: Integer # in cents + multiplicity: "0..1" + FunctionAsAService: + superclass: infrastructure_InfrastructureElement + attributes: + cost: + type: Integer # in cents + multiplicity: "0..1" + Network: + superclass: commons_DOMLElement + attributes: + protocol: + type: String + multiplicity: "0..1" + default: "TCP/IP" + cidr: + type: Integer + multiplicity: "0..1" + associations: + connectedIfaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::belongsTo + gateways: + class: infrastructure_InternetGateway + multiplicity: "0..*" + subnets: + class: infrastructure_Subnet + multiplicity: "0..*" + Subnet: + superclass: infrastructure_Network + associations: + connectedTo: + class: infrastructure_Network + multiplicity: "0..*" + NetworkInterface: + superclass: infrastructure_InfrastructureElement + attributes: + endPoint: + type: Integer + multiplicity: "0..1" + speed: + type: String + multiplicity: "0..1" + associations: + belongsTo: + class: infrastructure_Network + multiplicity: "0..1" # This should be "1", but it would break InternetGateway + associated: + class: infrastructure_SecurityGroup + multiplicity: "0..1" + InternetGateway: + superclass: infrastructure_Node + attributes: + address: + type: String + multiplicity: "1" + ComputingGroup: + superclass: commons_DOMLElement + associations: + groupedNodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + inverse_of: infrastructure_ComputingNode::group + SecurityGroup: + superclass: commons_DOMLElement + associations: + rules: + class: infrastructure_Rule + multiplicity: "0..*" + ifaces: + class: infrastructure_NetworkInterface + multiplicity: "0..*" + inverse_of: infrastructure_NetworkInterface::associated + Rule: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + protocol: + type: String + multiplicity: "1" + fromPort: + type: Integer + multiplicity: "1" + toPort: + type: Integer + multiplicity: "1" + cidr: + type: String + multiplicity: "0..*" + SwarmRole: + superclass: commons_DOMLElement + attributes: + kind: + type: String + multiplicity: "1" + associations: + nodes: + class: infrastructure_ComputingNode + multiplicity: "0..*" + Swarm: + superclass: infrastructure_ComputingGroup + associations: + roles: + class: infrastructure_SwarmRole + multiplicity: "0..*" + ExtInfrastructureElement: + superclass: infrastructure_InfrastructureElement + +concrete: + ConcreteInfrastructure: + superclass: commons_DOMLElement + associations: + providers: + class: concrete_RuntimeProvider + multiplicity: "0..*" + ConcreteElement: + superclass: commons_DOMLElement + associations: + refs: + class: concrete_ConcreteElement + multiplicity: "0..*" + attributes: + resourceName: + type: String + multiplicity: "0..1" + configurationScript: + type: String + multiplicity: "0..1" + preexisting: + multiplicity: "1" + type: Boolean + default: false + RuntimeProvider: + superclass: commons_DOMLElement + associations: + resources: + class: concrete_GenericResource + multiplicity: "0..*" + vms: + class: concrete_VirtualMachine + multiplicity: "0..*" + executionEnvironments: + class: concrete_ExecutionEnvironment + multiplicity: "0..*" + vmImages: + class: concrete_VMImage + multiplicity: "0..*" + containerImages: + class: concrete_ContainerImage + multiplicity: "0..*" + networks: + class: concrete_Network + multiplicity: "0..*" + storages: + class: concrete_Storage + multiplicity: "0..*" + faas: + class: concrete_FunctionAsAService + multiplicity: "0..*" + autoScalingGroups: + class: concrete_AutoScalingGroup + multiplicity: "0..*" + VirtualMachine: + superclass: concrete_ConcreteElement + attributes: + vm_type: + type: String + multiplicity: "0..1" + associations: + maps: + class: infrastructure_VirtualMachine + multiplicity: "0..1" + VMImage: + superclass: concrete_ConcreteElement + attributes: + image_name: + type: String + multiplicity: "1" + associations: + maps: + class: infrastructure_VMImage + multiplicity: "0..1" + ContainerImage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_ContainerImage + multiplicity: "0..1" + ExecutionEnvironment: + superclass: concrete_ConcreteElement + attributes: + instance_type: + type: String + multiplicity: "0..1" + storage_type: + type: String + multiplicity: "0..1" + associations: + maps: + class: infrastructure_ExecutionEnvironment + multiplicity: "0..1" + Network: + superclass: concrete_ConcreteElement + attributes: + protocol: + type: String + multiplicity: "0..1" + addressRange: + type: String + multiplicity: "0..1" + associations: + subnets: + class: concrete_Subnet + multiplicity: "0..*" + maps: + class: infrastructure_Network + multiplicity: "0..1" + Subnet: + superclass: concrete_Network + Storage: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_Storage + multiplicity: "0..1" + FunctionAsAService: + superclass: concrete_ConcreteElement + associations: + maps: + class: infrastructure_FunctionAsAService + multiplicity: "0..1" + AutoScalingGroup: + superclass: concrete_ConcreteElement + attributes: + vm_type: + type: String + multiplicity: "0..1" + associations: + maps: + class: infrastructure_AutoScalingGroup + multiplicity: "0..1" + GenericResource: + superclass: concrete_ConcreteElement + attributes: + type: + type: "String" + multiplicity: "1" diff --git a/mc_openapi/assets/doml.ecore b/mc_openapi/assets/metamodels/doml_v1.0.ecore similarity index 100% rename from mc_openapi/assets/doml.ecore rename to mc_openapi/assets/metamodels/doml_v1.0.ecore diff --git a/mc_openapi/doml/doml.ecore b/mc_openapi/assets/metamodels/doml_v2.0.ecore similarity index 86% rename from mc_openapi/doml/doml.ecore rename to mc_openapi/assets/metamodels/doml_v2.0.ecore index e8cc0d6e555f08f8fcf9b10522f40ffaecbcca7d..9c23605fed74133837525dfab8b471013077d262 100644 --- a/mc_openapi/doml/doml.ecore +++ b/mc_openapi/assets/metamodels/doml_v2.0.ecore @@ -9,6 +9,8 @@ <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" nsPrefix="commons"> <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + changeable="false" defaultValueLiteral="v2"/> <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" @@ -26,12 +28,23 @@ <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" upperBound="-1" eType="#//commons/Requirement" containment="true"/> </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="Property"> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/> </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> @@ -54,7 +67,6 @@ eType="#//infrastructure/InfrastructureElement"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Requirement"> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="identifier" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> @@ -123,10 +135,6 @@ <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" eType="#//infrastructure/ComputingNode" containment="true"/> - <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" - eType="#//infrastructure/VPC" containment="true"/> - <eStructuralFeatures xsi:type="ecore:EReference" name="secGroups" upperBound="-1" - eType="#//infrastructure/SecurityGroup" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" @@ -135,12 +143,18 @@ eType="#//infrastructure/FunctionAsAService" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" eType="#//infrastructure/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingNode"> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" eType="#//infrastructure/VirtualMachine" containment="true"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" @@ -163,14 +177,14 @@ <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRanges" upperBound="-1" + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> <eLiterals name="EGRESS"/> <eLiterals name="INGRESS" value="1"/> </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" eType="#//infrastructure/Rule" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" @@ -182,9 +196,9 @@ <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" eType="#//infrastructure/NetworkInterface" containment="true"/> @@ -225,17 +239,16 @@ <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> - <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="hosts" upperBound="-1" + eType="#//infrastructure/ComputingNode"/> </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="Network" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1" eType="#//infrastructure/InternetGateway" containment="true"/> - </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="VPC" eSuperTypes="#//infrastructure/Network"> <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" eType="#//infrastructure/Subnet" containment="true"/> </eClassifiers> @@ -253,7 +266,8 @@ </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/> <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" eType="#//infrastructure/NetworkInterface" containment="true"/> @@ -265,6 +279,8 @@ </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//infrastructure/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> </eClassifiers> @@ -272,6 +288,21 @@ <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> </eSubpackages> <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" @@ -334,7 +365,17 @@ <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" upperBound="-1" eType="#//commons/Requirement" containment="true"/> </eClassifiers> - <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"/> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" eSuperTypes="#//commons/DOMLElement"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" diff --git a/mc_openapi/assets/metamodels/doml_v2.1.ecore b/mc_openapi/assets/metamodels/doml_v2.1.ecore new file mode 100644 index 0000000000000000000000000000000000000000..02f3904f45a536afce64bd47b8e8a4f89b8209a4 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v2.1.ecore @@ -0,0 +1,396 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + changeable="false" defaultValueLiteral="v2"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//application/ApplicationComponent"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configFile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//infrastructure/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//infrastructure/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup" + eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//infrastructure/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//infrastructure/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/metamodels/doml_v2.2.1.ecore b/mc_openapi/assets/metamodels/doml_v2.2.1.ecore new file mode 100644 index 0000000000000000000000000000000000000000..cbff3c686bae8d319a1d8c6a272d16b18cc65034 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v2.2.1.ecore @@ -0,0 +1,423 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="2.2"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//commons/DeployableElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source" + containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//commons/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/MonitoringRule" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings" + upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup" + eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1" + eType="#//concrete/GenericResource" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1" + eType="#//concrete/ConcreteElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/metamodels/doml_v2.2.ecore b/mc_openapi/assets/metamodels/doml_v2.2.ecore new file mode 100644 index 0000000000000000000000000000000000000000..a294cdef5b4ac189c94d5e7088cfb79db4aaf7ae --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v2.2.ecore @@ -0,0 +1,415 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="2.2"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//commons/DeployableElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source" + containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//commons/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/MonitoringRule" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings" + upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup" + eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/metamodels/doml_v2.3.ecore b/mc_openapi/assets/metamodels/doml_v2.3.ecore new file mode 100644 index 0000000000000000000000000000000000000000..30a5244fea7c765953d14e30108c5163936f1758 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v2.3.ecore @@ -0,0 +1,422 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="2.2"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//commons/DeployableElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source" + containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//commons/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/MonitoringRule" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings" + upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1" + eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1" + eType="#//concrete/GenericResource" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1" + eType="#//concrete/ConcreteElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/metamodels/doml_v3.0.ecore b/mc_openapi/assets/metamodels/doml_v3.0.ecore new file mode 100644 index 0000000000000000000000000000000000000000..3d4e249441ae848ac55cd694236ae2b4916329de --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v3.0.ecore @@ -0,0 +1,424 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="3.0"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//commons/DeployableElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source" + containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//commons/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/MonitoringRule" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodeSpecificMonitoring" + upperBound="-1" eType="#//infrastructure/MonitoringRule"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings" + upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1" + eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1" + eType="#//concrete/GenericResource" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1" + eType="#//concrete/ComputingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1" + eType="#//concrete/ConcreteElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="optimization"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/metamodels/doml_v3.1.ecore b/mc_openapi/assets/metamodels/doml_v3.1.ecore new file mode 100644 index 0000000000000000000000000000000000000000..ce4f02e1e1cd9b8186b33d6ab0dd5a2452c699e8 --- /dev/null +++ b/mc_openapi/assets/metamodels/doml_v3.1.ecore @@ -0,0 +1,489 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml"> + <eAnnotations source="emf.gen"> + <details key="basePackage" value="eu.piacere.doml"/> + <details key="fileExtensions" value="domlx"/> + <details key="complianceLevel" value="JDK80"/> + </eAnnotations> + <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons" + nsPrefix="commons"> + <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="3.1"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1" + eType="#//concrete/ConcreteInfrastructure" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//commons/Configuration" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration" + eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure" + eType="#//concrete/ConcreteInfrastructure"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ListProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EReference" name="values" upperBound="-1" + eType="#//commons/Property" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1" + eType="#//commons/Property" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1" + eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1" + eType="#//commons/Deployment" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Deployment"> + <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1" + eType="#//commons/DeployableElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1" + eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true" + eSuperTypes="#//commons/Requirement"/> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement" + eSuperTypes="#//commons/DeploymentRequirement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1" + eType="#//infrastructure/InfrastructureElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/> + <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="inventory" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + </eSubpackages> + <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application" + nsPrefix="app"> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1" + eType="#//application/ApplicationComponent" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source" + containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/> + <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1" + eType="#//application/SoftwareInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="databaseName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="engine" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="engineVersion" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure" + nsPrefix="infra"> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1" + eType="#//infrastructure/ComputingNodeGenerator" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//infrastructure/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//infrastructure/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1" + eType="#//commons/Credentials" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="executionEnvironments" + upperBound="-1" eType="#//infrastructure/ExecutionEnvironment" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1" + eType="#//infrastructure/ComputingGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/MonitoringRule" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1" + eType="#//infrastructure/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject" + defaultValueLiteral="1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind" + defaultValueLiteral="DEFAULT"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind"> + <eLiterals name="DEFAULT"/> + <eLiterals name="INTERNAL" value="1"/> + <eLiterals name="EXTERNAL" value="2"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RuleKind"> + <eLiterals name="EGRESS"/> + <eLiterals name="INGRESS" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1" + eType="#//infrastructure/Rule" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true" + eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/> + <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup" + eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodeSpecificMonitoring" + upperBound="-1" eType="#//infrastructure/MonitoringRule"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings" + upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind"> + <eLiterals name="SCRIPT"/> + <eLiterals name="IMAGE" value="1"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1" + eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers" + upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="configInterface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage" + eOpposite="#//infrastructure/VMImage/generatedVMs"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configInterface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerHostConfig" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="environment_variables" + upperBound="-1" eType="#//commons/SProperty" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1" + eType="#//infrastructure/ContainerConfig" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage" + eOpposite="#//infrastructure/ContainerImage/generatedContainers"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="hostConfigs" upperBound="-1" + eType="#//infrastructure/ContainerHostConfig" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/ContainerNetwork"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="volumes" upperBound="-1" + eType="#//infrastructure/ContainerVolume"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="dependsOn" upperBound="-1" + eType="#//infrastructure/Container"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerGroup" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="services" lowerBound="1" + upperBound="-1" eType="#//infrastructure/Container" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//infrastructure/ContainerNetwork" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="volumes" upperBound="-1" + eType="#//infrastructure/ContainerVolume" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerNetwork" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="containerNetworkName" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerVolume" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="containerVolumeName" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="path" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExecutionEnvironment" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="maxSize" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="network" eType="#//infrastructure/Network"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1" + eType="#//infrastructure/SecurityGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="TCP/IP"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1" + eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1" + eType="#//infrastructure/InternetGateway" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//infrastructure/Subnet" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network"> + <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1" + eType="#//infrastructure/Subnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network" + eOpposite="#//infrastructure/Network/connectedIfaces"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1" + eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="RoleKind"> + <eLiterals name="NONE"/> + <eLiterals name="MANAGER" value="1"/> + <eLiterals name="WORKER" value="2"/> + <eLiterals name="MASTER" value="3"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" + eType="#//infrastructure/ComputingNode" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup"> + <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1" + eType="#//infrastructure/SwarmRole" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete" + nsPrefix="concrete"> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1" + eType="#//concrete/RuntimeProvider" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1" + eType="#//concrete/GenericResource" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1" + eType="#//concrete/VirtualMachine" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="executionEnvironments" + upperBound="-1" eType="#//concrete/ExecutionEnvironment" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1" + eType="#//concrete/VMImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1" + eType="#//concrete/ContainerImage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1" + eType="#//concrete/Network" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1" + eType="#//concrete/Storage" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1" + eType="#//concrete/FunctionAsAService" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="autoScalingGroups" upperBound="-1" + eType="#//concrete/AutoScalingGroup" containment="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="resourceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject" + defaultValueLiteral="false"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1" + eType="#//concrete/ConcreteElement"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExecutionEnvironment" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="instance_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ExecutionEnvironment"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1" + eType="#//concrete/Subnet" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//concrete/Network"/> + <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//concrete/ConcreteElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/AutoScalingGroup"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/> + </eSubpackages> + <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization" + nsPrefix="opt"> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1" + eType="#//optimization/OptimizationSolution" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1" + eType="#//optimization/OptimizationObjective" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements" + upperBound="-1" eType="#//commons/Requirement" containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="runtime" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue" + containment="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true" + eSuperTypes="#//commons/DOMLElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + defaultValueLiteral="Max"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/> + <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/> + </eSubpackages> +</ecore:EPackage> diff --git a/mc_openapi/assets/static/bulma.css.map b/mc_openapi/assets/static/bulma.css.map new file mode 100644 index 0000000000000000000000000000000000000000..dbe97a3f8b86f760be5e2dca7572dc06c70b5874 --- /dev/null +++ b/mc_openapi/assets/static/bulma.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../bulma.sass","../sass/utilities/_all.sass","../sass/utilities/extends.sass","../sass/utilities/controls.sass","../sass/utilities/initial-variables.sass","bulma.css","../sass/utilities/mixins.sass","../sass/base/_all.sass","../sass/base/minireset.sass","../sass/base/generic.sass","../sass/utilities/derived-variables.sass","../sass/base/animations.sass","../sass/elements/_all.sass","../sass/elements/box.sass","../sass/elements/button.sass","../sass/utilities/functions.sass","../sass/elements/container.sass","../sass/elements/content.sass","../sass/elements/icon.sass","../sass/elements/image.sass","../sass/elements/notification.sass","../sass/elements/progress.sass","../sass/elements/table.sass","../sass/elements/tag.sass","../sass/elements/title.sass","../sass/elements/other.sass","../sass/form/_all.sass","../sass/form/shared.sass","../sass/form/input-textarea.sass","../sass/form/checkbox-radio.sass","../sass/form/select.sass","../sass/form/file.sass","../sass/form/tools.sass","../sass/components/_all.sass","../sass/components/breadcrumb.sass","../sass/components/card.sass","../sass/components/dropdown.sass","../sass/components/level.sass","../sass/components/media.sass","../sass/components/menu.sass","../sass/components/message.sass","../sass/components/modal.sass","../sass/components/navbar.sass","../sass/components/pagination.sass","../sass/components/panel.sass","../sass/components/tabs.sass","../sass/grid/_all.sass","../sass/grid/columns.sass","../sass/grid/tiles.sass","../sass/helpers/_all.sass","../sass/helpers/color.sass","../sass/helpers/flexbox.sass","../sass/helpers/float.sass","../sass/helpers/other.sass","../sass/helpers/overflow.sass","../sass/helpers/position.sass","../sass/helpers/spacing.sass","../sass/helpers/typography.sass","../sass/helpers/visibility.sass","../sass/layout/_all.sass","../sass/layout/hero.sass","../sass/layout/section.sass","../sass/layout/footer.sass"],"names":[],"mappings":"AACA,6DAAA;ACDA,oBAAA;ACEA;;;;;ECYE,qBAAqB;EACrB,wBAAwB;EACxB,mBAAmB;EACnB,6BAA+C;EAC/C,kBCoDU;EDnDV,gBAAgB;EAChB,oBAAoB;EACpB,eCgBW;EDfX,aAfoB;EAgBpB,2BAA2B;EAC3B,gBAhBuB;EAiBvB,iCAf+D;EAgB/D,gCAfkE;EAgBlE,iCAhBkE;EAiBlE,8BAlB+D;EAmB/D,kBAAkB;EAClB,mBAAmB;AENrB;;AFQE;;;;;;;;;;;;;;;;;EAIE,aAAa;AEQjB;;AFPE;;;;;;;;;;;;;;;;EAEE,mBAAmB;AEwBvB;;AH1DA;;;;EI4LE,2BAA2B;EAC3B,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;AD3HnB;;AHlEA;EIgME,6BAD8B;EAE9B,kBAAkB;EAClB,eAAe;EACf,aAAa;EACb,YAAY;EACZ,cAAc;EACd,eAAe;EACf,qBAAqB;EACrB,oBAAoB;EACpB,kBAAkB;EAClB,QAAQ;EACR,yBAAyB;EACzB,wBAAwB;EACxB,cAAc;AD1HhB;;AC6HE;;EACE,qBFzKkB;ACgDtB;;AHlFA;EImLE,2BAA2B;EAC3B,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;EAwBjB,qBAAqB;EACrB,wBAAwB;EACxB,uCF7N2B;EE8N3B,YAAY;EACZ,qBFzJqB;EE0JrB,eAAe;EACf,oBAAoB;EACpB,qBAAqB;EACrB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,aAAa;EACb,kBAAkB;EAClB,mBAAmB;EACnB,WAAW;ADpHb;;ACqHE;EAEE,uBFpO2B;EEqO3B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,0DAA0D;EAC1D,+BAA+B;ADnHnC;;ACoHE;EACE,WAAW;EACX,UAAU;ADjHd;;ACkHE;EACE,WAAW;EACX,UAAU;AD/Gd;;ACgHE;EAEE,uCFjQyB;ACmJ7B;;AC+GE;EACE,uCFnQyB;ACuJ7B;;AC8GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;AD3Gf;;AC4GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADzGf;;AC0GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADvGf;;AHnKA;EI6QE,mDAA2C;UAA3C,2CAA2C;EAC3C,yBFrR4B;EEsR5B,qBFxNqB;EEyNrB,+BAA+B;EAC/B,6BAA6B;EAC7B,WAAW;EACX,cAAc;EACd,WAAW;EACX,kBAAkB;EAClB,UAAU;ADtGZ;;AH7KA;;;;;;;;;;;;;;;;;EIsRE,SADuB;EAEvB,OAFuB;EAGvB,kBAAkB;EAClB,QAJuB;EAKvB,MALuB;ADhFzB;;AHlMA;EIqDE,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,mBAAmB;EACnB,oBAAoB;EACpB,cAAc;EACd,SAAS;EACT,UAAU;ADiJZ;;AEtOA,eAAA;ACAA,0EAAA;AAEA;;;;;;;;;;;;;;;;;;;;;;;EAuBE,SAAS;EACT,UAAU;AHyOZ;;AGtOA;;;;;;EAME,eAAe;EACf,mBAAmB;AHyOrB;;AGtOA;EACE,gBAAgB;AHyOlB;;AGtOA;;;;EAIE,SAAS;AHyOX;;AGtOA;EACE,sBAAsB;AHyOxB;;AGvOA;EAII,mBAAmB;AHuOvB;;AGpOA;;EAEE,YAAY;EACZ,eAAe;AHuOjB;;AGpOA;EACE,SAAS;AHuOX;;AGpOA;EACE,yBAAyB;EACzB,iBAAiB;AHuOnB;;AGrOA;;EAEE,UAAU;AHwOZ;;AG1OA;;EAII,mBAAmB;AH2OvB;;AGvQA;EChBE,uBLnB6B;EKoB7B,eAhCc;EAiCd,kCAAkC;EAClC,mCAAmC;EACnC,gBAlCoB;EAmCpB,kBAhCsB;EAiCtB,kBAhCsB;EAiCtB,kCApCiC;EAqCjC,8BAAsB;KAAtB,2BAAsB;UAAtB,sBAAsB;AJ2RxB;;AIzRA;;;;;;;EAOE,cAAc;AJ4RhB;;AI1RA;;;;;;EAME,oLL/ByL;AC4T3L;;AI3RA;;EAEE,6BAA6B;EAC7B,4BAA4B;EAC5B,sBLpC0B;ACkU5B;;AI5RA;EACE,cL7D4B;EK8D5B,cA1DkB;EA2DlB,gBL7BiB;EK8BjB,gBA1DoB;AJyVtB;;AI3RA;EACE,cLtDgC;EKuDhC,eAAe;EACf,qBAAqB;AJ8RvB;;AIjSA;EAKI,mBAAmB;AJgSvB;;AIrSA;EAOI,cL5E0B;AC8W9B;;AIhSA;EACE,4BLxE4B;EKyE5B,cCnBsB;EDoBtB,kBArEiB;EAsEjB,mBAvEkB;EAwElB,4BAzEgC;AJ4WlC;;AIjSA;EACE,4BL/E4B;EKgF5B,YAAY;EACZ,cAAc;EACd,WAxEa;EAyEb,gBAxEkB;AJ4WpB;;AIlSA;EACE,YAAY;EACZ,eAAe;AJqSjB;;AInSA;;EAEE,wBAAwB;AJsS1B;;AIpSA;EACE,kBAvFuB;AJ8XzB;;AIrSA;EACE,mBAAmB;EACnB,oBAAoB;AJwStB;;AItSA;EACE,cL5G4B;EK6G5B,gBLvEe;ACgXjB;;AIrSA;EACE,YAAY;AJwSd;;AItSA;EHvDE,iCAAiC;EGyDjC,4BL/G4B;EKgH5B,cLtH4B;EKuH5B,kBAjGqB;EAkGrB,gBAAgB;EAChB,uBAlG0B;EAmG1B,gBAAgB;EAChB,iBAAiB;AJySnB;;AIjTA;EAUI,6BAA6B;EAC7B,mBAAmB;EACnB,cAvGoB;EAwGpB,UAAU;AJ2Sd;;AIzSA;;EAGI,mBAAmB;AJ2SvB;;AI9SA;;EAKM,mBAAmB;AJ8SzB;;AInTA;EAOI,cL1I0B;AC0b9B;;AMhcA;EACE;IACE,uBAAuB;ENmczB;EMlcA;IACE,yBAAyB;ENoc3B;AACF;;AMzcA;EACE;IACE,uBAAuB;ENmczB;EMlcA;IACE,yBAAyB;ENoc3B;AACF;;AOzcA,mBAAA;ACWA;EAEE,uBTE6B;ESD7B,kBTyDgB;ESxDhB,0FTb2B;ESc3B,cTT4B;ESU5B,cAAc;EACd,gBAZmB;AR6crB;;AQ/bA;EAGI,yETD8B;ACiclC;;AQncA;EAKI,oETH8B;ACqclC;;AS/ZA;EAGE,uBVhD6B;EUiD7B,qBVtD4B;EUuD5B,iBX5DwB;EW6DxB,cV5D4B;EU6D5B,eAAe;EAGf,uBAAuB;EACvB,iCA7D6D;EA8D7D,iBA7D6B;EA8D7B,kBA9D6B;EA+D7B,8BAhE6D;EAiE7D,kBAAkB;EAClB,mBAAmB;AT8ZrB;;AS9aA;EAkBI,cAAc;ATgalB;;ASlbA;EAwBM,aAAa;EACb,YAAY;AT8ZlB;;ASvbA;ERwHI,+BQ7FsG;ER6FtG,oBQ5FmE;ATgavE;;AS5bA;ERwHI,mBQ1FmE;ER0FnE,gCQzFsG;ATka1G;;ASjcA;EAiCM,+BAAiF;EACjF,gCAAkF;AToaxF;;AStcA;EAsCI,qBVzF0B;EU0F1B,cV7F0B;ACigB9B;;AS3cA;EA0CI,qBVhF8B;EUiF9B,cVjG0B;ACsgB9B;;AShdA;EA6CM,iDVnF4B;AC0flC;;ASpdA;EAgDI,qBVrG0B;EUsG1B,cVvG0B;AC+gB9B;;ASzdA;EAoDI,6BAA6B;EAC7B,yBAAyB;EACzB,cV3G0B;EU4G1B,0BA1F8B;ATmgBlC;;ASheA;EA4DM,4BV3GwB;EU4GxB,cVnHwB;AC2hB9B;;ASreA;EAgEM,yBChB2B;EDiB3B,cVvHwB;ACgiB9B;;AS1eA;;EAoEM,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;AT2atB;;ASjfA;EAwEI,gBAvG0B;EAwG1B,yBAvGmC;EAwGnC,cVhH8B;EUiH9B,qBAvG0B;ATohB9B;;ASxfA;EA8EM,cVpH4B;EUqH5B,0BAzGmC;ATuhBzC;;AS7fA;EAoFM,uBVjIyB;EUkIzB,yBAAyB;EACzB,cVhJuB;AC6jB7B;;ASngBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,cVrJqB;ACmkB7B;;ASzgBA;EA8FQ,yBAAyB;EACzB,cVzJqB;ACwkB7B;;AS9gBA;EAiGU,mDV9IqB;AC+jB/B;;ASlhBA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,cVhKqB;ACklB7B;;ASxhBA;;EAyGQ,uBVtJuB;EUuJvB,mBVvJuB;EUwJvB,gBAAgB;ATobxB;;AS/hBA;EA6GQ,yBVvKqB;EUwKrB,YV3JuB;ACilB/B;;ASpiBA;EAiHU,uBCjEuB;AVwfjC;;ASxiBA;;EAoHU,yBV9KmB;EU+KnB,yBAAyB;EACzB,gBAAgB;EAChB,YVpKqB;AC6lB/B;;AShjBA;EA0HU,gEAA4E;AT0btF;;ASpjBA;EA4HQ,6BAA6B;EAC7B,mBV1KuB;EU2KvB,YV3KuB;ACumB/B;;AS1jBA;EAmIU,uBVhLqB;EUiLrB,mBVjLqB;EUkLrB,cV/LmB;AC0nB7B;;AShkBA;EAwIY,4DAA8D;AT4b1E;;ASpkBA;EA8Ic,gEAA4E;AT0b1F;;ASxkBA;;EAiJU,6BAA6B;EAC7B,mBV/LqB;EUgMrB,gBAAgB;EAChB,YVjMqB;AC6nB/B;;AShlBA;EAsJQ,6BAA6B;EAC7B,qBVjNqB;EUkNrB,cVlNqB;ACgpB7B;;AStlBA;EA6JU,yBVvNmB;EUwNnB,YV3MqB;ACwoB/B;;AS3lBA;EAqKc,4DAA8D;AT0b5E;;AS/lBA;;EAwKU,6BAA6B;EAC7B,qBVnOmB;EUoOnB,gBAAgB;EAChB,cVrOmB;ACiqB7B;;ASvmBA;EAoFM,yBV9IuB;EU+IvB,yBAAyB;EACzB,YVnIyB;AC0pB/B;;AS7mBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,YVxIuB;ACgqB/B;;ASnnBA;EA8FQ,yBAAyB;EACzB,YV5IuB;ACqqB/B;;ASxnBA;EAiGU,gDV3JmB;ACsrB7B;;AS5nBA;EAoGQ,uBCpDyB;EDqDzB,yBAAyB;EACzB,YVnJuB;AC+qB/B;;ASloBA;;EAyGQ,yBVnKqB;EUoKrB,qBVpKqB;EUqKrB,gBAAgB;AT8hBxB;;ASzoBA;EA6GQ,uBV1JuB;EU2JvB,cVxKqB;ACwsB7B;;AS9oBA;EAiHU,yBCjEuB;AVkmBjC;;ASlpBA;;EAoHU,uBVjKqB;EUkKrB,yBAAyB;EACzB,gBAAgB;EAChB,cVjLmB;ACotB7B;;AS1pBA;EA0HU,4DAA4E;AToiBtF;;AS9pBA;EA4HQ,6BAA6B;EAC7B,qBVvLqB;EUwLrB,cVxLqB;AC8tB7B;;ASpqBA;EAmIU,yBV7LmB;EU8LnB,qBV9LmB;EU+LnB,YVlLqB;ACutB/B;;AS1qBA;EAwIY,gEAA8D;ATsiB1E;;AS9qBA;EA8Ic,4DAA4E;AToiB1F;;ASlrBA;;EAiJU,6BAA6B;EAC7B,qBV5MmB;EU6MnB,gBAAgB;EAChB,cV9MmB;ACovB7B;;AS1rBA;EAsJQ,6BAA6B;EAC7B,mBVpMuB;EUqMvB,YVrMuB;AC6uB/B;;AShsBA;EA6JU,uBV1MqB;EU2MrB,cVxNmB;AC+vB7B;;ASrsBA;EAqKc,gEAA8D;AToiB5E;;ASzsBA;;EAwKU,6BAA6B;EAC7B,mBVtNqB;EUuNrB,gBAAgB;EAChB,YVxNqB;AC8vB/B;;ASjtBA;EAoFM,4BVnIwB;EUoIxB,yBAAyB;EACzB,yBClEe;AVmsBrB;;ASvtBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,yBCvEa;AVysBrB;;AS7tBA;EA8FQ,yBAAyB;EACzB,yBC3Ea;AV8sBrB;;ASluBA;EAiGU,mDVhJoB;ACqxB9B;;AStuBA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,yBClFa;AVwtBrB;;AS5uBA;;EAyGQ,4BVxJsB;EUyJtB,wBVzJsB;EU0JtB,gBAAgB;ATwoBxB;;ASnvBA;EA6GQ,oCCzFa;ED0Fb,iBV7JsB;ACuyB9B;;ASxvBA;EAiHU,oCCjEuB;AV4sBjC;;AS5vBA;;EAoHU,oCChGW;EDiGX,yBAAyB;EACzB,gBAAgB;EAChB,iBVtKoB;ACmzB9B;;ASpwBA;EA0HU,sFAA4E;AT8oBtF;;ASxwBA;EA4HQ,6BAA6B;EAC7B,wBV5KsB;EU6KtB,iBV7KsB;AC6zB9B;;AS9wBA;EAmIU,4BVlLoB;EUmLpB,wBVnLoB;EUoLpB,yBCjHW;AVgwBrB;;ASpxBA;EAwIY,sEAA8D;ATgpB1E;;ASxxBA;EA8Ic,sFAA4E;AT8oB1F;;AS5xBA;;EAiJU,6BAA6B;EAC7B,wBVjMoB;EUkMpB,gBAAgB;EAChB,iBVnMoB;ACm1B9B;;ASpyBA;EAsJQ,6BAA6B;EAC7B,gCCnIa;EDoIb,yBCpIa;AVsxBrB;;AS1yBA;EA6JU,oCCzIW;ED0IX,iBV7MoB;AC81B9B;;AS/yBA;EAqKc,sEAA8D;AT8oB5E;;ASnzBA;;EAwKU,6BAA6B;EAC7B,gCCrJW;EDsJX,gBAAgB;EAChB,yBCvJW;AVuyBrB;;AS3zBA;EAoFM,yBV1IwB;EU2IxB,yBAAyB;EACzB,WChEU;AV2yBhB;;ASj0BA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVizBhB;;ASv0BA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVszBhB;;AS50BA;EAiGU,gDVvJoB;ACs4B9B;;ASh1BA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVg0BhB;;ASt1BA;;EAyGQ,yBV/JsB;EUgKtB,qBVhKsB;EUiKtB,gBAAgB;ATkvBxB;;AS71BA;EA6GQ,sBCvFQ;EDwFR,cVpKsB;ACw5B9B;;ASl2BA;EAiHU,yBCjEuB;AVszBjC;;ASt2BA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV7KoB;ACo6B9B;;AS92BA;EA0HU,0DAA4E;ATwvBtF;;ASl3BA;EA4HQ,6BAA6B;EAC7B,qBVnLsB;EUoLtB,cVpLsB;AC86B9B;;ASx3BA;EAmIU,yBVzLoB;EU0LpB,qBV1LoB;EU2LpB,WC/GM;AVw2BhB;;AS93BA;EAwIY,gEAA8D;AT0vB1E;;ASl4BA;EA8Ic,0DAA4E;ATwvB1F;;ASt4BA;;EAiJU,6BAA6B;EAC7B,qBVxMoB;EUyMpB,gBAAgB;EAChB,cV1MoB;ACo8B9B;;AS94BA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV83BhB;;ASp5BA;EA6JU,sBCvIM;EDwIN,cVpNoB;AC+8B9B;;ASz5BA;EAqKc,gEAA8D;ATwvB5E;;AS75BA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV+4BhB;;ASr6BA;EAoFM,yBV5H4B;EU6H5B,yBAAyB;EACzB,WChEU;AVq5BhB;;AS36BA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AV25BhB;;ASj7BA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVg6BhB;;ASt7BA;EAiGU,iDVzIwB;ACk+BlC;;AS17BA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AV06BhB;;ASh8BA;;EAyGQ,yBVjJ0B;EUkJ1B,qBVlJ0B;EUmJ1B,gBAAgB;AT41BxB;;ASv8BA;EA6GQ,sBCvFQ;EDwFR,cVtJ0B;ACo/BlC;;AS58BA;EAiHU,yBCjEuB;AVg6BjC;;ASh9BA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV/JwB;ACggClC;;ASx9BA;EA0HU,0DAA4E;ATk2BtF;;AS59BA;EA4HQ,6BAA6B;EAC7B,qBVrK0B;EUsK1B,cVtK0B;AC0gClC;;ASl+BA;EAmIU,yBV3KwB;EU4KxB,qBV5KwB;EU6KxB,WC/GM;AVk9BhB;;ASx+BA;EAwIY,gEAA8D;ATo2B1E;;AS5+BA;EA8Ic,0DAA4E;ATk2B1F;;ASh/BA;;EAiJU,6BAA6B;EAC7B,qBV1LwB;EU2LxB,gBAAgB;EAChB,cV5LwB;ACgiClC;;ASx/BA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVw+BhB;;AS9/BA;EA6JU,sBCvIM;EDwIN,cVtMwB;AC2iClC;;ASngCA;EAqKc,gEAA8D;ATk2B5E;;ASvgCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVy/BhB;;AS/gCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV++BrE;;ASphCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVq/BrE;;AS1hCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AV2/BrE;;AShiCA;EAoFM,yBV1H4B;EU2H5B,yBAAyB;EACzB,WChEU;AVghChB;;AStiCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVshChB;;AS5iCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AV2hChB;;ASjjCA;EAiGU,iDVvIwB;AC2lClC;;ASrjCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVqiChB;;AS3jCA;;EAyGQ,yBV/I0B;EUgJ1B,qBVhJ0B;EUiJ1B,gBAAgB;ATu9BxB;;ASlkCA;EA6GQ,sBCvFQ;EDwFR,cVpJ0B;AC6mClC;;ASvkCA;EAiHU,yBCjEuB;AV2hCjC;;AS3kCA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV7JwB;ACynClC;;ASnlCA;EA0HU,0DAA4E;AT69BtF;;ASvlCA;EA4HQ,6BAA6B;EAC7B,qBVnK0B;EUoK1B,cVpK0B;ACmoClC;;AS7lCA;EAmIU,yBVzKwB;EU0KxB,qBV1KwB;EU2KxB,WC/GM;AV6kChB;;ASnmCA;EAwIY,gEAA8D;AT+9B1E;;ASvmCA;EA8Ic,0DAA4E;AT69B1F;;AS3mCA;;EAiJU,6BAA6B;EAC7B,qBVxLwB;EUyLxB,gBAAgB;EAChB,cV1LwB;ACypClC;;ASnnCA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVmmChB;;ASznCA;EA6JU,sBCvIM;EDwIN,cVpMwB;ACoqClC;;AS9nCA;EAqKc,gEAA8D;AT69B5E;;ASloCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVonChB;;AS1oCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV0mCrE;;AS/oCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVgnCrE;;ASrpCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVsnCrE;;AS3pCA;EAoFM,yBV3H4B;EU4H5B,yBAAyB;EACzB,WChEU;AV2oChB;;ASjqCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVipChB;;ASvqCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVspChB;;AS5qCA;EAiGU,kDVxIwB;ACutClC;;AShrCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVgqChB;;AStrCA;;EAyGQ,yBVhJ0B;EUiJ1B,qBVjJ0B;EUkJ1B,gBAAgB;ATklCxB;;AS7rCA;EA6GQ,sBCvFQ;EDwFR,cVrJ0B;ACyuClC;;ASlsCA;EAiHU,yBCjEuB;AVspCjC;;AStsCA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV9JwB;ACqvClC;;AS9sCA;EA0HU,0DAA4E;ATwlCtF;;ASltCA;EA4HQ,6BAA6B;EAC7B,qBVpK0B;EUqK1B,cVrK0B;AC+vClC;;ASxtCA;EAmIU,yBV1KwB;EU2KxB,qBV3KwB;EU4KxB,WC/GM;AVwsChB;;AS9tCA;EAwIY,gEAA8D;AT0lC1E;;ASluCA;EA8Ic,0DAA4E;ATwlC1F;;AStuCA;;EAiJU,6BAA6B;EAC7B,qBVzLwB;EU0LxB,gBAAgB;EAChB,cV3LwB;ACqxClC;;AS9uCA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV8tChB;;ASpvCA;EA6JU,sBCvIM;EDwIN,cVrMwB;ACgyClC;;ASzvCA;EAqKc,gEAA8D;ATwlC5E;;AS7vCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV+uChB;;ASrwCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVquCrE;;AS1wCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AV2uCrE;;AShxCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVivCrE;;AStxCA;EAoFM,yBV7H4B;EU8H5B,yBAAyB;EACzB,WChEU;AVswChB;;AS5xCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AV4wChB;;ASlyCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVixChB;;ASvyCA;EAiGU,kDV1IwB;ACo1ClC;;AS3yCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AV2xChB;;ASjzCA;;EAyGQ,yBVlJ0B;EUmJ1B,qBVnJ0B;EUoJ1B,gBAAgB;AT6sCxB;;ASxzCA;EA6GQ,sBCvFQ;EDwFR,cVvJ0B;ACs2ClC;;AS7zCA;EAiHU,yBCjEuB;AVixCjC;;ASj0CA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cVhKwB;ACk3ClC;;ASz0CA;EA0HU,0DAA4E;ATmtCtF;;AS70CA;EA4HQ,6BAA6B;EAC7B,qBVtK0B;EUuK1B,cVvK0B;AC43ClC;;ASn1CA;EAmIU,yBV5KwB;EU6KxB,qBV7KwB;EU8KxB,WC/GM;AVm0ChB;;ASz1CA;EAwIY,gEAA8D;ATqtC1E;;AS71CA;EA8Ic,0DAA4E;ATmtC1F;;ASj2CA;;EAiJU,6BAA6B;EAC7B,qBV3LwB;EU4LxB,gBAAgB;EAChB,cV7LwB;ACk5ClC;;ASz2CA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVy1ChB;;AS/2CA;EA6JU,sBCvIM;EDwIN,cVvMwB;AC65ClC;;ASp3CA;EAqKc,gEAA8D;ATmtC5E;;ASx3CA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV02ChB;;ASh4CA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVg2CrE;;ASr4CA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVs2CrE;;AS34CA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AV42CrE;;ASj5CA;EAoFM,yBV9H4B;EU+H5B,yBAAyB;EACzB,yBClEe;AVm4CrB;;ASv5CA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,yBCvEa;AVy4CrB;;AS75CA;EA8FQ,yBAAyB;EACzB,yBC3Ea;AV84CrB;;ASl6CA;EAiGU,mDV3IwB;ACg9ClC;;ASt6CA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,yBClFa;AVw5CrB;;AS56CA;;EAyGQ,yBVnJ0B;EUoJ1B,qBVpJ0B;EUqJ1B,gBAAgB;ATw0CxB;;ASn7CA;EA6GQ,oCCzFa;ED0Fb,cVxJ0B;ACk+ClC;;ASx7CA;EAiHU,oCCjEuB;AV44CjC;;AS57CA;;EAoHU,oCChGW;EDiGX,yBAAyB;EACzB,gBAAgB;EAChB,cVjKwB;AC8+ClC;;ASp8CA;EA0HU,sFAA4E;AT80CtF;;ASx8CA;EA4HQ,6BAA6B;EAC7B,qBVvK0B;EUwK1B,cVxK0B;ACw/ClC;;AS98CA;EAmIU,yBV7KwB;EU8KxB,qBV9KwB;EU+KxB,yBCjHW;AVg8CrB;;ASp9CA;EAwIY,gEAA8D;ATg1C1E;;ASx9CA;EA8Ic,sFAA4E;AT80C1F;;AS59CA;;EAiJU,6BAA6B;EAC7B,qBV5LwB;EU6LxB,gBAAgB;EAChB,cV9LwB;AC8gDlC;;ASp+CA;EAsJQ,6BAA6B;EAC7B,gCCnIa;EDoIb,yBCpIa;AVs9CrB;;AS1+CA;EA6JU,oCCzIW;ED0IX,cVxMwB;ACyhDlC;;AS/+CA;EAqKc,gEAA8D;AT80C5E;;ASn/CA;;EAwKU,6BAA6B;EAC7B,gCCrJW;EDsJX,gBAAgB;EAChB,yBCvJW;AVu+CrB;;AS3/CA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV29CrE;;AShgDA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVi+CrE;;AStgDA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVu+CrE;;AS5gDA;EAoFM,yBVxH2B;EUyH3B,yBAAyB;EACzB,WChEU;AV4/ChB;;ASlhDA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVkgDhB;;ASxhDA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVugDhB;;AS7hDA;EAiGU,kDVrIuB;ACqkDjC;;ASjiDA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVihDhB;;ASviDA;;EAyGQ,yBV7IyB;EU8IzB,qBV9IyB;EU+IzB,gBAAgB;ATm8CxB;;AS9iDA;EA6GQ,sBCvFQ;EDwFR,cVlJyB;ACulDjC;;ASnjDA;EAiHU,yBCjEuB;AVugDjC;;ASvjDA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV3JuB;ACmmDjC;;AS/jDA;EA0HU,0DAA4E;ATy8CtF;;ASnkDA;EA4HQ,6BAA6B;EAC7B,qBVjKyB;EUkKzB,cVlKyB;AC6mDjC;;ASzkDA;EAmIU,yBVvKuB;EUwKvB,qBVxKuB;EUyKvB,WC/GM;AVyjDhB;;AS/kDA;EAwIY,gEAA8D;AT28C1E;;ASnlDA;EA8Ic,0DAA4E;ATy8C1F;;ASvlDA;;EAiJU,6BAA6B;EAC7B,qBVtLuB;EUuLvB,gBAAgB;EAChB,cVxLuB;ACmoDjC;;AS/lDA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV+kDhB;;ASrmDA;EA6JU,sBCvIM;EDwIN,cVlMuB;AC8oDjC;;AS1mDA;EAqKc,gEAA8D;ATy8C5E;;AS9mDA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVgmDhB;;AStnDA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVslDrE;;AS3nDA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AV4lDrE;;ASjoDA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVkmDrE;;ASvoDA;EARE,kBVdc;ACiqDhB;;ASrpDE;EACE,kBVkBc;ACsoDlB;;AS/oDA;EANE,eVjBW;AC0qDb;;ASnpDA;EAJE,kBVpBc;AC+qDhB;;ASvpDA;EAFE,iBVvBa;ACorDf;;AS3pDA;;EAyMI,uBVtP2B;EUuP3B,qBV5P0B;EU6P1B,gBAjOyB;EAkOzB,YAjOyB;ATwrD7B;;ASnqDA;EA8MI,aAAa;EACb,WAAW;ATy9Cf;;ASxqDA;EAiNI,6BAA6B;EAC7B,oBAAoB;AT29CxB;;AS7qDA;ERnDE,kBAAkB;EAKhB,6BAAmC;EACnC,4BAAkC;EQmQhC,6BAA6B;AT89CnC;;ASprDA;EAwNI,4BVvQ0B;EUwQ1B,qBV3Q0B;EU4Q1B,cV9Q0B;EU+Q1B,gBAAgB;EAChB,oBAAoB;ATg+CxB;;AS5rDA;EA8NI,qBVlNmB;EUmNnB,gCAA0D;EAC1D,iCAA2D;ATk+C/D;;ASh+CA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;ATm+C7B;;ASv+CA;EAMI,qBAAqB;ATq+CzB;;AS3+CA;ER1GI,oBQkHwC;ATu+C5C;;AS/+CA;EAUI,sBAAsB;ATy+C1B;;ASn/CA;EAYI,mBAAmB;AT2+CvB;;ASv/CA;EA1OE,kBVdc;ACmvDhB;;ASvuDE;EACE,kBVkBc;ACwtDlB;;AS//CA;EAtOE,kBVpBc;AC6vDhB;;ASngDA;EApOE,iBVvBa;ACkwDf;;ASvgDA;EA0BQ,4BAA4B;EAC5B,yBAAyB;ATi/CjC;;AS5gDA;EA6BQ,6BAA6B;EAC7B,0BAA0B;ERxI9B,kBQyIwC;ATm/C5C;;ASlhDA;ER1GI,eQ2IqC;ATq/CzC;;ASthDA;EAoCQ,UAAU;ATs/ClB;;AS1hDA;EA0CQ,UAAU;ATo/ClB;;AS9hDA;EA4CU,UAAU;ATs/CpB;;ASliDA;EA8CQ,YAAY;EACZ,cAAc;ATw/CtB;;ASviDA;EAiDI,uBAAuB;AT0/C3B;;AS3iDA;EAoDQ,oBAAoB;EACpB,qBAAqB;AT2/C7B;;AShjDA;EAuDI,yBAAyB;AT6/C7B;;ASpjDA;EA0DQ,oBAAoB;EACpB,qBAAqB;AT8/C7B;;ACzvDE;EQiQM;IACE,oBAlTyD;ET8yDjE;ES1/CM;;IAEE,qBAtT0F;ETkzDlG;ESjgDM;IACE,kBV1TM;EC6zDd;ESpgDM;IACE,eV3TG;ECi0DX;AACF;;ACrwDE;EQ6PM;IACE,qBAlTyL;ET8zDjM;ES1gDM;;IAEE,kBV9TM;EC00Dd;ESjhDM;IACE,eV3TG;EC80DX;ESphDM;IACE,kBV5TM;ECk1Dd;AACF;;AWl3DA;EACE,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,WAAW;AXq3Db;;AWz3DA;EAMI,0BAA0B;EAC1B,kBZyCM;EYxCN,mBZwCM;EYvCN,WAAW;AXu3Df;;AC/wDE;EUjHF;IAWI,gBAAuC;EX03DzC;AACF;;AC3wDI;EU3HJ;IAcM,iBAAqE;EX63DzE;AACF;;AClwDI;EU1IJ;IAiBM,iBAAiE;EXg4DrE;AACF;;AClxDI;EUhIJ;IAoBM,iBAAqE;EXm4DzE;AACF;;ACzwDI;EU/IJ;IAuBM,iBAAiE;EXs4DrE;AACF;;AY34DA;EAII,kBAAkB;AZ24DtB;;AY/4DA;;;;;;;EAcM,kBAhC2B;AZ26DjC;;AYz5DA;;;;;;EAqBI,cbvC0B;EawC1B,gBbHiB;EaIjB,kBA3C+B;AZw7DnC;;AYp6DA;EAyBI,cAAc;EACd,oBAAoB;AZ+4DxB;;AYz6DA;EA4BM,eAAe;AZi5DrB;;AY76DA;EA8BI,iBAAiB;EACjB,uBAAuB;AZm5D3B;;AYl7DA;EAiCM,oBAAoB;AZq5D1B;;AYt7DA;EAmCI,gBAAgB;EAChB,uBAAuB;AZu5D3B;;AY37DA;EAsCM,oBAAoB;AZy5D1B;;AY/7DA;EAwCI,iBAAiB;EACjB,oBAAoB;AZ25DxB;;AYp8DA;EA2CI,kBAAkB;EAClB,uBAAuB;AZ65D3B;;AYz8DA;EA8CI,cAAc;EACd,kBAAkB;AZ+5DtB;;AY98DA;EAiDI,4Bb5D0B;EEuK1B,8BF1K0B;EaiE1B,qBAjEqC;AZk+DzC;;AYp9DA;EAqDI,4BAA4B;EXuG5B,gBWtGmC;EACnC,eAAe;AZm6DnB;;AY19DA;EAyDM,wBAAwB;AZq6D9B;;AY99DA;EA2DQ,4BAA4B;AZu6DpC;;AYl+DA;EA6DQ,4BAA4B;AZy6DpC;;AYt+DA;EA+DQ,4BAA4B;AZ26DpC;;AY1+DA;EAiEQ,4BAA4B;AZ66DpC;;AY9+DA;EAmEI,wBAAwB;EXyFxB,gBWxFmC;EACnC,eAAe;AZ+6DnB;;AYp/DA;EAuEM,uBAAuB;EACvB,iBAAiB;AZi7DvB;;AYz/DA;EA0EQ,uBAAuB;AZm7D/B;;AY7/DA;EX4JI,gBWhFmC;AZq7DvC;;AYjgEA;EA8EI,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;AZu7DtB;;AYvgEA;EAkFM,eAAe;AZy7DrB;;AY3gEA;EAoFM,kBAAkB;AZ27DxB;;AY/gEA;EAsFM,qBAAqB;AZ67D3B;;AYnhEA;EAwFM,kBAAkB;AZ+7DxB;;AYvhEA;EX2CE,iCAAiC;EWgD/B,gBAAgB;EAChB,qBAxG8B;EAyG9B,gBAAgB;EAChB,iBAAiB;AZi8DrB;;AY/hEA;;EAiGI,cAAc;AZm8DlB;;AYpiEA;EAmGI,WAAW;AZq8Df;;AYxiEA;;EAsGM,yBbpHwB;EaqHxB,qBAhHmC;EAiHnC,qBAhHmC;EAiHnC,mBAAmB;AZu8DzB;;AYhjEA;EA2GM,cb7HwB;ACskE9B;;AYpjEA;EA6GQ,mBAAmB;AZ28D3B;;AYxjEA;;EAiHQ,qBAvHsC;EAwHtC,cbpIsB;ACglE9B;;AY9jEA;;EAsHQ,qBAzHsC;EA0HtC,cbzIsB;ACslE9B;;AYpkEA;;EA6HY,sBAjI4C;AZ6kExD;;AYzkEA;EAgIM,aAAa;AZ68DnB;;AY7kEA;EAmII,kBbrHY;ACmkEhB;;AYjlEA;EAqII,ebxHS;ACwkEb;;AYrlEA;EAuII,kBb3HY;AC6kEhB;;AYzlEA;EAyII,iBb9HW;ACklEf;;Aa/mEA;EACE,mBAAmB;EACnB,oBAAoB;EACpB,uBAAuB;EACvB,cAVsB;EAWtB,aAXsB;Ab6nExB;;AavnEA;EAQI,YAbwB;EAcxB,WAdwB;AbioE5B;;Aa5nEA;EAWI,YAfyB;EAgBzB,WAhByB;AbqoE7B;;AajoEA;EAcI,YAjBwB;EAkBxB,WAlBwB;AbyoE5B;;AarnEA;EACE,uBAAuB;EACvB,cAAc;EACd,oBAAoB;EACpB,eAAe;EACf,mBA5BsB;EA6BtB,mBAAmB;AbwnErB;;Aa9nEA;EAQI,YAAY;EACZ,cAAc;Ab0nElB;;AanoEA;EAYQ,oBA/BkB;Ab0pE1B;;AavoEA;EAiBQ,mBApCkB;Ab8pE1B;;AatnEA;EACE,aAAa;AbynEf;;AclqEA;EACE,cAAc;EACd,kBAAkB;AdqqEpB;;AcvqEA;EAII,cAAc;EACd,YAAY;EACZ,WAAW;AduqEf;;Ac7qEA;EAQM,qBf4DiB;AC6mEvB;;AcjrEA;EAUI,WAAW;Ad2qEf;;AcrrEA;;;;;;;;;;;;;;;;;EA+BM,YAAY;EACZ,WAAW;Ad0qEjB;;Ac1sEA;EAmCI,iBAAiB;Ad2qErB;;Ac9sEA;EAqCI,gBAAgB;Ad6qEpB;;AcltEA;EAuCI,gBAAgB;Ad+qEpB;;ActtEA;EAyCI,qBAAqB;AdirEzB;;Ac1tEA;EA2CI,gBAAgB;AdmrEpB;;Ac9tEA;EA6CI,mBAAmB;AdqrEvB;;AcluEA;EA+CI,gBAAgB;AdurEpB;;ActuEA;EAiDI,qBAAqB;AdyrEzB;;Ac1uEA;EAmDI,iBAAiB;Ad2rErB;;Ac9uEA;EAqDI,sBAAsB;Ad6rE1B;;AclvEA;EAuDI,iBAAiB;Ad+rErB;;ActvEA;EAyDI,sBAAsB;AdisE1B;;Ac1vEA;EA2DI,sBAAsB;AdmsE1B;;Ac9vEA;EA6DI,iBAAiB;AdqsErB;;AclwEA;EA+DI,iBAAiB;AdusErB;;ActwEA;EAmEM,YAAwB;EACxB,WAAuB;AdusE7B;;Ac3wEA;EAmEM,YAAwB;EACxB,WAAuB;Ad4sE7B;;AchxEA;EAmEM,YAAwB;EACxB,WAAuB;AditE7B;;AcrxEA;EAmEM,YAAwB;EACxB,WAAuB;AdstE7B;;Ac1xEA;EAmEM,YAAwB;EACxB,WAAuB;Ad2tE7B;;Ac/xEA;EAmEM,YAAwB;EACxB,WAAuB;AdguE7B;;AcpyEA;EAmEM,aAAwB;EACxB,YAAuB;AdquE7B;;AelyEA;EAEE,4BhBA4B;EgBC5B,kBhBwDU;EgBvDV,kBAAkB;EAEhB,sCAXoD;Af8yExD;;AezyEA;EAUI,mBAAmB;EACnB,0BAA0B;AfmyE9B;;Ae9yEA;EAaI,mBAAmB;AfqyEvB;;AelzEA;;EAgBI,iBhBZ2B;ACmzE/B;;AevzEA;EAkBI,uBAAuB;AfyyE3B;;Ae3zEA;EdiLI,ac7J4B;EAC5B,kBAAkB;EAClB,WAAW;Af2yEf;;Aej0EA;;;EA0BI,mBAAmB;Af6yEvB;;Aev0EA;EAgCM,uBhB5ByB;EgB6BzB,chB1CuB;ACq1E7B;;Ae50EA;EAgCM,yBhBzCuB;EgB0CvB,YhB7ByB;AC60E/B;;Aej1EA;EAgCM,4BhB9BwB;EgB+BxB,yBLoCe;AVixErB;;Aet1EA;EAgCM,yBhBrCwB;EgBsCxB,WLsCU;AVoxEhB;;Ae31EA;EAgCM,yBhBvB4B;EgBwB5B,WLsCU;AVyxEhB;;Aeh2EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AV+wErE;;Aer2EA;EAgCM,yBhBrB4B;EgBsB5B,WLsCU;AVmyEhB;;Ae12EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVyxErE;;Ae/2EA;EAgCM,yBhBtB4B;EgBuB5B,WLsCU;AV6yEhB;;Aep3EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVmyErE;;Aez3EA;EAgCM,yBhBxB4B;EgByB5B,WLsCU;AVuzEhB;;Ae93EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AV6yErE;;Aen4EA;EAgCM,yBhBzB4B;EgB0B5B,yBLoCe;AVm0ErB;;Aex4EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVuzErE;;Ae74EA;EAgCM,yBhBnB2B;EgBoB3B,WLsCU;AV20EhB;;Ael5EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVi0ErE;;AgBx5EA;EAEE,qBAAqB;EACrB,wBAAwB;EACxB,YAAY;EACZ,qBjByDqB;EiBxDrB,cAAc;EACd,YjBoBW;EiBnBX,gBAAgB;EAChB,UAAU;EACV,WAAW;AhB05Eb;;AgBp6EA;EAYI,yBjBX2B;ACu6E/B;;AgBx6EA;EAcI,yBjBjB0B;AC+6E9B;;AgB56EA;EAgBI,yBjBnB0B;ACm7E9B;;AgBh7EA;EAkBI,yBjBrB0B;EiBsB1B,YAAY;AhBk6EhB;;AgBr7EA;EAyBQ,uBjBpBuB;ACo7E/B;;AgBz7EA;EA2BQ,uBjBtBuB;ACw7E/B;;AgB77EA;EA6BQ,uBjBxBuB;AC47E/B;;AgBj8EA;EA+BQ,mEAA2F;AhBs6EnG;;AgBr8EA;EAyBQ,yBjBjCqB;ACi9E7B;;AgBz8EA;EA2BQ,yBjBnCqB;ACq9E7B;;AgB78EA;EA6BQ,yBjBrCqB;ACy9E7B;;AgBj9EA;EA+BQ,qEAA2F;AhBs7EnG;;AgBr9EA;EAyBQ,4BjBtBsB;ACs9E9B;;AgBz9EA;EA2BQ,4BjBxBsB;AC09E9B;;AgB79EA;EA6BQ,4BjB1BsB;AC89E9B;;AgBj+EA;EA+BQ,wEAA2F;AhBs8EnG;;AgBr+EA;EAyBQ,yBjB7BsB;AC6+E9B;;AgBz+EA;EA2BQ,yBjB/BsB;ACi/E9B;;AgB7+EA;EA6BQ,yBjBjCsB;ACq/E9B;;AgBj/EA;EA+BQ,qEAA2F;AhBs9EnG;;AgBr/EA;EAyBQ,yBjBf0B;AC++ElC;;AgBz/EA;EA2BQ,yBjBjB0B;ACm/ElC;;AgB7/EA;EA6BQ,yBjBnB0B;ACu/ElC;;AgBjgFA;EA+BQ,qEAA2F;AhBs+EnG;;AgBrgFA;EAyBQ,yBjBb0B;AC6/ElC;;AgBzgFA;EA2BQ,yBjBf0B;ACigFlC;;AgB7gFA;EA6BQ,yBjBjB0B;ACqgFlC;;AgBjhFA;EA+BQ,qEAA2F;AhBs/EnG;;AgBrhFA;EAyBQ,yBjBd0B;AC8gFlC;;AgBzhFA;EA2BQ,yBjBhB0B;ACkhFlC;;AgB7hFA;EA6BQ,yBjBlB0B;ACshFlC;;AgBjiFA;EA+BQ,qEAA2F;AhBsgFnG;;AgBriFA;EAyBQ,yBjBhB0B;ACgiFlC;;AgBziFA;EA2BQ,yBjBlB0B;ACoiFlC;;AgB7iFA;EA6BQ,yBjBpB0B;ACwiFlC;;AgBjjFA;EA+BQ,qEAA2F;AhBshFnG;;AgBrjFA;EAyBQ,yBjBjB0B;ACijFlC;;AgBzjFA;EA2BQ,yBjBnB0B;ACqjFlC;;AgB7jFA;EA6BQ,yBjBrB0B;ACyjFlC;;AgBjkFA;EA+BQ,qEAA2F;AhBsiFnG;;AgBrkFA;EAyBQ,yBjBXyB;AC2jFjC;;AgBzkFA;EA2BQ,yBjBbyB;AC+jFjC;;AgB7kFA;EA6BQ,yBjBfyB;ACmkFjC;;AgBjlFA;EA+BQ,qEAA2F;AhBsjFnG;;AgBrlFA;EAkCI,gCAtCkC;UAsClC,wBAtCkC;EAuClC,2CAAmC;UAAnC,mCAAmC;EACnC,yCAAiC;UAAjC,iCAAiC;EACjC,yCAAiC;UAAjC,iCAAiC;EACjC,yBjBrC2B;EiBsC3B,qEAA0F;EAC1F,6BAA6B;EAC7B,4BAA4B;EAC5B,0BAA0B;AhBujF9B;;AgBjmFA;EA4CM,6BAA6B;AhByjFnC;;AgBrmFA;EA8CM,6BAA6B;AhB2jFnC;;AgBzmFA;EAgDM,oBAAoB;AhB6jF1B;;AgB7mFA;EAoDI,ejBxBY;ACqlFhB;;AgBjnFA;EAsDI,ejB5BY;AC2lFhB;;AgBrnFA;EAwDI,cjB/BW;ACgmFf;;AgB/jFA;EACE;IACE,2BAA2B;EhBkkF7B;EgBjkFA;IACE,4BAA4B;EhBmkF9B;AACF;;AgBxkFA;EACE;IACE,2BAA2B;EhBkkF7B;EgBjkFA;IACE,4BAA4B;EhBmkF9B;AACF;;AiB9mFA;EAEE,uBlBjB6B;EkBkB7B,clB3B4B;AC2oF9B;;AiBnnFA;;EAMI,yBlB1B0B;EkB2B1B,qBA/B6B;EAgC7B,qBA/B6B;EAgC7B,mBAAmB;AjBknFvB;;AiB3nFA;;EAeQ,uBlB9BuB;EkB+BvB,mBlB/BuB;EkBgCvB,clB7CqB;AC8pF7B;;AiBloFA;;EAeQ,yBlB3CqB;EkB4CrB,qBlB5CqB;EkB6CrB,YlBhCuB;ACwpF/B;;AiBzoFA;;EAeQ,4BlBhCsB;EkBiCtB,wBlBjCsB;EkBkCtB,yBPiCa;AV8lFrB;;AiBhpFA;;EAeQ,yBlBvCsB;EkBwCtB,qBlBxCsB;EkByCtB,WPmCQ;AVmmFhB;;AiBvpFA;;EAeQ,yBlBzB0B;EkB0B1B,qBlB1B0B;EkB2B1B,WPmCQ;AV0mFhB;;AiB9pFA;;EAeQ,yBlBvB0B;EkBwB1B,qBlBxB0B;EkByB1B,WPmCQ;AVinFhB;;AiBrqFA;;EAeQ,yBlBxB0B;EkByB1B,qBlBzB0B;EkB0B1B,WPmCQ;AVwnFhB;;AiB5qFA;;EAeQ,yBlB1B0B;EkB2B1B,qBlB3B0B;EkB4B1B,WPmCQ;AV+nFhB;;AiBnrFA;;EAeQ,yBlB3B0B;EkB4B1B,qBlB5B0B;EkB6B1B,yBPiCa;AVwoFrB;;AiB1rFA;;EAeQ,yBlBrByB;EkBsBzB,qBlBtByB;EkBuBzB,WPmCQ;AV6oFhB;;AiBjsFA;;EAoBM,mBAAmB;EACnB,SAAS;AjBkrFf;;AiBvsFA;;EAuBM,yBlBjC4B;EkBkC5B,WP4BU;AVypFhB;;AiB7sFA;;;;EA2BQ,mBAAmB;AjByrF3B;;AiBptFA;;EA6BM,sBAAsB;AjB4rF5B;;AiBztFA;EA+BI,clBvD0B;ACqvF9B;;AiB7tFA;EAiCM,gBAtDsB;AjBsvF5B;;AiBjuFA;EAoCM,yBlB9C4B;EkB+C5B,WPeU;AVkrFhB;;AiBtuFA;;EAwCQ,mBAAmB;AjBmsF3B;;AiB3uFA;;EA2CQ,kBPSQ;EORR,mBAAmB;AjBqsF3B;;AiBjvFA;EA8CI,6BA5DqC;AjBmwFzC;;AiBrvFA;;EAiDM,qBApEgC;EAqEhC,clB1EwB;ACmxF9B;;AiB3vFA;EAoDI,6BAhEqC;AjB2wFzC;;AiB/vFA;;EAuDM,qBAxEgC;EAyEhC,clBhFwB;AC6xF9B;;AiBrwFA;EA0DI,6BAvEqC;AjBsxFzC;;AiBzwFA;;EA+DU,sBAAsB;AjB+sFhC;;AiB9wFA;;EAoEM,iBAAiB;AjB+sFvB;;AiBnxFA;;EAyEU,wBAAwB;AjB+sFlC;;AiBxxFA;EA2EI,WAAW;AjBitFf;;AiB5xFA;EAgFU,yBlBhGoB;ACgzF9B;;AiBhyFA;EAqFY,yBlBrGkB;ACozF9B;;AiBpyFA;EAuFc,4BlBxGgB;ACyzF9B;;AiBxyFA;;EA2FM,qBAAqB;AjBktF3B;;AiB7yFA;EAgGU,yBlBhHoB;ACi0F9B;;AiB/sFA;EhB7DE,iCAAiC;EgBgEjC,cAAc;EACd,kBAAkB;EAClB,eAAe;AjBitFjB;;AkB70FA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;AlBg1F7B;;AkBp1FA;EAMI,qBAAqB;AlBk1FzB;;AkBx1FA;EjB2KI,oBiBnKwC;AlBo1F5C;;AkB51FA;EAUI,sBAAsB;AlBs1F1B;;AkBh2FA;EAYI,mBAAmB;AlBw1FvB;;AkBp2FA;EAgBM,enBYO;AC40Fb;;AkBx2FA;EAmBM,kBnBQU;ACi1FhB;;AkB52FA;EAqBI,uBAAuB;AlB21F3B;;AkBh3FA;EAuBM,qBAAqB;EACrB,oBAAoB;AlB61F1B;;AkBr3FA;EA0BI,yBAAyB;AlB+1F7B;;AkBz3FA;EA6BQ,mBAAmB;AlBg2F3B;;AkB73FA;EA+BQ,eAAe;AlBk2FvB;;AkBj4FA;EjB2KI,eiBzImC;AlBm2FvC;;AkBr4FA;EjB2KI,ciBvIqC;EAE/B,yBAAyB;EACzB,4BAA4B;AlBo2FtC;;AkB34FA;EA6CU,0BAA0B;EAC1B,6BAA6B;AlBk2FvC;;AkB71FA;EACE,mBAAmB;EACnB,4BnBjD4B;EmBkD5B,kBnBOU;EmBNV,cnBzD4B;EmB0D5B,oBAAoB;EACpB,kBnB5Bc;EmB6Bd,WAAW;EACX,uBAAuB;EACvB,gBAAgB;EAChB,oBAAoB;EACpB,qBAAqB;EACrB,mBAAmB;AlBg2FrB;;AkB52FA;EjBwHI,oBiB1GuC;EjB0GvC,uBiBzGyC;AlBk2F7C;;AkBj3FA;EAqBM,uBnBlEyB;EmBmEzB,cnBhFuB;ACg7F7B;;AkBt3FA;EAqBM,yBnB/EuB;EmBgFvB,YnBnEyB;ACw6F/B;;AkB33FA;EAqBM,4BnBpEwB;EmBqExB,yBRFe;AV42FrB;;AkBh4FA;EAqBM,yBnB3EwB;EmB4ExB,WRAU;AV+2FhB;;AkBr4FA;EAqBM,yBnB7D4B;EmB8D5B,WRAU;AVo3FhB;;AkB14FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV02FrE;;AkB/4FA;EAqBM,yBnB3D4B;EmB4D5B,WRAU;AV83FhB;;AkBp5FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVo3FrE;;AkBz5FA;EAqBM,yBnB5D4B;EmB6D5B,WRAU;AVw4FhB;;AkB95FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV83FrE;;AkBn6FA;EAqBM,yBnB9D4B;EmB+D5B,WRAU;AVk5FhB;;AkBx6FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVw4FrE;;AkB76FA;EAqBM,yBnB/D4B;EmBgE5B,yBRFe;AV85FrB;;AkBl7FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVk5FrE;;AkBv7FA;EAqBM,yBnBzD2B;EmB0D3B,WRAU;AVs6FhB;;AkB57FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV45FrE;;AkBj8FA;EAgCI,kBnBtDY;AC29FhB;;AkBr8FA;EAkCI,enBzDS;ACg+Fb;;AkBz8FA;EAoCI,kBnB5DY;ACq+FhB;;AkB78FA;EjBwHI,qBiBjF0C;EjBiF1C,sBiBhF0C;AlB06F9C;;AkBl9FA;EjBwHI,qBiB9E0C;EjB8E1C,sBiB7E0C;AlB46F9C;;AkBv9FA;EjBwHI,qBiB3E0C;EjB2E1C,sBiB1E0C;AlB86F9C;;AkB59FA;EjBwHI,gBiB/KmB;EAyGnB,UAAU;EACV,kBAAkB;EAClB,UAAU;AlB+6Fd;;AkBn+FA;EAuDM,8BAA8B;EAC9B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,0DAA0D;EAC1D,+BAA+B;AlBg7FrC;;AkB9+FA;EAgEM,WAAW;EACX,UAAU;AlBk7FhB;;AkBn/FA;EAmEM,WAAW;EACX,UAAU;AlBo7FhB;;AkBx/FA;EAuEM,yBAAmD;AlBq7FzD;;AkB5/FA;EAyEM,yBAAoD;AlBu7F1D;;AkBhgGA;EA2EI,qBnB/DmB;ACw/FvB;;AkBv7FA;EAEI,0BAA0B;AlBy7F9B;;AmB/iGA;;EAGE,sBAAsB;AnBijGxB;;AmBpjGA;;;;EAMI,oBAAoB;AnBqjGxB;;AmB3jGA;;EAQI,iBApBmB;AnB4kGvB;;AmBhkGA;;EAUI,iBArBmB;AnBglGvB;;AmBrkGA;;EAYI,sBAAsB;AnB8jG1B;;AmB5jGA;EACE,cpB9B4B;EoBiC5B,epBLW;EoBMX,gBpBGmB;EoBFnB,kBAnCuB;AnBgmGzB;;AmBnkGA;EAQI,cApCwB;EAqCxB,oBApCyB;AnBmmG7B;;AmBxkGA;EAWI,oBA3B+B;AnB4lGnC;;AmB5kGA;EAgBM,epBnBO;ACmlGb;;AmBhlGA;EAgBM,iBpBlBS;ACslGf;;AmBplGA;EAgBM,epBjBO;ACylGb;;AmBxlGA;EAgBM,iBpBhBS;AC4lGf;;AmB5lGA;EAgBM,kBpBfU;AC+lGhB;;AmBhmGA;EAgBM,epBdO;ACkmGb;;AmBpmGA;EAgBM,kBpBbU;ACqmGhB;;AmBtlGA;EACE,cpB/C4B;EoBkD5B,kBpBrBc;EoBsBd,gBpBjBiB;EoBkBjB,iBA3CyB;AnBkoG3B;;AmB7lGA;EAQI,cpBvD0B;EoBwD1B,gBpBnBiB;AC4mGrB;;AmBlmGA;EAWI,oBA7C+B;AnBwoGnC;;AmBtmGA;EAgBM,epBrCO;AC+nGb;;AmB1mGA;EAgBM,iBpBpCS;ACkoGf;;AmB9mGA;EAgBM,epBnCO;ACqoGb;;AmBlnGA;EAgBM,iBpBlCS;ACwoGf;;AmBtnGA;EAgBM,kBpBjCU;AC2oGhB;;AmB1nGA;EAgBM,epBhCO;AC8oGb;;AmB9nGA;EAgBM,kBpB/BU;ACipGhB;;AoB/qGA;EACE,cAAc;EACd,eAAe;EACf,mBAAmB;EACnB,kBAAkB;EAClB,yBAAyB;ApBkrG3B;;AoB7qGA;EACE,mBAAmB;EACnB,4BrBP4B;EqBQ5B,qBrBmDqB;EqBlDrB,oBAAoB;EACpB,kBrBac;EqBZd,WAAW;EACX,uBAAuB;EACvB,oBAAoB;EACpB,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;EAClB,mBAAmB;ApBgrGrB;;AqB9sGA,eAAA;AC0DA;EAxBE,uBvBnB6B;EuBoB7B,qBvBzB4B;EuB0B5B,kBvBkCU;EuBjCV,cvB/B4B;ACgtG9B;;AC9oGI;EqBjCA,4BvBjC0B;ACotG9B;;AClpGI;EqBjCA,4BvBjC0B;ACwtG9B;;ACtpGI;EqBjCA,4BvBjC0B;AC4tG9B;;AC1pGI;EqBjCA,4BvBjC0B;ACguG9B;;AsB9rGE;EAEE,qBvBjC0B;ACiuG9B;;AsB/rGE;EAIE,qBvBzB8B;EuB0B9B,iDvB1B8B;ACytGlC;;AsB9rGE;;;;;EAEE,4BvBtC0B;EuBuC1B,wBvBvC0B;EuBwC1B,gBAAgB;EAChB,cvB9C0B;ACkvG9B;;AClrGI;;;;;EqBhBE,+BvBhDwB;AC0vG9B;;AC1rGI;;;;;EqBhBE,+BvBhDwB;ACkwG9B;;AClsGI;;;;;EqBhBE,+BvBhDwB;AC0wG9B;;AC1sGI;;;;;EqBhBE,+BvBhDwB;ACkxG9B;;AuBpxGA;EAEE,2DxBN2B;EwBO3B,eAAe;EACf,WAAW;AvBsxGb;;AuBrxGE;EACE,gBAAgB;AvBwxGpB;;AuBpxGI;EACE,mBxBFyB;ACyxG/B;;AuBxxGK;EAMG,mDxBPuB;AC6xG/B;;AuB5xGI;EACE,qBxBfuB;AC8yG7B;;AuBhyGK;EAMG,gDxBpBqB;ACkzG7B;;AuBpyGI;EACE,wBxBJwB;AC2yG9B;;AuBxyGK;EAMG,mDxBTsB;AC+yG9B;;AuB5yGI;EACE,qBxBXwB;AC0zG9B;;AuBhzGK;EAMG,gDxBhBsB;AC8zG9B;;AuBpzGI;EACE,qBxBG4B;ACozGlC;;AuBxzGK;EAMG,iDxBF0B;ACwzGlC;;AuB5zGI;EACE,qBxBK4B;AC0zGlC;;AuBh0GK;EAMG,iDxBA0B;AC8zGlC;;AuBp0GI;EACE,qBxBI4B;ACm0GlC;;AuBx0GK;EAMG,kDxBD0B;ACu0GlC;;AuB50GI;EACE,qBxBE4B;AC60GlC;;AuBh1GK;EAMG,kDxBH0B;ACi1GlC;;AuBp1GI;EACE,qBxBC4B;ACs1GlC;;AuBx1GK;EAMG,mDxBJ0B;AC01GlC;;AuB51GI;EACE,qBxBO2B;ACw1GjC;;AuBh2GK;EAMG,kDxBEyB;AC41GjC;;AuB51GE;EzBmBA,kBC0BgB;EDzBhB,kBCNc;ACm1GhB;;AuB/1GE;EzBoBA,kBCVc;ACy1GhB;;AuBj2GE;EzBoBA,iBCba;AC81Gf;;AuBl2GE;EACE,cAAc;EACd,WAAW;AvBq2Gf;;AuBp2GE;EACE,eAAe;EACf,WAAW;AvBu2Gf;;AuBr2GA;EAGI,qBxB+BmB;EwB9BnB,gDAA4D;EAC5D,iDAA6D;AvBs2GjE;;AuB32GA;EAOI,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;AvBw2GpB;;AuBt2GA;EAEE,cAAc;EACd,eAAe;EACf,eAAe;EACf,2BzB7CkE;EyB8ClE,gBAAgB;AvBw2GlB;;AuB92GA;EAQI,gBA1DsB;EA2DtB,eA1DqB;AvBo6GzB;;AuBn3GA;EAWI,eAAe;AvB42GnB;;AuBv3GA;EAcI,YAAY;AvB62GhB;;AwB96GA;EACE,eAAe;EACf,qBAAqB;EACrB,iBAAiB;EACjB,kBAAkB;AxBi7GpB;;AwBh7GE;EACE,eAAe;AxBm7GnB;;AwBl7GE;EACE,czBF0B;ACu7G9B;;AwBp7GE;;;;;EAGE,czBJ0B;EyBK1B,mBAAmB;AxBy7GvB;;AwBp7GA;EvBkKI,kBuB/JqC;AxBq7GzC;;AyBx8GA;EACE,qBAAqB;EACrB,eAAe;EACf,kBAAkB;EAClB,mBAAmB;AzB28GrB;;AyB/8GA;EAMI,a3BDkB;AE88GtB;;AyBn9GA;EAUM,qB1BU4B;EEsK9B,cwB/K+B;EAC7B,UAAU;AzB68GhB;;AyBz9GA;EAeM,qB1BuDiB;EE4GnB,iBwBlKsC;AzB88G1C;;AyB99GA;EAmBI,eAAe;EACf,cAAc;EACd,cAAc;EACd,eAAe;EACf,aAAa;AzB+8GjB;;AyBt+GA;EAyBM,aAAa;AzBi9GnB;;AyB1+GA;;EA4BM,wB1BjBwB;ACo+G9B;;AyB/+GA;ExBkLI,oBwBpJwC;AzBq9G5C;;AyBn/GA;EAgCM,YAAY;EACZ,UAAU;AzBu9GhB;;AyBx/GA;EAmCQ,kBAAkB;AzBy9G1B;;AyB5/GA;EAuCM,qB1BnCwB;AC4/G9B;;AyBhgHA;EA6CQ,mB1BhCuB;ACu/G/B;;AyBpgHA;EA+CQ,mB1BlCuB;AC2/G/B;;AyBxgHA;EAkDU,qBfwDuB;AVk6GjC;;AyB5gHA;EAuDU,mD1B1CqB;ACmgH/B;;AyBhhHA;EA6CQ,qB1B7CqB;ACohH7B;;AyBphHA;EA+CQ,qB1B/CqB;ACwhH7B;;AyBxhHA;EAkDU,mBfwDuB;AVk7GjC;;AyB5hHA;EAuDU,gD1BvDmB;ACgiH7B;;AyBhiHA;EA6CQ,wB1BlCsB;ACyhH9B;;AyBpiHA;EA+CQ,wB1BpCsB;AC6hH9B;;AyBxiHA;EAkDU,qBfwDuB;AVk8GjC;;AyB5iHA;EAuDU,mD1B5CoB;ACqiH9B;;AyBhjHA;EA6CQ,qB1BzCsB;ACgjH9B;;AyBpjHA;EA+CQ,qB1B3CsB;ACojH9B;;AyBxjHA;EAkDU,qBfwDuB;AVk9GjC;;AyB5jHA;EAuDU,gD1BnDoB;AC4jH9B;;AyBhkHA;EA6CQ,qB1B3B0B;ACkjHlC;;AyBpkHA;EA+CQ,qB1B7B0B;ACsjHlC;;AyBxkHA;EAkDU,qBfwDuB;AVk+GjC;;AyB5kHA;EAuDU,iD1BrCwB;AC8jHlC;;AyBhlHA;EA6CQ,qB1BzB0B;ACgkHlC;;AyBplHA;EA+CQ,qB1B3B0B;ACokHlC;;AyBxlHA;EAkDU,qBfwDuB;AVk/GjC;;AyB5lHA;EAuDU,iD1BnCwB;AC4kHlC;;AyBhmHA;EA6CQ,qB1B1B0B;ACilHlC;;AyBpmHA;EA+CQ,qB1B5B0B;ACqlHlC;;AyBxmHA;EAkDU,qBfwDuB;AVkgHjC;;AyB5mHA;EAuDU,kD1BpCwB;AC6lHlC;;AyBhnHA;EA6CQ,qB1B5B0B;ACmmHlC;;AyBpnHA;EA+CQ,qB1B9B0B;ACumHlC;;AyBxnHA;EAkDU,qBfwDuB;AVkhHjC;;AyB5nHA;EAuDU,kD1BtCwB;AC+mHlC;;AyBhoHA;EA6CQ,qB1B7B0B;AConHlC;;AyBpoHA;EA+CQ,qB1B/B0B;ACwnHlC;;AyBxoHA;EAkDU,qBfwDuB;AVkiHjC;;AyB5oHA;EAuDU,mD1BvCwB;ACgoHlC;;AyBhpHA;EA6CQ,qB1BvByB;AC8nHjC;;AyBppHA;EA+CQ,qB1BzByB;ACkoHjC;;AyBxpHA;EAkDU,qBfwDuB;AVkjHjC;;AyB5pHA;EAuDU,kD1BjCuB;AC0oHjC;;AyBhqHA;E3ByCE,kBC0BgB;EDzBhB,kBCNc;ACioHhB;;AyBrqHA;E3B4CE,kBCVc;ACuoHhB;;AyBzqHA;E3B8CE,iBCba;AC4oHf;;AyB7qHA;EAkEM,gCAA8C;EAC9C,YAAY;AzB+mHlB;;AyBlrHA;EAqEI,WAAW;AzBinHf;;AyBtrHA;EAuEM,WAAW;AzBmnHjB;;AyB1rHA;EA2EM,aAAa;EACb,kBAAkB;ExB8GpB,cwB7G+B;EAC7B,YAAY;EACZ,eAAe;AzBmnHrB;;AyBlsHA;EAiFM,kB1B7CU;ACkqHhB;;AyBtsHA;EAmFM,kB1BjDU;ACwqHhB;;AyB1sHA;EAqFM,iB1BpDS;AC6qHf;;A0BjsHA;EAEE,oBAAoB;EACpB,aAAa;EACb,2BAA2B;EAC3B,kBAAkB;A1BmsHpB;;A0BxsHA;EAYQ,uB3BZuB;E2BavB,yBAAyB;EACzB,c3B3BqB;AC2tH7B;;A0B9sHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,c3BjCmB;ACiuH7B;;A0BptHA;EAwBU,yBAAyB;EACzB,+C3BzBqB;E2B0BrB,c3BvCmB;ACuuH7B;;A0B1tHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,c3B7CmB;AC6uH7B;;A0BhuHA;EAYQ,yB3BzBqB;E2B0BrB,yBAAyB;EACzB,Y3BduB;ACsuH/B;;A0BtuHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,Y3BpBqB;AC4uH/B;;A0B5uHA;EAwBU,yBAAyB;EACzB,4C3BtCmB;E2BuCnB,Y3B1BqB;ACkvH/B;;A0BlvHA;EA8BU,uBhB+DuB;EgB9DvB,yBAAyB;EACzB,Y3BhCqB;ACwvH/B;;A0BxvHA;EAYQ,4B3BdsB;E2BetB,yBAAyB;EACzB,yBhBmDa;AV6rHrB;;A0B9vHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,yBhB6CW;AVmsHrB;;A0BpwHA;EAwBU,yBAAyB;EACzB,+C3B3BoB;E2B4BpB,yBhBuCW;AVysHrB;;A0B1wHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,yBhBiCW;AV+sHrB;;A0BhxHA;EAYQ,yB3BrBsB;E2BsBtB,yBAAyB;EACzB,WhBqDQ;AVmtHhB;;A0BtxHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVytHhB;;A0B5xHA;EAwBU,yBAAyB;EACzB,4C3BlCoB;E2BmCpB,WhByCM;AV+tHhB;;A0BlyHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVquHhB;;A0BxyHA;EAYQ,yB3BP0B;E2BQ1B,yBAAyB;EACzB,WhBqDQ;AV2uHhB;;A0B9yHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVivHhB;;A0BpzHA;EAwBU,yBAAyB;EACzB,6C3BpBwB;E2BqBxB,WhByCM;AVuvHhB;;A0B1zHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AV6vHhB;;A0Bh0HA;EAYQ,yB3BL0B;E2BM1B,yBAAyB;EACzB,WhBqDQ;AVmwHhB;;A0Bt0HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVywHhB;;A0B50HA;EAwBU,yBAAyB;EACzB,6C3BlBwB;E2BmBxB,WhByCM;AV+wHhB;;A0Bl1HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVqxHhB;;A0Bx1HA;EAYQ,yB3BN0B;E2BO1B,yBAAyB;EACzB,WhBqDQ;AV2xHhB;;A0B91HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AViyHhB;;A0Bp2HA;EAwBU,yBAAyB;EACzB,8C3BnBwB;E2BoBxB,WhByCM;AVuyHhB;;A0B12HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AV6yHhB;;A0Bh3HA;EAYQ,yB3BR0B;E2BS1B,yBAAyB;EACzB,WhBqDQ;AVmzHhB;;A0Bt3HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVyzHhB;;A0B53HA;EAwBU,yBAAyB;EACzB,8C3BrBwB;E2BsBxB,WhByCM;AV+zHhB;;A0Bl4HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVq0HhB;;A0Bx4HA;EAYQ,yB3BT0B;E2BU1B,yBAAyB;EACzB,yBhBmDa;AV60HrB;;A0B94HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,yBhB6CW;AVm1HrB;;A0Bp5HA;EAwBU,yBAAyB;EACzB,+C3BtBwB;E2BuBxB,yBhBuCW;AVy1HrB;;A0B15HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,yBhBiCW;AV+1HrB;;A0Bh6HA;EAYQ,yB3BHyB;E2BIzB,yBAAyB;EACzB,WhBqDQ;AVm2HhB;;A0Bt6HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVy2HhB;;A0B56HA;EAwBU,yBAAyB;EACzB,8C3BhBuB;E2BiBvB,WhByCM;AV+2HhB;;A0Bl7HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVq3HhB;;A0Bx7HA;EAmCI,kB3BZY;ACq6HhB;;A0B57HA;EAqCI,e3BfS;AC06Hb;;A0Bh8HA;EAuCI,kB3BlBY;AC+6HhB;;A0Bp8HA;EA0CQ,eAAe;A1B85HvB;;A0Bx8HA;EA4CI,iB3BxBW;ACw7Hf;;A0B58HA;EA+CQ,eAAe;A1Bi6HvB;;A0Bh9HA;EAmDM,6BAA6B;EAC7B,0BAA0B;A1Bi6HhC;;A0Br9HA;EAsDM,4BAA4B;EAC5B,yBAAyB;A1Bm6H/B;;A0B19HA;EA0DQ,kB3BHI;ACu6HZ;;A0B99HA;EA4DQ,aAAa;A1Bs6HrB;;A0Bl+HA;EA+DM,sBAAsB;A1Bu6H5B;;A0Bt+HA;EAiEM,sBAAsB;EACtB,YAAY;EACZ,gBAAgB;A1By6HtB;;A0B5+HA;EAqEM,uBAAuB;A1B26H7B;;A0Bh/HA;EAuEM,aAAa;EACb,YAAY;A1B66HlB;;A0Br/HA;EA0EQ,eAAe;A1B+6HvB;;A0Bz/HA;EA6EQ,eAAe;A1Bg7HvB;;A0B7/HA;EAgFQ,eAAe;A1Bi7HvB;;A0BjgIA;EAmFQ,eAAe;A1Bk7HvB;;A0BrgIA;EAsFQ,0BAA4C;A1Bm7HpD;;A0BzgIA;EAwFQ,0B3BjCI;E2BkCJ,uBAAuB;A1Bq7H/B;;A0B9gIA;EA2FI,uBAAuB;A1Bu7H3B;;A0BlhIA;EA8FM,WAAW;A1Bw7HjB;;A0BthIA;EAgGM,YAAY;EACZ,eAAe;A1B07HrB;;A0B3hIA;EAmGI,yBAAyB;A1B47H7B;;A0B/hIA;EAqGM,0BAA4C;A1B87HlD;;A0BniIA;EAuGM,0B3BhDM;E2BiDN,2BAA2B;EAC3B,SAAS;A1Bg8Hf;;A0B97HA;EACE,oBAAoB;EACpB,aAAa;EACb,eAAe;EACf,2BAA2B;EAC3B,gBAAgB;EAChB,kBAAkB;A1Bi8HpB;;A0Bv8HA;EASM,yBhBvB2B;EgBwB3B,c3B9HwB;ACgkI9B;;A0B58HA;EAYM,qBhB1B2B;AV89HjC;;A0Bh9HA;EAeM,yBhB7B2B;EgB8B3B,c3BpIwB;ACykI9B;;A0Br9HA;EAkBM,qBhBhC2B;AVu+HjC;;A0Br8HA;EACE,YAAY;EACZ,OAAO;EACP,UAAU;EACV,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,WAAW;A1Bw8Hb;;A0Bt8HA;;EAGE,qB3BhJ4B;E2BiJ5B,kB3BrFU;E2BsFV,cAAc;EACd,iBAAiB;EACjB,kBAAkB;EAClB,mBAAmB;A1Bw8HrB;;A0Bt8HA;EACE,4B3BrJ4B;E2BsJ5B,c3B5J4B;ACqmI9B;;A0Bv8HA;EACE,qB3B5J4B;E2B6J5B,mBA9J4B;EA+J5B,2BA9JoC;EA+JpC,cAAc;EACd,eA/JwB;EAgKxB,gBAAgB;EAChB,mBAAmB;EACnB,uBAAuB;A1B08HzB;;A0Bx8HA;EACE,mBAAmB;EACnB,aAAa;EACb,WAAW;EACX,uBAAuB;EzBCrB,mByBAmC;EACrC,UAAU;A1B28HZ;;A0Bj9HA;EAQI,eAAe;A1B68HnB;;A2B7nIA;EACE,c5BF4B;E4BG5B,cAAc;EACd,e5B2BW;E4B1BX,gB5BiCe;AC+lIjB;;A2BpoIA;EAMI,oBAAoB;A3BkoIxB;;A2BxoIA;EASI,kB5BsBY;AC6mIhB;;A2B5oIA;EAWI,kB5BkBY;ACmnIhB;;A2BhpIA;EAaI,iB5BeW;ACwnIf;;A2BroIA;EACE,cAAc;EACd,kB5Bcc;E4Bbd,mBAAmB;A3BwoIrB;;A2B3oIA;EAOM,Y5BdyB;ACspI/B;;A2B/oIA;EAOM,c5B3BuB;ACuqI7B;;A2BnpIA;EAOM,iB5BhBwB;ACgqI9B;;A2BvpIA;EAOM,c5BvBwB;AC2qI9B;;A2B3pIA;EAOM,c5BT4B;ACiqIlC;;A2B/pIA;EAOM,c5BP4B;ACmqIlC;;A2BnqIA;EAOM,c5BR4B;ACwqIlC;;A2BvqIA;EAOM,c5BV4B;AC8qIlC;;A2B3qIA;EAOM,c5BX4B;ACmrIlC;;A2B/qIA;EAOM,c5BL2B;ACirIjC;;A2BxqIA;EAEI,sBAAsB;A3B0qI1B;;A2B5qIA;EAKI,aAAa;EACb,2BAA2B;A3B2qI/B;;A2BjrIA;E1BmJI,kB0B1IwC;A3B4qI5C;;A2BrrIA;;;EAcU,gBAAgB;A3B6qI1B;;A2B3rIA;;;EAoBY,6BAA6B;EAC7B,0BAA0B;A3B6qItC;;A2BlsIA;;;EA8BY,4BAA4B;EAC5B,yBAAyB;A3B0qIrC;;A2BzsIA;;;;;EAyCY,UAAU;A3BwqItB;;A2BjtIA;;;;;;;;;EA8CY,UAAU;A3B+qItB;;A2B7tIA;;;;;;;;;EAgDc,UAAU;A3ByrIxB;;A2BzuIA;EAkDQ,YAAY;EACZ,cAAc;A3B2rItB;;A2B9uIA;EAqDM,uBAAuB;A3B6rI7B;;A2BlvIA;EAuDM,yBAAyB;A3B+rI/B;;A2BtvIA;EA0DQ,YAAY;EACZ,cAAc;A3BgsItB;;A2B3vIA;EA6DI,aAAa;EACb,2BAA2B;A3BksI/B;;A2BhwIA;EAgEM,cAAc;A3BosIpB;;A2BpwIA;EAkEQ,gBAAgB;E1BiFpB,qB0BhF2C;A3BssI/C;;A2BzwIA;EAqEQ,YAAY;EACZ,cAAc;A3BwsItB;;A2B9wIA;EAwEM,uBAAuB;A3B0sI7B;;A2BlxIA;EA0EM,yBAAyB;A3B4sI/B;;A2BtxIA;EA4EM,eAAe;A3B8sIrB;;A2B1xIA;EAgFU,sBAAsB;A3B8sIhC;;A2B9xIA;EAkFQ,uBAAuB;A3BgtI/B;;A2BlyIA;EAoFQ,gBAAgB;A3BktIxB;;AC7tIE;E0BzEF;IAuFM,aAAa;E3BotIjB;AACF;;A2BntIA;EAEI,kBAAkB;A3BqtItB;;AC3uIE;E0BoBF;IAII,qBAAqB;E3BwtIvB;AACF;;AC7uIE;E0BgBF;IAMI,aAAa;IACb,YAAY;IACZ,cAAc;I1BkDd,oB0BjDsC;IACtC,iBAAiB;E3B4tInB;E2BtuIF;IAYM,kB5BhGU;I4BiGV,oBAAoB;E3B6tIxB;E2B1uIF;IAeM,oBAAoB;E3B8tIxB;E2B7uIF;IAiBM,kB5BvGU;I4BwGV,oBAAoB;E3B+tIxB;E2BjvIF;IAoBM,iB5B3GS;I4B4GT,oBAAoB;E3BguIxB;AACF;;A2B/tIA;EAEI,gBAAgB;A3BiuIpB;;AC1wIE;E0BuCF;IAII,aAAa;IACb,aAAa;IACb,YAAY;IACZ,cAAc;E3BouIhB;E2B3uIF;IASM,gBAAgB;E3BquIpB;E2B9uIF;IAWM,cAAc;E3BsuIlB;E2BjvIF;IAaQ,YAAY;E3BuuIlB;E2BpvIF;I1BmCI,qB0BpB2C;E3BwuI7C;AACF;;A2BvuIA;EACE,sBAAsB;EACtB,WAAW;EACX,e5BhIW;E4BiIX,kBAAkB;EAClB,mBAAmB;A3B0uIrB;;A2B/uIA;;;EAaU,c5BxKoB;ACg5I9B;;A2BrvIA;;;EAeQ,kB5B3IQ;ACu3IhB;;A2B3vIA;;;EAiBQ,kB5B/IQ;AC+3IhB;;A2BjwIA;;;EAmBQ,iB5BlJO;ACs4If;;A2BvwIA;EAqBM,c5B7KwB;E4B8KxB,a7BjLgB;E6BkLhB,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,Y7BrLgB;E6BsLhB,UAAU;A3BsvIhB;;A2BjxIA;;EA+BM,mB7B1LgB;AEi7ItB;;A2BtxIA;EAiCM,OAAO;A3ByvIb;;A2B1xIA;;EAqCM,oB7BhMgB;AE07ItB;;A2B/xIA;EAuCM,QAAQ;A3B4vId;;A2BnyIA;EA2CM,6BAA6B;E1BjB/B,c0BkB+B;EAC7B,YAAY;EACZ,UAAU;A3B4vIhB;;A2B1yIA;EAgDM,kB5B5KU;AC06IhB;;A2B9yIA;EAkDM,kB5BhLU;ACg7IhB;;A2BlzIA;EAoDM,iB5BnLS;ACq7If;;A4Bx9IA,qBAAA;ACWA;EAGE,e9BuBW;E8BtBX,mBAAmB;A7B+8IrB;;A6Bn9IA;EAMI,mBAAmB;EACnB,c9BI8B;E8BH9B,aAAa;EACb,uBAAuB;EACvB,iBAduC;A7B+9I3C;;A6B39IA;EAYM,c9BjBwB;ACo+I9B;;A6B/9IA;EAcI,mBAAmB;EACnB,aAAa;A7Bq9IjB;;A6Bp+IA;E5ByKI,e4BxJoC;A7Bu9IxC;;A6Bx+IA;EAoBQ,c9BzBsB;E8B0BtB,eAAe;EACf,oBAAoB;A7Bw9I5B;;A6B9+IA;EAwBM,c9B1BwB;E8B2BxB,iBAAiB;A7B09IvB;;A6Bn/IA;;EA4BI,uBAAuB;EACvB,aAAa;EACb,eAAe;EACf,2BAA2B;A7B49I/B;;A6B3/IA;E5ByKI,mB4BvIuC;A7B69I3C;;A6B//IA;E5ByKI,kB4BrIuC;A7B+9I3C;;A6BngJA;;EAyCM,uBAAuB;A7B+9I7B;;A6BxgJA;;EA6CM,yBAAyB;A7Bg+I/B;;A6B7gJA;EAgDI,kB9BrBY;ACs/IhB;;A6BjhJA;EAkDI,kB9BzBY;AC4/IhB;;A6BrhJA;EAoDI,iB9B5BW;ACigJf;;A6BzhJA;EAwDM,iBAAiB;A7Bq+IvB;;A6B7hJA;EA2DM,iBAAiB;A7Bs+IvB;;A6BjiJA;EA8DM,iBAAiB;A7Bu+IvB;;A6BriJA;EAiEM,iBAAiB;A7Bw+IvB;;A8B9hJA;EACE,uB/BR6B;E+BS7B,sBAnBmB;EAoBnB,0F/BvB2B;E+BwB3B,c/BnB4B;E+BoB5B,eAAe;EACf,kBAAkB;A9BiiJpB;;A8B9hJE;EACE,+BA3BiB;EA4BjB,gCA5BiB;A9B6jJrB;;A8BhiJE;EACE,kCA9BiB;EA+BjB,mCA/BiB;A9BkkJrB;;A8BjiJA;EAEE,6BAjCwC;EAkCxC,oBAAoB;EACpB,kD/BxC2B;E+ByC3B,aAAa;A9BmiJf;;A8BjiJA;EACE,mBAAmB;EACnB,c/BzC4B;E+B0C5B,aAAa;EACb,YAAY;EACZ,gB/BNe;E+BOf,qBA1CgC;A9B8kJlC;;A8B1iJA;EAQI,uBAAuB;A9BsiJ3B;;A8BpiJA;E7BqBE,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,mBAAmB;EACnB,oBAAoB;EACpB,cAAc;EACd,SAAS;EACT,UAAU;E6B5BV,mBAAmB;EACnB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,qBApDgC;A9BomJlC;;A8B9iJA;EACE,cAAc;EACd,kBAAkB;A9BijJpB;;A8BnjJA;EAKM,+BA/De;EAgEf,gCAhEe;A9BknJrB;;A8BxjJA;EASM,kCAnEe;EAoEf,mCApEe;A9BunJrB;;A8BjjJA;EAEE,6BAhEyC;EAiEzC,eAhE2B;A9BmnJ7B;;A8BjjJA;EAEE,6BAlEwC;EAmExC,6B/BxE6B;E+ByE7B,oBAAoB;EACpB,aAAa;A9BmjJf;;A8BjjJA;EACE,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,uBAAuB;EACvB,gBA5E2B;A9BgoJ7B;;A8B3jJA;E7B6FI,+BFzK2B;AC2oJ/B;;A8BljJA;EAEI,qB/BtDkB;AC0mJtB;;A+BroJA;EACE,oBAAoB;EACpB,kBAAkB;EAClB,mBAAmB;A/BwoJrB;;A+B3oJA;EAOM,cAAc;A/BwoJpB;;A+B/oJA;EAUM,UAAU;EACV,QAAQ;A/ByoJd;;A+BppJA;EAcM,YAAY;EACZ,mBA9BuB;EA+BvB,oBAAoB;EACpB,SAAS;A/B0oJf;;A+BxoJA;EACE,aAAa;E9BmJX,O8BlJqB;EACvB,gBAzC6B;EA0C7B,gBAtC2B;EAuC3B,kBAAkB;EAClB,SAAS;EACT,WApCqB;A/B+qJvB;;A+BzoJA;EACE,uBhCnC6B;EgCoC7B,kBhCmBU;EgClBV,0FhClD2B;EgCmD3B,sBA9CsC;EA+CtC,mBA9CmC;A/B0rJrC;;Ae9qJgB;EgBqCd,chClD4B;EgCmD5B,cAAc;EACd,mBAAmB;EACnB,gBAAgB;EAChB,sBAAsB;EACtB,kBAAkB;A/B6oJpB;;A+B3oJA;;E9BoHI,mB8BlHmC;EACrC,mBAAmB;EACnB,mBAAmB;EACnB,WAAW;A/B8oJb;;A+BnpJA;;EAOI,4BhC1D0B;EgC2D1B,chCtEyB;ACutJ7B;;A+BzpJA;;EAUI,yBhCpD8B;EgCqD9B,WrBOY;AV6oJhB;;A+BlpJA;EACE,yBhCnE6B;EgCoE7B,YAAY;EACZ,cAAc;EACd,WAAW;EACX,gBAAgB;A/BqpJlB;;AgCnuJA;EAEE,mBAAmB;EACnB,8BAA8B;AhCquJhC;;AgCxuJA;EAKI,kBjC6DQ;AC0qJZ;;AgC5uJA;EAOI,qBAAqB;EACrB,mBAAmB;AhCyuJvB;;AgCjvJA;EAWI,aAAa;AhC0uJjB;;AgCrvJA;;EAcM,aAAa;AhC4uJnB;;AgC1vJA;EAgBM,aAAa;AhC8uJnB;;AgC9vJA;EAmBQ,gBAAgB;E/B6JpB,qB+BlLuC;AhCqwJ3C;;AgCnwJA;EAsBQ,YAAY;AhCivJpB;;ACjqJE;E+BtGF;IAyBI,aAAa;EhCmvJf;EgC5wJF;IA4BQ,YAAY;EhCmvJlB;AACF;;AgClvJA;EACE,mBAAmB;EACnB,aAAa;EACb,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,uBAAuB;AhCqvJzB;;AgC3vJA;;EASI,gBAAgB;AhCuvJpB;;AC5rJE;E+BpEF;IAaM,sBA7CqC;EhCqyJzC;AACF;;AgCvvJA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;AhC0vJhB;;AgC9vJA;;EAQM,YAAY;AhC2vJlB;;AC1sJE;E+BzDF;;I/BmII,qB+BlLuC;EhCwzJzC;AACF;;AgC5vJA;EACE,mBAAmB;EACnB,2BAA2B;AhC+vJ7B;;AC1tJE;E+BvCF;IAMM,kBAAkB;EhCgwJtB;AACF;;AC5tJE;E+B3CF;IAQI,aAAa;EhCowJf;AACF;;AgCnwJA;EACE,mBAAmB;EACnB,yBAAyB;AhCswJ3B;;ACvuJE;E+BjCF;IAKI,aAAa;EhCwwJf;AACF;;AiC50JA;EACE,uBAAuB;EACvB,aAAa;EACb,mBAAmB;AjC+0JrB;;AiCl1JA;EAKI,sBAV2B;AjC21J/B;;AiCt1JA;EAOI,8ClCR0B;EkCS1B,aAAa;EACb,oBAb2B;AjCg2J/B;;AiC51JA;;EAYM,qBAfgC;AjCo2JtC;;AiCj2JA;EAcM,mBAhBwB;AjCu2J9B;;AiCr2JA;EAgBQ,kBAlBsB;AjC22J9B;;AiCz2JA;EAkBI,8ClCnB0B;EkCoB1B,gBA1BgB;EA2BhB,iBA3BgB;AjCs3JpB;;AiC/2JA;EAwBM,kBA9BsB;EA+BtB,mBA/BsB;AjC03J5B;;AiCz1JA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;AjC41JhB;;AiC11JA;EhCwII,kBgChLgB;AjCs4JpB;;AiC31JA;EhCqII,iBgChLgB;AjC04JpB;;AiC51JA;EACE,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,mBAAmB;AjC+1JrB;;AC/yJE;EgCpDF;IAQI,gBAAgB;EjCg2JlB;AACF;;AkCv4JA;EACE,enCgBW;AC03Jb;;AkC34JA;EAII,kBnCcY;AC63JhB;;AkC/4JA;EAMI,kBnCUY;ACm4JhB;;AkCn5JA;EAQI,iBnCOW;ACw4Jf;;AkC74JA;EACE,iBArB0B;AlCq6J5B;;AkCj5JA;EAGI,kBnCoCc;EmCnCd,cnC3B0B;EmC4B1B,cAAc;EACd,qBAzBiC;AlC26JrC;;AkCx5JA;EAQM,4BnCzBwB;EmC0BxB,cnCjCwB;ACq7J9B;;AkC75JA;EAYM,yBnCpB4B;EmCqB5B,WxBuCU;AV82JhB;;AkCl6JA;EjCsJI,8BF1K0B;EmCqCxB,cAnC0B;EjCwK5B,oBiCvKkC;AlCy7JtC;;AkCp5JA;EACE,cnC3C4B;EmC4C5B,iBApC2B;EAqC3B,qBApC+B;EAqC/B,yBAAyB;AlCu5J3B;;AkC35JA;EAMI,eAtCoB;AlC+7JxB;;AkC/5JA;EAQI,kBAxCoB;AlCm8JxB;;AmC97JA;EAEE,4BpCZ4B;EoCa5B,kBpC4CU;EoC3CV,epCUW;ACs7Jb;;AmCp8JA;EAMI,mBAAmB;AnCk8JvB;;AmCx8JA;EAQI,mBAAmB;EACnB,0BAA0B;AnCo8J9B;;AmC78JA;EAYI,kBpCGY;ACk8JhB;;AmCj9JA;EAcI,kBpCDY;ACw8JhB;;AmCr9JA;EAgBI,iBpCJW;AC68Jf;;AmCz9JA;EAsCM,uBAH+C;AnC07JrD;;AmC79JA;EAwCQ,uBpChDuB;EoCiDvB,cpC9DqB;ACu/J7B;;AmCl+JA;EA2CQ,mBpCnDuB;AC8+J/B;;AmCt+JA;EAsCM,yBAH+C;AnCu8JrD;;AmC1+JA;EAwCQ,yBpC7DqB;EoC8DrB,YpCjDuB;ACu/J/B;;AmC/+JA;EA2CQ,qBpChEqB;ACwgK7B;;AmCn/JA;EAsCM,yBAH+C;AnCo9JrD;;AmCv/JA;EAwCQ,4BpClDsB;EoCmDtB,yBzBgBa;AVm8JrB;;AmC5/JA;EA2CQ,wBpCrDsB;AC0gK9B;;AmChgKA;EAsCM,yBAH+C;AnCi+JrD;;AmCpgKA;EAwCQ,yBpCzDsB;EoC0DtB,WzBkBQ;AV88JhB;;AmCzgKA;EA2CQ,qBpC5DsB;AC8hK9B;;AmC7gKA;EAsCM,yBzB4B0C;AV+8JhD;;AmCjhKA;EAwCQ,yBpC3C0B;EoC4C1B,WzBkBQ;AV29JhB;;AmCthKA;EA2CQ,qBpC9C0B;EoC+C1B,czB8B6D;AVi9JrE;;AmC3hKA;EAsCM,yBzB4B0C;AV69JhD;;AmC/hKA;EAwCQ,yBpCzC0B;EoC0C1B,WzBkBQ;AVy+JhB;;AmCpiKA;EA2CQ,qBpC5C0B;EoC6C1B,czB8B6D;AV+9JrE;;AmCziKA;EAsCM,yBzB4B0C;AV2+JhD;;AmC7iKA;EAwCQ,yBpC1C0B;EoC2C1B,WzBkBQ;AVu/JhB;;AmCljKA;EA2CQ,qBpC7C0B;EoC8C1B,czB8B6D;AV6+JrE;;AmCvjKA;EAsCM,yBzB4B0C;AVy/JhD;;AmC3jKA;EAwCQ,yBpC5C0B;EoC6C1B,WzBkBQ;AVqgKhB;;AmChkKA;EA2CQ,qBpC/C0B;EoCgD1B,czB8B6D;AV2/JrE;;AmCrkKA;EAsCM,yBzB4B0C;AVugKhD;;AmCzkKA;EAwCQ,yBpC7C0B;EoC8C1B,yBzBgBa;AVqhKrB;;AmC9kKA;EA2CQ,qBpChD0B;EoCiD1B,czB8B6D;AVygKrE;;AmCnlKA;EAsCM,yBzB4B0C;AVqhKhD;;AmCvlKA;EAwCQ,yBpCvCyB;EoCwCzB,WzBkBQ;AViiKhB;;AmC5lKA;EA2CQ,qBpC1CyB;EoC2CzB,czB8B6D;AVuhKrE;;AmCnjKA;EACE,mBAAmB;EACnB,yBpChE4B;EoCiE5B,0BAAgE;EAChE,WzBSc;EyBRd,aAAa;EACb,gBpC/Be;EoCgCf,8BAA8B;EAC9B,iBAAiB;EACjB,mBAtEiC;EAuEjC,kBAAkB;AnCsjKpB;;AmChkKA;EAYI,YAAY;EACZ,cAAc;ElCkGd,mBkCjGsC;AnCwjK1C;;AmCtkKA;EAgBI,eAjEgC;EAkEhC,yBAAyB;EACzB,0BAA0B;AnC0jK9B;;AmCxjKA;EACE,qBpChF4B;EoCiF5B,kBpCrBU;EoCsBV,mBAAmB;EACnB,uBAjFmC;EAkFnC,cpCvF4B;EoCwF5B,qBAjFiC;AnC4oKnC;;AmCjkKA;;EASI,uBpCnF2B;ACgpK/B;;AmCtkKA;EAWI,6BAlFgD;AnCipKpD;;AoCjoKA;EAEE,mBAAmB;EACnB,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EACvB,gBAAgB;EAChB,eAAe;EACf,WAxCU;ApC2qKZ;;AoC3oKA;EAWI,aAAa;ApCooKjB;;AoCloKA;EAEE,wCrC/C2B;ACmrK7B;;AoCloKA;;EAEE,cA9CgC;EA+ChC,+BAA0D;EAC1D,cAAc;EACd,kBAAkB;EAClB,WAAW;ApCqoKb;;ACpmKE;EmCvCF;;IASI,cAAc;IACd,8BAA0D;IAC1D,YAxDuB;EpCgsKzB;AACF;;AoCvoKA;EAEE,gBAAgB;EAChB,YAxD2B;EAyD3B,eAAe;EnCwHb,WmChLoB;EA0DtB,SAzDoB;EA0DpB,WA5D2B;ApCqsK7B;;AoCvoKA;EACE,aAAa;EACb,sBAAsB;EACtB,8BAAgD;EAChD,gBAAgB;EAChB,uBAAuB;ApC0oKzB;;AoCxoKA;;EAEE,mBAAmB;EACnB,4BrCtE4B;EqCuE5B,aAAa;EACb,cAAc;EACd,2BAA2B;EAC3B,aApE4B;EAqE5B,kBAAkB;ApC2oKpB;;AoCzoKA;EACE,gCrCjF4B;EqCkF5B,2BrCrBgB;EqCsBhB,4BrCtBgB;ACkqKlB;;AoC1oKA;EACE,crC1F4B;EqC2F5B,YAAY;EACZ,cAAc;EACd,iBrChEa;EqCiEb,cA7E8B;ApC0tKhC;;AoC3oKA;EACE,8BrChCgB;EqCiChB,+BrCjCgB;EqCkChB,6BrC/F4B;AC6uK9B;;AoCjpKA;EnC8EI,mBmCxEuC;ApC+oK3C;;AoC7oKA;EnC3CE,iCAAiC;EmC6CjC,uBrCjG6B;EqCkG7B,YAAY;EACZ,cAAc;EACd,cAAc;EACd,aAtF4B;ApCsuK9B;;AqC1sKA;EACE,uBtC5C6B;EsC6C7B,mBAvDqB;EAwDrB,kBAAkB;EAClB,WAtDW;ArCmwKb;;AqCjtKA;EASM,uBtCpDyB;EsCqDzB,ctClEuB;AC8wK7B;;AqCttKA;;EAcU,ctCtEmB;ACmxK7B;;AqC3tKA;;;;EAoBY,yB3B8BqB;E2B7BrB,ctC7EiB;AC2xK7B;;AqCnuKA;EAwBY,qBtChFiB;AC+xK7B;;AqCvuKA;EA0BQ,ctClFqB;ACmyK7B;;AC3sKE;EoChCF;;;;IAgCY,ctCxFiB;EC2yK3B;EqCnvKF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,ctC/Fe;ECwzK3B;EqChwKF;;IA0Cc,qBtClGe;EC4zK3B;EqCpwKF;;;IA8CU,yB3BIuB;I2BHvB,ctCvGmB;ECk0K3B;EqC1wKF;IAmDc,uBtC9FiB;IsC+FjB,ctC5Ge;ECs0K3B;AACF;;AqC/wKA;EASM,yBtCjEuB;EsCkEvB,YtCrDyB;AC+zK/B;;AqCpxKA;;EAcU,YtCzDqB;ACo0K/B;;AqCzxKA;;;;EAoBY,uB3B8BqB;E2B7BrB,YtChEmB;AC40K/B;;AqCjyKA;EAwBY,mBtCnEmB;ACg1K/B;;AqCryKA;EA0BQ,YtCrEuB;ACo1K/B;;ACzwKE;EoChCF;;;;IAgCY,YtC3EmB;EC41K7B;EqCjzKF;;;;;;;;;;IAsCc,uB3BYmB;I2BXnB,YtClFiB;ECy2K7B;EqC9zKF;;IA0Cc,mBtCrFiB;EC62K7B;EqCl0KF;;;IA8CU,uB3BIuB;I2BHvB,YtC1FqB;ECm3K7B;EqCx0KF;IAmDc,yBtC3Ge;IsC4Gf,YtC/FiB;ECu3K7B;AACF;;AqC70KA;EASM,4BtCtDwB;EsCuDxB,yB3BYe;AV4zKrB;;AqCl1KA;;EAcU,yB3BQW;AVi0KrB;;AqCv1KA;;;;EAoBY,yB3B8BqB;E2B7BrB,yB3BCS;AVy0KrB;;AqC/1KA;EAwBY,gC3BFS;AV60KrB;;AqCn2KA;EA0BQ,yB3BJa;AVi1KrB;;ACv0KE;EoChCF;;;;IAgCY,yB3BVS;EVy1KnB;EqC/2KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,yB3BjBO;EVs2KnB;EqC53KF;;IA0Cc,gC3BpBO;EV02KnB;EqCh4KF;;;IA8CU,yB3BIuB;I2BHvB,yB3BzBW;EVg3KnB;EqCt4KF;IAmDc,4BtChGgB;IsCiGhB,yB3B9BO;EVo3KnB;AACF;;AqC34KA;EASM,yBtC7DwB;EsC8DxB,W3BcU;AVw3KhB;;AqCh5KA;;EAcU,W3BUM;AV63KhB;;AqCr5KA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVq4KhB;;AqC75KA;EAwBY,kB3BAI;AVy4KhB;;AqCj6KA;EA0BQ,W3BFQ;AV64KhB;;ACr4KE;EoChCF;;;;IAgCY,W3BRI;EVq5Kd;EqC76KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVk6Kd;EqC17KF;;IA0Cc,kB3BlBE;EVs6Kd;EqC97KF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EV46Kd;EqCp8KF;IAmDc,yBtCvGgB;IsCwGhB,W3B5BE;EVg7Kd;AACF;;AqCz8KA;EASM,yBtC/C4B;EsCgD5B,W3BcU;AVs7KhB;;AqC98KA;;EAcU,W3BUM;AV27KhB;;AqCn9KA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVm8KhB;;AqC39KA;EAwBY,kB3BAI;AVu8KhB;;AqC/9KA;EA0BQ,W3BFQ;AV28KhB;;ACn8KE;EoChCF;;;;IAgCY,W3BRI;EVm9Kd;EqC3+KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVg+Kd;EqCx/KF;;IA0Cc,kB3BlBE;EVo+Kd;EqC5/KF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EV0+Kd;EqClgLF;IAmDc,yBtCzFoB;IsC0FpB,W3B5BE;EV8+Kd;AACF;;AqCvgLA;EASM,yBtC7C4B;EsC8C5B,W3BcU;AVo/KhB;;AqC5gLA;;EAcU,W3BUM;AVy/KhB;;AqCjhLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVigLhB;;AqCzhLA;EAwBY,kB3BAI;AVqgLhB;;AqC7hLA;EA0BQ,W3BFQ;AVygLhB;;ACjgLE;EoChCF;;;;IAgCY,W3BRI;EVihLd;EqCziLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV8hLd;EqCtjLF;;IA0Cc,kB3BlBE;EVkiLd;EqC1jLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVwiLd;EqChkLF;IAmDc,yBtCvFoB;IsCwFpB,W3B5BE;EV4iLd;AACF;;AqCrkLA;EASM,yBtC9C4B;EsC+C5B,W3BcU;AVkjLhB;;AqC1kLA;;EAcU,W3BUM;AVujLhB;;AqC/kLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AV+jLhB;;AqCvlLA;EAwBY,kB3BAI;AVmkLhB;;AqC3lLA;EA0BQ,W3BFQ;AVukLhB;;AC/jLE;EoChCF;;;;IAgCY,W3BRI;EV+kLd;EqCvmLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV4lLd;EqCpnLF;;IA0Cc,kB3BlBE;EVgmLd;EqCxnLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVsmLd;EqC9nLF;IAmDc,yBtCxFoB;IsCyFpB,W3B5BE;EV0mLd;AACF;;AqCnoLA;EASM,yBtChD4B;EsCiD5B,W3BcU;AVgnLhB;;AqCxoLA;;EAcU,W3BUM;AVqnLhB;;AqC7oLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AV6nLhB;;AqCrpLA;EAwBY,kB3BAI;AVioLhB;;AqCzpLA;EA0BQ,W3BFQ;AVqoLhB;;AC7nLE;EoChCF;;;;IAgCY,W3BRI;EV6oLd;EqCrqLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV0pLd;EqClrLF;;IA0Cc,kB3BlBE;EV8pLd;EqCtrLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVoqLd;EqC5rLF;IAmDc,yBtC1FoB;IsC2FpB,W3B5BE;EVwqLd;AACF;;AqCjsLA;EASM,yBtCjD4B;EsCkD5B,yB3BYe;AVgrLrB;;AqCtsLA;;EAcU,yB3BQW;AVqrLrB;;AqC3sLA;;;;EAoBY,yB3B8BqB;E2B7BrB,yB3BCS;AV6rLrB;;AqCntLA;EAwBY,gC3BFS;AVisLrB;;AqCvtLA;EA0BQ,yB3BJa;AVqsLrB;;AC3rLE;EoChCF;;;;IAgCY,yB3BVS;EV6sLnB;EqCnuLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,yB3BjBO;EV0tLnB;EqChvLF;;IA0Cc,gC3BpBO;EV8tLnB;EqCpvLF;;;IA8CU,yB3BIuB;I2BHvB,yB3BzBW;EVouLnB;EqC1vLF;IAmDc,yBtC3FoB;IsC4FpB,yB3B9BO;EVwuLnB;AACF;;AqC/vLA;EASM,yBtC3C2B;EsC4C3B,W3BcU;AV4uLhB;;AqCpwLA;;EAcU,W3BUM;AVivLhB;;AqCzwLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVyvLhB;;AqCjxLA;EAwBY,kB3BAI;AV6vLhB;;AqCrxLA;EA0BQ,W3BFQ;AViwLhB;;ACzvLE;EoChCF;;;;IAgCY,W3BRI;EVywLd;EqCjyLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVsxLd;EqC9yLF;;IA0Cc,kB3BlBE;EV0xLd;EqClzLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVgyLd;EqCxzLF;IAmDc,yBtCrFmB;IsCsFnB,W3B5BE;EVoyLd;AACF;;AqC7zLA;EAsDI,oBAAoB;EACpB,aAAa;EACb,mBA7GmB;EA8GnB,WAAW;ArC2wLf;;AqCp0LA;EA2DI,gCtCxG0B;ACq3L9B;;AqCx0LA;EALE,OAAO;EACP,eAAe;EACf,QAAQ;EACR,WA/CiB;ArCg4LnB;;AqC/0LA;EAgEI,SAAS;ArCmxLb;;AqCn1LA;EAkEM,iCtC/GwB;ACo4L9B;;AqCv1LA;EAoEI,MAAM;ArCuxLV;;AqCrxLA;;EAGI,oBA9HmB;ArCq5LvB;;AqC1xLA;;EAKI,uBAhImB;ArC05LvB;;AqCxxLA;;EAEE,oBAAoB;EACpB,aAAa;EACb,cAAc;EACd,mBAvIqB;ArCk6LvB;;AqCzxLA;EAIM,6BAA6B;ArCyxLnC;;AqCvxLA;EpCjFE,iCAAiC;EoCmFjC,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;ArC0xLpB;;AqCxxLA;EAEE,ctCrJ4B;EEoB5B,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,eAAe;EACf,cAAc;EACd,eoC7BqB;EpC8BrB,kBAAkB;EAClB,coC/BqB;EpC+KnB,iBoCtBkC;ArCmyLtC;;AC55LE;EACE,8BAA8B;EAC9B,cAAc;EACd,WAAW;EACX,qBAAqB;EACrB,kBAAkB;EAClB,wBAAwB;EACxB,yBF6BQ;EE5BR,yDAAyD;EACzD,oCFsBa;EErBb,WAAW;AD+5Lf;;AC95LI;EACE,oBAAoB;ADi6L1B;;ACh6LI;EACE,oBAAoB;ADm6L1B;;ACl6LI;EACE,oBAAoB;ADq6L1B;;ACp6LE;EACE,qCAAiC;ADu6LrC;;ACn6LM;EACE,wCAAwC;ADs6LhD;;ACr6LM;EACE,UAAU;ADw6LlB;;ACv6LM;EACE,0CAA0C;AD06LlD;;AqC10LA;EACE,aAAa;ArC60Lf;;AqC30LA;;EAEE,ctC9J4B;EsC+J5B,cAAc;EACd,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;ArC80LpB;;AqCp1LA;;EASM,qBAAqB;EACrB,sBAAsB;ArCg1L5B;;AqC90LA;;EAEE,eAAe;ArCi1LjB;;AqCn1LA;;;;;EAOI,yBtCxK0B;EsCyK1B,ctCjK8B;ACq/LlC;;AqCl1LA;EACE,YAAY;EACZ,cAAc;ArCq1LhB;;AqCv1LA;EAII,mBA7KgC;ArCogMpC;;AqC31LA;EAMI,UAAU;ArCy1Ld;;AqC/1LA;EAQI,YAAY;EACZ,cAAc;ArC21LlB;;AqCp2LA;EAWI,oCAAoC;EACpC,mBAhMmB;EAiMnB,kCAAkC;ArC61LtC;;AqC12LA;EAgBM,6BArLyC;EAsLzC,4BtCpL4B;ACkhMlC;;AqC/2LA;EAmBM,6BArL0C;EAsL1C,4BtCvL4B;EsCwL5B,0BArLuC;EAsLvC,wBArLqC;EAsLrC,ctC1L4B;EsC2L5B,kCAAwE;ArCg2L9E;;AqC91LA;EACE,YAAY;EACZ,cAAc;ArCi2LhB;;AqC/1LA;EpCnCI,oBoCoCoC;ArCk2LxC;;AqCn2LA;EAII,qBtCrM8B;EsCsM9B,oBAAoB;EpChCpB,coCiC6B;ArCm2LjC;;AqCj2LA;EACE,mBAAmB;EACnB,sBAAsB;EACtB,mBAAmB;ArCo2LrB;;AqCv2LA;EAKI,oBAAoB;EACpB,qBAAqB;ArCs2LzB;;AqCp2LA;EACE,4BtC3N4B;EsC4N5B,YAAY;EACZ,aAAa;EACb,WA/LyB;EAgMzB,gBAAgB;ArCu2LlB;;ACr/LE;EoCpCF;IAsLI,cAAc;ErCw2LhB;EqCv2LA;;IAGI,mBAAmB;IACnB,aAAa;ErCw2LjB;EqCv2LA;IAEI,aAAa;ErCw2LjB;EqCh8LF;IA0FI,uBtC3O2B;IsC4O3B,4CtCzPyB;IsC0PzB,iBAAiB;ErCy2LnB;EqC52LA;IAKI,cAAc;ErC02LlB;EqCx2LA;IA3MA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA/CiB;ErCqmMjB;EqC92LA;IAKI,SAAS;ErC42Lb;EqCj3LA;IAOM,4CtCrQqB;ECknM3B;EqCp3LA;IASI,MAAM;ErC82LV;EqCv3LA;IpC7LA,iCAAiC;IoC2M3B,iCAA2C;IAC3C,cAAc;ErC62LpB;EqC52LA;;IAGI,oBA9QiB;ErC2nMrB;EqCh3LA;;IAKI,uBAhRiB;ErC+nMrB;AACF;;AC3iME;EoC8LA;;;;IAIE,oBAAoB;IACpB,aAAa;ErCi3Lf;EqCplMF;IAqOI,mBA1RmB;ErC4oMrB;EqCn3LA;IAGI,kBA1R0B;ErC6oM9B;EqCt3LA;;IAMM,mBAAmB;ErCo3LzB;EqC13LA;;IASM,kBtCjOI;ECslMV;EqC93LA;;;;IAgBQ,wCAAwC;ErCo3LhD;EqCp4LA;IAuBU,wCAAwC;ErCg3LlD;EqCv4LA;IA4BU,4BtC7SkB;IsC8SlB,ctCzTiB;ECuqM3B;EqC34LA;IA+BU,4BtChTkB;IsCiTlB,ctCxSsB;ECupMhC;EqCnhMF;IAsKI,aAAa;ErCg3Lf;EqC7gMF;;IAgKI,mBAAmB;IACnB,aAAa;ErCi3Lf;EqC5/LF;IA8IM,oBAAoB;ErCi3LxB;EqCn3LA;IAKM,oDAAoD;ErCi3L1D;EqCt3LA;IAOM,gCtClUsB;IsCmUtB,0BAAkE;IAClE,gBAAgB;IAChB,YAAY;IACZ,4CtC9UqB;IsC+UrB,SAAS;ErCk3Lf;EqC93LA;IAkBM,cAAc;ErC+2LpB;EqC92LM;IAEE,UAAU;IACV,oBAAoB;IACpB,wBAAwB;ErC+2LhC;EqC3iMF;IA8LI,YAAY;IACZ,cAAc;ErCg3LhB;EqC/2LA;IACE,2BAA2B;IpC7K3B,kBoC8KoC;ErCi3LtC;EqCh3LA;IACE,yBAAyB;IpChLzB,iBoCiLoC;ErCk3LtC;EqCx/LF;IAwII,uBtCxV2B;IsCyV3B,8BtCjSc;IsCkSd,+BtClSc;IsCmSd,6BtChW0B;IsCiW1B,2CtCzWyB;IsC0WzB,aAAa;IACb,mBAAmB;IpCjLnB,OoCkLuB;IACvB,eAAe;IACf,kBAAkB;IAClB,SAAS;IACT,WAjVkB;ErCosMpB;EqCtgMF;IAqJM,sBAAsB;IACtB,mBAAmB;ErCo3LvB;EqCn4LA;IpClLE,mBoCmMuC;ErCq3LzC;EqCt4LA;IAoBM,4BtC7WsB;IsC8WtB,ctCzXqB;EC8uM3B;EqC14LA;IAuBM,4BtChXsB;IsCiXtB,ctCxW0B;EC8tMhC;EqCr3LE;IAEE,kBtC1TY;IsC2TZ,gBAAgB;IAChB,4EtCjYuB;IsCkYvB,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,wBAA8C;IAC9C,2BAA2B;IAC3B,yBtChUM;IsCiUN,uCAAuC;ErCs3L3C;EqC15LA;IAsCI,UAAU;IACV,QAAQ;ErCu3LZ;EqC7hMF;IAwKI,cAAc;ErCw3LhB;EqCv3LA;;IpC5NE,qBoC+NyC;ErCw3L3C;EqC33LA;;IpC5NE,sBoCiOyC;ErC03L3C;EqCx3LA;IAlWA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA/CiB;ErC4wMjB;EqC93LA;IAKI,SAAS;ErC43Lb;EqCj4LA;IAOM,4CtC5ZqB;ECyxM3B;EqCp4LA;IASI,MAAM;ErC83LV;EqC73LA;;IAGI,oBA/ZiB;ErC6xMrB;EqCj4LA;;IAKI,uBAjaiB;ErCiyMrB;EqCr4LA;;IAOI,oBAA4D;ErCk4LhE;EqCz4LA;;IASI,uBAA+D;ErCo4LnE;EqCl4LA;;IAGI,ctC7auB;ECgzM3B;EqCt4LA;;IAKI,6BAla2C;ErCuyM/C;EqCp4LA;IAKM,yBtCzasB;EC2yM5B;AACF;;AqC/3LA;EAEI,iCAA2C;ArCi4L/C;;AsCzxMA;EAEE,evCFW;EuCGX,gBAnC0B;AtC8zM5B;;AsC9xMA;EAMI,kBvCLY;ACiyMhB;;AsClyMA;EAQI,kBvCTY;ACuyMhB;;AsCtyMA;EAUI,iBvCZW;AC4yMf;;AsC1yMA;;EAcM,iBAAiB;EACjB,kBAAkB;EAClB,qBvCmBiB;AC8wMvB;;AsCjzMA;EAkBM,qBvCiBiB;ACkxMvB;;AsCjyMA;;EAEE,mBAAmB;EACnB,aAAa;EACb,uBAAuB;EACvB,kBAAkB;AtCoyMpB;;AsClyMA;;;;EAME,cA9D6B;EA+D7B,uBAAuB;EACvB,eA/D8B;EAgE9B,mBA/DkC;EAgElC,oBA/DmC;EAgEnC,kBAAkB;AtCmyMpB;;AsCjyMA;;;EAGE,qBvCtE4B;EuCuE5B,cvC3E4B;EuC4E5B,gBxC3EoB;AE+2MtB;;AsCzyMA;;;EAOI,qBvC3E0B;EuC4E1B,cvC/E0B;ACu3M9B;;AsChzMA;;;EAUI,qBvCjE8B;AC62MlC;;AsCtzMA;;;EAYI,iDvCvFyB;ACu4M7B;;AsC5zMA;;;;;EAeI,yBvClF0B;EuCmF1B,qBvCnF0B;EuCoF1B,gBAAgB;EAChB,cvCvF0B;EuCwF1B,YAAY;AtCqzMhB;;AsCnzMA;;EAEE,oBAvFkC;EAwFlC,qBAvFmC;EAwFnC,mBAAmB;AtCszMrB;;AsCpzMA;EAEI,yBvCpF8B;EuCqF9B,qBvCrF8B;EuCsF9B,W5B1BY;AVg1MhB;;AsCpzMA;EACE,cvCtG4B;EuCuG5B,oBAAoB;AtCuzMtB;;AsCrzMA;EACE,eAAe;AtCwzMjB;;AsCzzMA;EAGI,gBAAgB;AtC0zMpB;;ACz0ME;EqCjEF;IAoFI,eAAe;EtC2zMjB;EsCl1MF;;IA0BI,YAAY;IACZ,cAAc;EtC4zMhB;EsCv0MF;IAcM,YAAY;IACZ,cAAc;EtC4zMlB;AACF;;ACp1ME;EqCQF;IAmBI,YAAY;IACZ,cAAc;IACd,2BAA2B;IAC3B,QAAQ;EtC8zMV;EsCt4MF;;;;IA6EI,gBAAgB;IAChB,aAAa;EtC+zMf;EsC9zMA;IACE,QAAQ;EtCg0MV;EsC/zMA;IACE,QAAQ;EtCi0MV;EsC96MF;IA+GI,8BAA8B;IAC9B,gBAAgB;IAChB,aAAa;EtCk0Mf;EsCr0MA;IAMM,QAAQ;EtCk0Md;EsCx0MA;IAQM,uBAAuB;IACvB,QAAQ;EtCm0Md;EsC50MA;IAWM,QAAQ;EtCo0Md;EsC/0MA;IAcM,QAAQ;EtCo0Md;EsCl1MA;IAgBM,QAAQ;EtCq0Md;EsCr1MA;IAkBM,yBAAyB;IACzB,QAAQ;EtCs0Md;AACF;;AuC78MA;EACE,kBxCsCgB;EwCrChB,0FxChC2B;EwCiC3B,exCEW;AC88Mb;;AuCn9MA;EAKI,qBxCWkB;ACu8MtB;;AuCv9MA;EAYQ,uBxC7BuB;EwC8BvB,cxC3CqB;AC0/M7B;;AuC59MA;EAeQ,0BxChCuB;ACi/M/B;;AuCh+MA;EAiBQ,YxClCuB;ACq/M/B;;AuCp+MA;EAYQ,yBxC1CqB;EwC2CrB,YxC9BuB;AC0/M/B;;AuCz+MA;EAeQ,4BxC7CqB;AC2gN7B;;AuC7+MA;EAiBQ,cxC/CqB;AC+gN7B;;AuCj/MA;EAYQ,4BxC/BsB;EwCgCtB,yB7BmCa;AVs8MrB;;AuCt/MA;EAeQ,+BxClCsB;AC6gN9B;;AuC1/MA;EAiBQ,iBxCpCsB;ACihN9B;;AuC9/MA;EAYQ,yBxCtCsB;EwCuCtB,W7BqCQ;AVi9MhB;;AuCngNA;EAeQ,4BxCzCsB;ACiiN9B;;AuCvgNA;EAiBQ,cxC3CsB;ACqiN9B;;AuC3gNA;EAYQ,yBxCxB0B;EwCyB1B,W7BqCQ;AV89MhB;;AuChhNA;EAeQ,4BxC3B0B;ACgiNlC;;AuCphNA;EAiBQ,cxC7B0B;ACoiNlC;;AuCxhNA;EAYQ,yBxCtB0B;EwCuB1B,W7BqCQ;AV2+MhB;;AuC7hNA;EAeQ,4BxCzB0B;AC2iNlC;;AuCjiNA;EAiBQ,cxC3B0B;AC+iNlC;;AuCriNA;EAYQ,yBxCvB0B;EwCwB1B,W7BqCQ;AVw/MhB;;AuC1iNA;EAeQ,4BxC1B0B;ACyjNlC;;AuC9iNA;EAiBQ,cxC5B0B;AC6jNlC;;AuCljNA;EAYQ,yBxCzB0B;EwC0B1B,W7BqCQ;AVqgNhB;;AuCvjNA;EAeQ,4BxC5B0B;ACwkNlC;;AuC3jNA;EAiBQ,cxC9B0B;AC4kNlC;;AuC/jNA;EAYQ,yBxC1B0B;EwC2B1B,yB7BmCa;AVohNrB;;AuCpkNA;EAeQ,4BxC7B0B;ACslNlC;;AuCxkNA;EAiBQ,cxC/B0B;AC0lNlC;;AuC5kNA;EAYQ,yBxCpByB;EwCqBzB,W7BqCQ;AV+hNhB;;AuCjlNA;EAeQ,4BxCvByB;AC6lNjC;;AuCrlNA;EAiBQ,cxCzByB;ACimNjC;;AuCtkNA;;EAGI,gCxC3C2B;ACmnN/B;;AuCtkNA;EACE,yBxC9C6B;EwC+C7B,0BAA8C;EAC9C,cxCrD4B;EwCsD5B,iBAhDyB;EAiDzB,gBxCjBe;EwCkBf,iBArD8B;EAsD9B,mBArDgC;AvC8nNlC;;AuCvkNA;EACE,qBAAqB;EACrB,aAAa;EACb,kBArD4B;EAsD5B,uBAAuB;AvC0kNzB;;AuC9kNA;EAMI,gCxC7D0B;EwC8D1B,mBAAmB;EACnB,cAAc;AvC4kNlB;;AuCplNA;EAWM,4BxCrEwB;EwCsExB,cxCvEwB;ACopN9B;;AuC3kNA;EAEI,cxC1E0B;ACupN9B;;AuC/kNA;EAIM,cxC7D4B;AC4oNlC;;AuC7kNA;EACE,mBAAmB;EACnB,cxCjF4B;EwCkF5B,aAAa;EACb,2BAA2B;EAC3B,qBAAqB;AvCglNvB;;AuCrlNA;EtC+FI,oBsCxFsC;AvCklN1C;;AuCzlNA;EASI,YAAY;EACZ,cAAc;EACd,WAAW;AvColNf;;AuC/lNA;EAaI,eAAe;AvCslNnB;;AuCnmNA;EAeI,0BxC9E8B;EwC+E9B,cxC/F0B;ACurN9B;;AuCxmNA;EAkBM,cxCjF4B;AC2qNlC;;AuC5mNA;EAoBI,8BxClCc;EwCmCd,+BxCnCc;AC+nNlB;;AuC1lNA;;EAEE,eAAe;AvC6lNjB;;AuC/lNA;;EAII,4BxCnG0B;ACmsN9B;;AuC9lNA;EtChGE,qBAAqB;EACrB,esCgGgB;EtC/FhB,WsC+FqB;EtC9FrB,gBsC8FqB;EtC7FrB,kBAAkB;EAClB,mBAAmB;EACnB,UsC2FqB;EACrB,cxC5G4B;EE4K1B,oBsC/DoC;AvCumNxC;;AuC1mNA;EAKI,kBAAkB;EAClB,oBAAoB;AvCymNxB;;AwCnsNA;EvCqCE,iCAAiC;EuCjCjC,oBAAoB;EACpB,aAAa;EACb,ezCCW;EyCAX,8BAA8B;EAC9B,gBAAgB;EAChB,gBAAgB;EAChB,mBAAmB;AxCosNrB;;AwC9sNA;EAYI,mBAAmB;EACnB,4BzCjC0B;EyCkC1B,0BAzC4B;EA0C5B,wBAzC0B;EA0C1B,czCvC0B;EyCwC1B,aAAa;EACb,uBAAuB;EACvB,mBAA6C;EAC7C,kBAxCyB;EAyCzB,mBAAmB;AxCssNvB;;AwC3tNA;EAuBM,4BzC/CwB;EyCgDxB,czChDwB;ACwvN9B;;AwChuNA;EA0BI,cAAc;AxC0sNlB;;AwCpuNA;EA6BQ,4BzCrC0B;EyCsC1B,czCtC0B;ACivNlC;;AwCzuNA;EAgCI,mBAAmB;EACnB,4BzCrD0B;EyCsD1B,0BA7D4B;EA8D5B,wBA7D0B;EA8D1B,aAAa;EACb,YAAY;EACZ,cAAc;EACd,2BAA2B;AxC6sN/B;;AwCpvNA;EAyCM,qBAAqB;AxC+sN3B;;AwCxvNA;EA2CM,UAAU;EACV,uBAAuB;EACvB,oBAAoB;EACpB,qBAAqB;AxCitN3B;;AwC/vNA;EAgDM,yBAAyB;EACzB,oBAAoB;AxCmtN1B;;AwCpwNA;EvCsJI,mBuClGuC;AxCotN3C;;AwCxwNA;EvCsJI,kBuChGuC;AxCstN3C;;AwC5wNA;EA0DM,uBAAuB;AxCstN7B;;AwChxNA;EA6DM,yBAAyB;AxCutN/B;;AwCpxNA;EAiEM,6BAA6B;EAE3B,0BAAkE;AxCstN1E;;AwCzxNA;EAuEQ,4BzCxFsB;EyCyFtB,4BzC5FsB;ACkzN9B;;AwC9xNA;EA4EU,uBzC3FqB;EyC4FrB,qBzCjGoB;EyCkGpB,2CAA2E;AxCstNrF;;AwCpyNA;EAiFM,YAAY;EACZ,cAAc;AxCutNpB;;AwCzyNA;EAqFM,qBzCzGwB;EyC0GxB,mBA/F+B;EAgG/B,iBA/F6B;EAgG7B,gBAAgB;EAChB,kBAAkB;AxCwtNxB;;AwCjzNA;EA2FQ,4BzC5GsB;EyC6GtB,qBzCjHsB;EyCkHtB,UAAU;AxC0tNlB;;AwCvzNA;EvCsJI,iBuCtDuE;AxC2tN3E;;AwC3zNA;EAmGU,2BzC3DE;EyC4DF,8BzC5DE;ACwxNZ;;AwCh0NA;EA0GU,4BzClEE;EyCmEF,+BzCnEE;AC6xNZ;;AwCr0NA;EAiHU,yBzCzHwB;EyC0HxB,qBzC1HwB;EyC2HxB,W9B/DM;E8BgEN,UAAU;AxCwtNpB;;AwC50NA;EAsHM,mBAAmB;AxC0tNzB;;AwCh1NA;EA2HY,iCzCjFW;EyCkFX,8BzClFW;EyCmFX,oBAAoB;AxCytNhC;;AwCt1NA;EAoIY,kCzC1FW;EyC2FX,+BzC3FW;EyC4FX,qBAAqB;AxCstNjC;;AwC51NA;EA6II,kBzCrIY;ACw1NhB;;AwCh2NA;EA+II,kBzCzIY;AC81NhB;;AwCp2NA;EAiJI,iBzC5IW;ACm2Nf;;AyCt4NA,eAAA;ACIA;EACE,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAPkB;A1C64NpB;;A0Cr4NE;EACE,UAAU;EACV,YAAY;A1Cw4NhB;;A0Cv4NE;EACE,UAAU;EACV,WAAW;A1C04Nf;;A0Cz4NE;EACE,UAAU;EACV,UAAU;A1C44Nd;;A0C34NE;EACE,UAAU;EACV,eAAe;A1C84NnB;;A0C74NE;EACE,UAAU;EACV,UAAU;A1Cg5Nd;;A0C/4NE;EACE,UAAU;EACV,eAAe;A1Ck5NnB;;A0Cj5NE;EACE,UAAU;EACV,UAAU;A1Co5Nd;;A0Cn5NE;EACE,UAAU;EACV,UAAU;A1Cs5Nd;;A0Cr5NE;EACE,UAAU;EACV,UAAU;A1Cw5Nd;;A0Cv5NE;EACE,UAAU;EACV,UAAU;A1C05Nd;;A0Cz5NE;EACE,UAAU;EACV,UAAU;A1C45Nd;;A0C35NE;EzCyIE,gByCxImC;A1C85NvC;;A0C75NE;EzCuIE,qByCtIwC;A1Cg6N5C;;A0C/5NE;EzCqIE,gByCpImC;A1Ck6NvC;;A0Cj6NE;EzCmIE,qByClIwC;A1Co6N5C;;A0Cn6NE;EzCiIE,gByChImC;A1Cs6NvC;;A0Cr6NE;EzC+HE,gByC9HmC;A1Cw6NvC;;A0Cv6NE;EzC6HE,gByC5HmC;A1C06NvC;;A0Cz6NE;EzC2HE,gByC1HmC;A1C46NvC;;A0C36NE;EzCyHE,gByCxHmC;A1C86NvC;;A0C56NI;EACE,UAAU;EACV,SAAiC;A1C+6NvC;;A0C96NI;EzCmHA,eyClH4D;A1Ci7NhE;;A0Cr7NI;EACE,UAAU;EACV,eAAiC;A1Cw7NvC;;A0Cv7NI;EzCmHA,qByClH4D;A1C07NhE;;A0C97NI;EACE,UAAU;EACV,gBAAiC;A1Ci8NvC;;A0Ch8NI;EzCmHA,sByClH4D;A1Cm8NhE;;A0Cv8NI;EACE,UAAU;EACV,UAAiC;A1C08NvC;;A0Cz8NI;EzCmHA,gByClH4D;A1C48NhE;;A0Ch9NI;EACE,UAAU;EACV,gBAAiC;A1Cm9NvC;;A0Cl9NI;EzCmHA,sByClH4D;A1Cq9NhE;;A0Cz9NI;EACE,UAAU;EACV,gBAAiC;A1C49NvC;;A0C39NI;EzCmHA,sByClH4D;A1C89NhE;;A0Cl+NI;EACE,UAAU;EACV,UAAiC;A1Cq+NvC;;A0Cp+NI;EzCmHA,gByClH4D;A1Cu+NhE;;A0C3+NI;EACE,UAAU;EACV,gBAAiC;A1C8+NvC;;A0C7+NI;EzCmHA,sByClH4D;A1Cg/NhE;;A0Cp/NI;EACE,UAAU;EACV,gBAAiC;A1Cu/NvC;;A0Ct/NI;EzCmHA,sByClH4D;A1Cy/NhE;;A0C7/NI;EACE,UAAU;EACV,UAAiC;A1CggOvC;;A0C//NI;EzCmHA,gByClH4D;A1CkgOhE;;A0CtgOI;EACE,UAAU;EACV,gBAAiC;A1CygOvC;;A0CxgOI;EzCmHA,sByClH4D;A1C2gOhE;;A0C/gOI;EACE,UAAU;EACV,gBAAiC;A1CkhOvC;;A0CjhOI;EzCmHA,sByClH4D;A1CohOhE;;A0CxhOI;EACE,UAAU;EACV,WAAiC;A1C2hOvC;;A0C1hOI;EzCmHA,iByClH4D;A1C6hOhE;;ACz/NE;EyClGF;IAiEM,UAAU;IACV,YAAY;E1C+hOhB;E0CjmOF;IAoEM,UAAU;IACV,WAAW;E1CgiOf;E0CrmOF;IAuEM,UAAU;IACV,UAAU;E1CiiOd;E0CzmOF;IA0EM,UAAU;IACV,eAAe;E1CkiOnB;E0C7mOF;IA6EM,UAAU;IACV,UAAU;E1CmiOd;E0CjnOF;IAgFM,UAAU;IACV,eAAe;E1CoiOnB;E0CrnOF;IAmFM,UAAU;IACV,UAAU;E1CqiOd;E0CznOF;IAsFM,UAAU;IACV,UAAU;E1CsiOd;E0C7nOF;IAyFM,UAAU;IACV,UAAU;E1CuiOd;E0CjoOF;IA4FM,UAAU;IACV,UAAU;E1CwiOd;E0CroOF;IA+FM,UAAU;IACV,UAAU;E1CyiOd;E0CzoOF;IzCgLI,gByC9EqC;E1C0iOvC;E0C5oOF;IzCgLI,qByC5E0C;E1C2iO5C;E0C/oOF;IzCgLI,gByC1EqC;E1C4iOvC;E0ClpOF;IzCgLI,qByCxE0C;E1C6iO5C;E0CrpOF;IzCgLI,gByCtEqC;E1C8iOvC;E0CxpOF;IzCgLI,gByCpEqC;E1C+iOvC;E0C3pOF;IzCgLI,gByClEqC;E1CgjOvC;E0C9pOF;IzCgLI,gByChEqC;E1CijOvC;E0CjqOF;IzCgLI,gByC9DqC;E1CkjOvC;E0CpqOF;IAqHQ,UAAU;IACV,SAAiC;E1CkjOvC;E0CxqOF;IzCgLI,eyCxD8D;E1CmjOhE;E0C3qOF;IAqHQ,UAAU;IACV,eAAiC;E1CyjOvC;E0C/qOF;IzCgLI,qByCxD8D;E1C0jOhE;E0ClrOF;IAqHQ,UAAU;IACV,gBAAiC;E1CgkOvC;E0CtrOF;IzCgLI,sByCxD8D;E1CikOhE;E0CzrOF;IAqHQ,UAAU;IACV,UAAiC;E1CukOvC;E0C7rOF;IzCgLI,gByCxD8D;E1CwkOhE;E0ChsOF;IAqHQ,UAAU;IACV,gBAAiC;E1C8kOvC;E0CpsOF;IzCgLI,sByCxD8D;E1C+kOhE;E0CvsOF;IAqHQ,UAAU;IACV,gBAAiC;E1CqlOvC;E0C3sOF;IzCgLI,sByCxD8D;E1CslOhE;E0C9sOF;IAqHQ,UAAU;IACV,UAAiC;E1C4lOvC;E0CltOF;IzCgLI,gByCxD8D;E1C6lOhE;E0CrtOF;IAqHQ,UAAU;IACV,gBAAiC;E1CmmOvC;E0CztOF;IzCgLI,sByCxD8D;E1ComOhE;E0C5tOF;IAqHQ,UAAU;IACV,gBAAiC;E1C0mOvC;E0ChuOF;IzCgLI,sByCxD8D;E1C2mOhE;E0CnuOF;IAqHQ,UAAU;IACV,UAAiC;E1CinOvC;E0CvuOF;IzCgLI,gByCxD8D;E1CknOhE;E0C1uOF;IAqHQ,UAAU;IACV,gBAAiC;E1CwnOvC;E0C9uOF;IzCgLI,sByCxD8D;E1CynOhE;E0CjvOF;IAqHQ,UAAU;IACV,gBAAiC;E1C+nOvC;E0CrvOF;IzCgLI,sByCxD8D;E1CgoOhE;E0CxvOF;IAqHQ,UAAU;IACV,WAAiC;E1CsoOvC;E0C5vOF;IzCgLI,iByCxD8D;E1CuoOhE;AACF;;AC1pOE;EyCtGF;IA4HM,UAAU;IACV,YAAY;E1CyoOhB;E0CtwOF;IAgIM,UAAU;IACV,WAAW;E1CyoOf;E0C1wOF;IAoIM,UAAU;IACV,UAAU;E1CyoOd;E0C9wOF;IAwIM,UAAU;IACV,eAAe;E1CyoOnB;E0ClxOF;IA4IM,UAAU;IACV,UAAU;E1CyoOd;E0CtxOF;IAgJM,UAAU;IACV,eAAe;E1CyoOnB;E0C1xOF;IAoJM,UAAU;IACV,UAAU;E1CyoOd;E0C9xOF;IAwJM,UAAU;IACV,UAAU;E1CyoOd;E0ClyOF;IA4JM,UAAU;IACV,UAAU;E1CyoOd;E0CtyOF;IAgKM,UAAU;IACV,UAAU;E1CyoOd;E0C1yOF;IAoKM,UAAU;IACV,UAAU;E1CyoOd;E0C9yOF;IzCgLI,gByCRqC;E1CyoOvC;E0CjzOF;IzCgLI,qByCL0C;E1CyoO5C;E0CpzOF;IzCgLI,gByCFqC;E1CyoOvC;E0CvzOF;IzCgLI,qByCC0C;E1CyoO5C;E0C1zOF;IzCgLI,gByCIqC;E1CyoOvC;E0C7zOF;IzCgLI,gByCOqC;E1CyoOvC;E0Ch0OF;IzCgLI,gByCUqC;E1CyoOvC;E0Cn0OF;IzCgLI,gByCaqC;E1CyoOvC;E0Ct0OF;IzCgLI,gByCgBqC;E1CyoOvC;E0Cz0OF;IAoMQ,UAAU;IACV,SAAiC;E1CwoOvC;E0C70OF;IzCgLI,eyCwB8D;E1CwoOhE;E0Ch1OF;IAoMQ,UAAU;IACV,eAAiC;E1C+oOvC;E0Cp1OF;IzCgLI,qByCwB8D;E1C+oOhE;E0Cv1OF;IAoMQ,UAAU;IACV,gBAAiC;E1CspOvC;E0C31OF;IzCgLI,sByCwB8D;E1CspOhE;E0C91OF;IAoMQ,UAAU;IACV,UAAiC;E1C6pOvC;E0Cl2OF;IzCgLI,gByCwB8D;E1C6pOhE;E0Cr2OF;IAoMQ,UAAU;IACV,gBAAiC;E1CoqOvC;E0Cz2OF;IzCgLI,sByCwB8D;E1CoqOhE;E0C52OF;IAoMQ,UAAU;IACV,gBAAiC;E1C2qOvC;E0Ch3OF;IzCgLI,sByCwB8D;E1C2qOhE;E0Cn3OF;IAoMQ,UAAU;IACV,UAAiC;E1CkrOvC;E0Cv3OF;IzCgLI,gByCwB8D;E1CkrOhE;E0C13OF;IAoMQ,UAAU;IACV,gBAAiC;E1CyrOvC;E0C93OF;IzCgLI,sByCwB8D;E1CyrOhE;E0Cj4OF;IAoMQ,UAAU;IACV,gBAAiC;E1CgsOvC;E0Cr4OF;IzCgLI,sByCwB8D;E1CgsOhE;E0Cx4OF;IAoMQ,UAAU;IACV,UAAiC;E1CusOvC;E0C54OF;IzCgLI,gByCwB8D;E1CusOhE;E0C/4OF;IAoMQ,UAAU;IACV,gBAAiC;E1C8sOvC;E0Cn5OF;IzCgLI,sByCwB8D;E1C8sOhE;E0Ct5OF;IAoMQ,UAAU;IACV,gBAAiC;E1CqtOvC;E0C15OF;IzCgLI,sByCwB8D;E1CqtOhE;E0C75OF;IAoMQ,UAAU;IACV,WAAiC;E1C4tOvC;E0Cj6OF;IzCgLI,iByCwB8D;E1C4tOhE;AACF;;ACvzOE;EyC9GF;IA2MM,UAAU;IACV,YAAY;E1C+tOhB;E0C36OF;IA8MM,UAAU;IACV,WAAW;E1CguOf;E0C/6OF;IAiNM,UAAU;IACV,UAAU;E1CiuOd;E0Cn7OF;IAoNM,UAAU;IACV,eAAe;E1CkuOnB;E0Cv7OF;IAuNM,UAAU;IACV,UAAU;E1CmuOd;E0C37OF;IA0NM,UAAU;IACV,eAAe;E1CouOnB;E0C/7OF;IA6NM,UAAU;IACV,UAAU;E1CquOd;E0Cn8OF;IAgOM,UAAU;IACV,UAAU;E1CsuOd;E0Cv8OF;IAmOM,UAAU;IACV,UAAU;E1CuuOd;E0C38OF;IAsOM,UAAU;IACV,UAAU;E1CwuOd;E0C/8OF;IAyOM,UAAU;IACV,UAAU;E1CyuOd;E0Cn9OF;IzCgLI,gByC4DqC;E1C0uOvC;E0Ct9OF;IzCgLI,qByC8D0C;E1C2uO5C;E0Cz9OF;IzCgLI,gByCgEqC;E1C4uOvC;E0C59OF;IzCgLI,qByCkE0C;E1C6uO5C;E0C/9OF;IzCgLI,gByCoEqC;E1C8uOvC;E0Cl+OF;IzCgLI,gByCsEqC;E1C+uOvC;E0Cr+OF;IzCgLI,gByCwEqC;E1CgvOvC;E0Cx+OF;IzCgLI,gByC0EqC;E1CivOvC;E0C3+OF;IzCgLI,gByC4EqC;E1CkvOvC;E0C9+OF;IA+PQ,UAAU;IACV,SAAiC;E1CkvOvC;E0Cl/OF;IzCgLI,eyCkF8D;E1CmvOhE;E0Cr/OF;IA+PQ,UAAU;IACV,eAAiC;E1CyvOvC;E0Cz/OF;IzCgLI,qByCkF8D;E1C0vOhE;E0C5/OF;IA+PQ,UAAU;IACV,gBAAiC;E1CgwOvC;E0ChgPF;IzCgLI,sByCkF8D;E1CiwOhE;E0CngPF;IA+PQ,UAAU;IACV,UAAiC;E1CuwOvC;E0CvgPF;IzCgLI,gByCkF8D;E1CwwOhE;E0C1gPF;IA+PQ,UAAU;IACV,gBAAiC;E1C8wOvC;E0C9gPF;IzCgLI,sByCkF8D;E1C+wOhE;E0CjhPF;IA+PQ,UAAU;IACV,gBAAiC;E1CqxOvC;E0CrhPF;IzCgLI,sByCkF8D;E1CsxOhE;E0CxhPF;IA+PQ,UAAU;IACV,UAAiC;E1C4xOvC;E0C5hPF;IzCgLI,gByCkF8D;E1C6xOhE;E0C/hPF;IA+PQ,UAAU;IACV,gBAAiC;E1CmyOvC;E0CniPF;IzCgLI,sByCkF8D;E1CoyOhE;E0CtiPF;IA+PQ,UAAU;IACV,gBAAiC;E1C0yOvC;E0C1iPF;IzCgLI,sByCkF8D;E1C2yOhE;E0C7iPF;IA+PQ,UAAU;IACV,UAAiC;E1CizOvC;E0CjjPF;IzCgLI,gByCkF8D;E1CkzOhE;E0CpjPF;IA+PQ,UAAU;IACV,gBAAiC;E1CwzOvC;E0CxjPF;IzCgLI,sByCkF8D;E1CyzOhE;E0C3jPF;IA+PQ,UAAU;IACV,gBAAiC;E1C+zOvC;E0C/jPF;IzCgLI,sByCkF8D;E1Cg0OhE;E0ClkPF;IA+PQ,UAAU;IACV,WAAiC;E1Cs0OvC;E0CtkPF;IzCgLI,iByCkF8D;E1Cu0OhE;AACF;;ACx9OE;EyClHF;IAqQM,UAAU;IACV,YAAY;E1C00OhB;E0ChlPF;IAwQM,UAAU;IACV,WAAW;E1C20Of;E0CplPF;IA2QM,UAAU;IACV,UAAU;E1C40Od;E0CxlPF;IA8QM,UAAU;IACV,eAAe;E1C60OnB;E0C5lPF;IAiRM,UAAU;IACV,UAAU;E1C80Od;E0ChmPF;IAoRM,UAAU;IACV,eAAe;E1C+0OnB;E0CpmPF;IAuRM,UAAU;IACV,UAAU;E1Cg1Od;E0CxmPF;IA0RM,UAAU;IACV,UAAU;E1Ci1Od;E0C5mPF;IA6RM,UAAU;IACV,UAAU;E1Ck1Od;E0ChnPF;IAgSM,UAAU;IACV,UAAU;E1Cm1Od;E0CpnPF;IAmSM,UAAU;IACV,UAAU;E1Co1Od;E0CxnPF;IzCgLI,gByCsHqC;E1Cq1OvC;E0C3nPF;IzCgLI,qByCwH0C;E1Cs1O5C;E0C9nPF;IzCgLI,gByC0HqC;E1Cu1OvC;E0CjoPF;IzCgLI,qByC4H0C;E1Cw1O5C;E0CpoPF;IzCgLI,gByC8HqC;E1Cy1OvC;E0CvoPF;IzCgLI,gByCgIqC;E1C01OvC;E0C1oPF;IzCgLI,gByCkIqC;E1C21OvC;E0C7oPF;IzCgLI,gByCoIqC;E1C41OvC;E0ChpPF;IzCgLI,gByCsIqC;E1C61OvC;E0CnpPF;IAyTQ,UAAU;IACV,SAAiC;E1C61OvC;E0CvpPF;IzCgLI,eyC4I8D;E1C81OhE;E0C1pPF;IAyTQ,UAAU;IACV,eAAiC;E1Co2OvC;E0C9pPF;IzCgLI,qByC4I8D;E1Cq2OhE;E0CjqPF;IAyTQ,UAAU;IACV,gBAAiC;E1C22OvC;E0CrqPF;IzCgLI,sByC4I8D;E1C42OhE;E0CxqPF;IAyTQ,UAAU;IACV,UAAiC;E1Ck3OvC;E0C5qPF;IzCgLI,gByC4I8D;E1Cm3OhE;E0C/qPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cy3OvC;E0CnrPF;IzCgLI,sByC4I8D;E1C03OhE;E0CtrPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cg4OvC;E0C1rPF;IzCgLI,sByC4I8D;E1Ci4OhE;E0C7rPF;IAyTQ,UAAU;IACV,UAAiC;E1Cu4OvC;E0CjsPF;IzCgLI,gByC4I8D;E1Cw4OhE;E0CpsPF;IAyTQ,UAAU;IACV,gBAAiC;E1C84OvC;E0CxsPF;IzCgLI,sByC4I8D;E1C+4OhE;E0C3sPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cq5OvC;E0C/sPF;IzCgLI,sByC4I8D;E1Cs5OhE;E0CltPF;IAyTQ,UAAU;IACV,UAAiC;E1C45OvC;E0CttPF;IzCgLI,gByC4I8D;E1C65OhE;E0CztPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cm6OvC;E0C7tPF;IzCgLI,sByC4I8D;E1Co6OhE;E0ChuPF;IAyTQ,UAAU;IACV,gBAAiC;E1C06OvC;E0CpuPF;IzCgLI,sByC4I8D;E1C26OhE;E0CvuPF;IAyTQ,UAAU;IACV,WAAiC;E1Ci7OvC;E0C3uPF;IzCgLI,iByC4I8D;E1Ck7OhE;AACF;;AC9mPI;EyCjIJ;IA+TM,UAAU;IACV,YAAY;E1Cq7OhB;E0CrvPF;IAkUM,UAAU;IACV,WAAW;E1Cs7Of;E0CzvPF;IAqUM,UAAU;IACV,UAAU;E1Cu7Od;E0C7vPF;IAwUM,UAAU;IACV,eAAe;E1Cw7OnB;E0CjwPF;IA2UM,UAAU;IACV,UAAU;E1Cy7Od;E0CrwPF;IA8UM,UAAU;IACV,eAAe;E1C07OnB;E0CzwPF;IAiVM,UAAU;IACV,UAAU;E1C27Od;E0C7wPF;IAoVM,UAAU;IACV,UAAU;E1C47Od;E0CjxPF;IAuVM,UAAU;IACV,UAAU;E1C67Od;E0CrxPF;IA0VM,UAAU;IACV,UAAU;E1C87Od;E0CzxPF;IA6VM,UAAU;IACV,UAAU;E1C+7Od;E0C7xPF;IzCgLI,gByCgLqC;E1Cg8OvC;E0ChyPF;IzCgLI,qByCkL0C;E1Ci8O5C;E0CnyPF;IzCgLI,gByCoLqC;E1Ck8OvC;E0CtyPF;IzCgLI,qByCsL0C;E1Cm8O5C;E0CzyPF;IzCgLI,gByCwLqC;E1Co8OvC;E0C5yPF;IzCgLI,gByC0LqC;E1Cq8OvC;E0C/yPF;IzCgLI,gByC4LqC;E1Cs8OvC;E0ClzPF;IzCgLI,gByC8LqC;E1Cu8OvC;E0CrzPF;IzCgLI,gByCgMqC;E1Cw8OvC;E0CxzPF;IAmXQ,UAAU;IACV,SAAiC;E1Cw8OvC;E0C5zPF;IzCgLI,eyCsM8D;E1Cy8OhE;E0C/zPF;IAmXQ,UAAU;IACV,eAAiC;E1C+8OvC;E0Cn0PF;IzCgLI,qByCsM8D;E1Cg9OhE;E0Ct0PF;IAmXQ,UAAU;IACV,gBAAiC;E1Cs9OvC;E0C10PF;IzCgLI,sByCsM8D;E1Cu9OhE;E0C70PF;IAmXQ,UAAU;IACV,UAAiC;E1C69OvC;E0Cj1PF;IzCgLI,gByCsM8D;E1C89OhE;E0Cp1PF;IAmXQ,UAAU;IACV,gBAAiC;E1Co+OvC;E0Cx1PF;IzCgLI,sByCsM8D;E1Cq+OhE;E0C31PF;IAmXQ,UAAU;IACV,gBAAiC;E1C2+OvC;E0C/1PF;IzCgLI,sByCsM8D;E1C4+OhE;E0Cl2PF;IAmXQ,UAAU;IACV,UAAiC;E1Ck/OvC;E0Ct2PF;IzCgLI,gByCsM8D;E1Cm/OhE;E0Cz2PF;IAmXQ,UAAU;IACV,gBAAiC;E1Cy/OvC;E0C72PF;IzCgLI,sByCsM8D;E1C0/OhE;E0Ch3PF;IAmXQ,UAAU;IACV,gBAAiC;E1CggPvC;E0Cp3PF;IzCgLI,sByCsM8D;E1CigPhE;E0Cv3PF;IAmXQ,UAAU;IACV,UAAiC;E1CugPvC;E0C33PF;IzCgLI,gByCsM8D;E1CwgPhE;E0C93PF;IAmXQ,UAAU;IACV,gBAAiC;E1C8gPvC;E0Cl4PF;IzCgLI,sByCsM8D;E1C+gPhE;E0Cr4PF;IAmXQ,UAAU;IACV,gBAAiC;E1CqhPvC;E0Cz4PF;IzCgLI,sByCsM8D;E1CshPhE;E0C54PF;IAmXQ,UAAU;IACV,WAAiC;E1C4hPvC;E0Ch5PF;IzCgLI,iByCsM8D;E1C6hPhE;AACF;;ACpwPI;EyChJJ;IAyXM,UAAU;IACV,YAAY;E1CgiPhB;E0C15PF;IA4XM,UAAU;IACV,WAAW;E1CiiPf;E0C95PF;IA+XM,UAAU;IACV,UAAU;E1CkiPd;E0Cl6PF;IAkYM,UAAU;IACV,eAAe;E1CmiPnB;E0Ct6PF;IAqYM,UAAU;IACV,UAAU;E1CoiPd;E0C16PF;IAwYM,UAAU;IACV,eAAe;E1CqiPnB;E0C96PF;IA2YM,UAAU;IACV,UAAU;E1CsiPd;E0Cl7PF;IA8YM,UAAU;IACV,UAAU;E1CuiPd;E0Ct7PF;IAiZM,UAAU;IACV,UAAU;E1CwiPd;E0C17PF;IAoZM,UAAU;IACV,UAAU;E1CyiPd;E0C97PF;IAuZM,UAAU;IACV,UAAU;E1C0iPd;E0Cl8PF;IzCgLI,gByC0OqC;E1C2iPvC;E0Cr8PF;IzCgLI,qByC4O0C;E1C4iP5C;E0Cx8PF;IzCgLI,gByC8OqC;E1C6iPvC;E0C38PF;IzCgLI,qByCgP0C;E1C8iP5C;E0C98PF;IzCgLI,gByCkPqC;E1C+iPvC;E0Cj9PF;IzCgLI,gByCoPqC;E1CgjPvC;E0Cp9PF;IzCgLI,gByCsPqC;E1CijPvC;E0Cv9PF;IzCgLI,gByCwPqC;E1CkjPvC;E0C19PF;IzCgLI,gByC0PqC;E1CmjPvC;E0C79PF;IA6aQ,UAAU;IACV,SAAiC;E1CmjPvC;E0Cj+PF;IzCgLI,eyCgQ8D;E1CojPhE;E0Cp+PF;IA6aQ,UAAU;IACV,eAAiC;E1C0jPvC;E0Cx+PF;IzCgLI,qByCgQ8D;E1C2jPhE;E0C3+PF;IA6aQ,UAAU;IACV,gBAAiC;E1CikPvC;E0C/+PF;IzCgLI,sByCgQ8D;E1CkkPhE;E0Cl/PF;IA6aQ,UAAU;IACV,UAAiC;E1CwkPvC;E0Ct/PF;IzCgLI,gByCgQ8D;E1CykPhE;E0Cz/PF;IA6aQ,UAAU;IACV,gBAAiC;E1C+kPvC;E0C7/PF;IzCgLI,sByCgQ8D;E1CglPhE;E0ChgQF;IA6aQ,UAAU;IACV,gBAAiC;E1CslPvC;E0CpgQF;IzCgLI,sByCgQ8D;E1CulPhE;E0CvgQF;IA6aQ,UAAU;IACV,UAAiC;E1C6lPvC;E0C3gQF;IzCgLI,gByCgQ8D;E1C8lPhE;E0C9gQF;IA6aQ,UAAU;IACV,gBAAiC;E1ComPvC;E0ClhQF;IzCgLI,sByCgQ8D;E1CqmPhE;E0CrhQF;IA6aQ,UAAU;IACV,gBAAiC;E1C2mPvC;E0CzhQF;IzCgLI,sByCgQ8D;E1C4mPhE;E0C5hQF;IA6aQ,UAAU;IACV,UAAiC;E1CknPvC;E0ChiQF;IzCgLI,gByCgQ8D;E1CmnPhE;E0CniQF;IA6aQ,UAAU;IACV,gBAAiC;E1CynPvC;E0CviQF;IzCgLI,sByCgQ8D;E1C0nPhE;E0C1iQF;IA6aQ,UAAU;IACV,gBAAiC;E1CgoPvC;E0C9iQF;IzCgLI,sByCgQ8D;E1CioPhE;E0CjjQF;IA6aQ,UAAU;IACV,WAAiC;E1CuoPvC;E0CrjQF;IzCgLI,iByCgQ8D;E1CwoPhE;AACF;;A0CvoPA;EzClQI,qByClLgB;EzCkLhB,sByClLgB;EAublB,oBAvbkB;A1CikQpB;;A0C7oPA;EAKI,uBAzbgB;A1CqkQpB;;A0CjpPA;EAOI,qCAA4C;A1C8oPhD;;A0CrpPA;EAUI,uBAAuB;A1C+oP3B;;A0CzpPA;EzClQI,cyC8QiC;EzC9QjC,eyC+QiC;EACjC,aAAa;A1CipPjB;;A0C/pPA;EAgBM,SAAS;EACT,qBAAqB;A1CmpP3B;;A0CpqPA;EAmBM,qBAAqB;A1CqpP3B;;A0CxqPA;EAqBM,gBAAgB;A1CupPtB;;A0C5qPA;EAuBI,aAAa;A1CypPjB;;A0ChrPA;EAyBI,eAAe;A1C2pPnB;;A0CprPA;EA2BI,mBAAmB;A1C6pPvB;;ACpgQE;EyC4UF;IA+BM,aAAa;E1C8pPjB;AACF;;AC9/PE;EyCgUF;IAmCM,aAAa;E1CgqPjB;AACF;;A0C9pPE;EACE,oBAAY;EzCzSZ,wCyC0S2D;EzC1S3D,yCyC2S2D;A1CiqP/D;;A0CpqPE;EAKI,8BAA8B;EAC9B,+BAA+B;A1CmqPrC;;A0CzqPE;EASM,iBAAY;A1CoqPpB;;ACniQE;EyCsXA;IAYQ,iBAAY;E1CsqPpB;AACF;;ACriQE;EyCkXA;IAeQ,iBAAY;E1CyqPpB;AACF;;ACviQE;EyC8WA;IAkBQ,iBAAY;E1C4qPpB;AACF;;ACziQE;EyC0WA;IAqBQ,iBAAY;E1C+qPpB;AACF;;AC3iQE;EyCsWA;IAwBQ,iBAAY;E1CkrPpB;AACF;;AC5iQI;EyCiWF;IA2BQ,iBAAY;E1CqrPpB;AACF;;ACxiQI;EyCuVF;IA8BQ,iBAAY;E1CwrPpB;AACF;;ACziQI;EyCkVF;IAiCQ,iBAAY;E1C2rPpB;AACF;;ACriQI;EyCwUF;IAoCQ,iBAAY;E1C8rPpB;AACF;;A0CnuPE;EASM,oBAAY;A1C8tPpB;;AC7lQE;EyCsXA;IAYQ,oBAAY;E1CguPpB;AACF;;AC/lQE;EyCkXA;IAeQ,oBAAY;E1CmuPpB;AACF;;ACjmQE;EyC8WA;IAkBQ,oBAAY;E1CsuPpB;AACF;;ACnmQE;EyC0WA;IAqBQ,oBAAY;E1CyuPpB;AACF;;ACrmQE;EyCsWA;IAwBQ,oBAAY;E1C4uPpB;AACF;;ACtmQI;EyCiWF;IA2BQ,oBAAY;E1C+uPpB;AACF;;AClmQI;EyCuVF;IA8BQ,oBAAY;E1CkvPpB;AACF;;ACnmQI;EyCkVF;IAiCQ,oBAAY;E1CqvPpB;AACF;;AC/lQI;EyCwUF;IAoCQ,oBAAY;E1CwvPpB;AACF;;A0C7xPE;EASM,mBAAY;A1CwxPpB;;ACvpQE;EyCsXA;IAYQ,mBAAY;E1C0xPpB;AACF;;ACzpQE;EyCkXA;IAeQ,mBAAY;E1C6xPpB;AACF;;AC3pQE;EyC8WA;IAkBQ,mBAAY;E1CgyPpB;AACF;;AC7pQE;EyC0WA;IAqBQ,mBAAY;E1CmyPpB;AACF;;AC/pQE;EyCsWA;IAwBQ,mBAAY;E1CsyPpB;AACF;;AChqQI;EyCiWF;IA2BQ,mBAAY;E1CyyPpB;AACF;;AC5pQI;EyCuVF;IA8BQ,mBAAY;E1C4yPpB;AACF;;AC7pQI;EyCkVF;IAiCQ,mBAAY;E1C+yPpB;AACF;;ACzpQI;EyCwUF;IAoCQ,mBAAY;E1CkzPpB;AACF;;A0Cv1PE;EASM,oBAAY;A1Ck1PpB;;ACjtQE;EyCsXA;IAYQ,oBAAY;E1Co1PpB;AACF;;ACntQE;EyCkXA;IAeQ,oBAAY;E1Cu1PpB;AACF;;ACrtQE;EyC8WA;IAkBQ,oBAAY;E1C01PpB;AACF;;ACvtQE;EyC0WA;IAqBQ,oBAAY;E1C61PpB;AACF;;ACztQE;EyCsWA;IAwBQ,oBAAY;E1Cg2PpB;AACF;;AC1tQI;EyCiWF;IA2BQ,oBAAY;E1Cm2PpB;AACF;;ACttQI;EyCuVF;IA8BQ,oBAAY;E1Cs2PpB;AACF;;ACvtQI;EyCkVF;IAiCQ,oBAAY;E1Cy2PpB;AACF;;ACntQI;EyCwUF;IAoCQ,oBAAY;E1C42PpB;AACF;;A0Cj5PE;EASM,iBAAY;A1C44PpB;;AC3wQE;EyCsXA;IAYQ,iBAAY;E1C84PpB;AACF;;AC7wQE;EyCkXA;IAeQ,iBAAY;E1Ci5PpB;AACF;;AC/wQE;EyC8WA;IAkBQ,iBAAY;E1Co5PpB;AACF;;ACjxQE;EyC0WA;IAqBQ,iBAAY;E1Cu5PpB;AACF;;ACnxQE;EyCsWA;IAwBQ,iBAAY;E1C05PpB;AACF;;ACpxQI;EyCiWF;IA2BQ,iBAAY;E1C65PpB;AACF;;AChxQI;EyCuVF;IA8BQ,iBAAY;E1Cg6PpB;AACF;;ACjxQI;EyCkVF;IAiCQ,iBAAY;E1Cm6PpB;AACF;;AC7wQI;EyCwUF;IAoCQ,iBAAY;E1Cs6PpB;AACF;;A0C38PE;EASM,oBAAY;A1Cs8PpB;;ACr0QE;EyCsXA;IAYQ,oBAAY;E1Cw8PpB;AACF;;ACv0QE;EyCkXA;IAeQ,oBAAY;E1C28PpB;AACF;;ACz0QE;EyC8WA;IAkBQ,oBAAY;E1C88PpB;AACF;;AC30QE;EyC0WA;IAqBQ,oBAAY;E1Ci9PpB;AACF;;AC70QE;EyCsWA;IAwBQ,oBAAY;E1Co9PpB;AACF;;AC90QI;EyCiWF;IA2BQ,oBAAY;E1Cu9PpB;AACF;;AC10QI;EyCuVF;IA8BQ,oBAAY;E1C09PpB;AACF;;AC30QI;EyCkVF;IAiCQ,oBAAY;E1C69PpB;AACF;;ACv0QI;EyCwUF;IAoCQ,oBAAY;E1Cg+PpB;AACF;;A0CrgQE;EASM,mBAAY;A1CggQpB;;AC/3QE;EyCsXA;IAYQ,mBAAY;E1CkgQpB;AACF;;ACj4QE;EyCkXA;IAeQ,mBAAY;E1CqgQpB;AACF;;ACn4QE;EyC8WA;IAkBQ,mBAAY;E1CwgQpB;AACF;;ACr4QE;EyC0WA;IAqBQ,mBAAY;E1C2gQpB;AACF;;ACv4QE;EyCsWA;IAwBQ,mBAAY;E1C8gQpB;AACF;;ACx4QI;EyCiWF;IA2BQ,mBAAY;E1CihQpB;AACF;;ACp4QI;EyCuVF;IA8BQ,mBAAY;E1CohQpB;AACF;;ACr4QI;EyCkVF;IAiCQ,mBAAY;E1CuhQpB;AACF;;ACj4QI;EyCwUF;IAoCQ,mBAAY;E1C0hQpB;AACF;;A0C/jQE;EASM,oBAAY;A1C0jQpB;;ACz7QE;EyCsXA;IAYQ,oBAAY;E1C4jQpB;AACF;;AC37QE;EyCkXA;IAeQ,oBAAY;E1C+jQpB;AACF;;AC77QE;EyC8WA;IAkBQ,oBAAY;E1CkkQpB;AACF;;AC/7QE;EyC0WA;IAqBQ,oBAAY;E1CqkQpB;AACF;;ACj8QE;EyCsWA;IAwBQ,oBAAY;E1CwkQpB;AACF;;ACl8QI;EyCiWF;IA2BQ,oBAAY;E1C2kQpB;AACF;;AC97QI;EyCuVF;IA8BQ,oBAAY;E1C8kQpB;AACF;;AC/7QI;EyCkVF;IAiCQ,oBAAY;E1CilQpB;AACF;;AC37QI;EyCwUF;IAoCQ,oBAAY;E1ColQpB;AACF;;A0CznQE;EASM,iBAAY;A1ConQpB;;ACn/QE;EyCsXA;IAYQ,iBAAY;E1CsnQpB;AACF;;ACr/QE;EyCkXA;IAeQ,iBAAY;E1CynQpB;AACF;;ACv/QE;EyC8WA;IAkBQ,iBAAY;E1C4nQpB;AACF;;ACz/QE;EyC0WA;IAqBQ,iBAAY;E1C+nQpB;AACF;;AC3/QE;EyCsWA;IAwBQ,iBAAY;E1CkoQpB;AACF;;AC5/QI;EyCiWF;IA2BQ,iBAAY;E1CqoQpB;AACF;;ACx/QI;EyCuVF;IA8BQ,iBAAY;E1CwoQpB;AACF;;ACz/QI;EyCkVF;IAiCQ,iBAAY;E1C2oQpB;AACF;;ACr/QI;EyCwUF;IAoCQ,iBAAY;E1C8oQpB;AACF;;A2C3oRA;EACE,oBAAoB;EACpB,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,+BAAuB;EAAvB,4BAAuB;EAAvB,uBAAuB;A3C8oRzB;;A2CppRA;EASI,qBAA+B;EAC/B,sBAAgC;EAChC,oBAA8B;A3C+oRlC;;A2C1pRA;EAaM,uBAAiC;A3CipRvC;;A2C9pRA;EAeM,sBAjBgB;A3CoqRtB;;A2ClqRA;EAiBI,oBAAoB;A3CqpRxB;;A2CtqRA;EAmBI,gBArBkB;A3C4qRtB;;A2C1qRA;EAqBI,sBAAsB;A3CypR1B;;A2C9qRA;EAuBM,gCAAgC;A3C2pRtC;;AC5kRE;E0CtGF;IA2BM,aAAa;E3C4pRjB;E2CvrRF;IA8BQ,UAAU;IACV,eAA8B;E3C4pRpC;E2C3rRF;IA8BQ,UAAU;IACV,gBAA8B;E3CgqRpC;E2C/rRF;IA8BQ,UAAU;IACV,UAA8B;E3CoqRpC;E2CnsRF;IA8BQ,UAAU;IACV,gBAA8B;E3CwqRpC;E2CvsRF;IA8BQ,UAAU;IACV,gBAA8B;E3C4qRpC;E2C3sRF;IA8BQ,UAAU;IACV,UAA8B;E3CgrRpC;E2C/sRF;IA8BQ,UAAU;IACV,gBAA8B;E3CorRpC;E2CntRF;IA8BQ,UAAU;IACV,gBAA8B;E3CwrRpC;E2CvtRF;IA8BQ,UAAU;IACV,UAA8B;E3C4rRpC;E2C3tRF;IA8BQ,UAAU;IACV,gBAA8B;E3CgsRpC;E2C/tRF;IA8BQ,UAAU;IACV,gBAA8B;E3CosRpC;E2CnuRF;IA8BQ,UAAU;IACV,WAA8B;E3CwsRpC;AACF;;A4C5uRA,kBAAA;ACIE;EACE,uBAAwB;A7C4uR5B;;A6C3uRE;EAGI,yBAA0C;A7C4uRhD;;A6C3uRE;EACE,kCAAmC;A7C8uRvC;;A6CrvRE;EACE,yBAAwB;A7CwvR5B;;A6CvvRE;EAGI,uBAA0C;A7CwvRhD;;A6CvvRE;EACE,oCAAmC;A7C0vRvC;;A6CjwRE;EACE,4BAAwB;A7CowR5B;;A6CnwRE;EAGI,yBAA0C;A7CowRhD;;A6CnwRE;EACE,uCAAmC;A7CswRvC;;A6C7wRE;EACE,yBAAwB;A7CgxR5B;;A6C/wRE;EAGI,yBAA0C;A7CgxRhD;;A6C/wRE;EACE,oCAAmC;A7CkxRvC;;A6CzxRE;EACE,yBAAwB;A7C4xR5B;;A6C3xRE;EAGI,yBAA0C;A7C4xRhD;;A6C3xRE;EACE,oCAAmC;A7C8xRvC;;A6CzxRI;EACE,yBAA8B;A7C4xRpC;;A6C3xRI;EAGI,yBAAgD;A7C4xRxD;;A6C3xRI;EACE,oCAAyC;A7C8xR/C;;A6C5xRI;EACE,yBAA6B;A7C+xRnC;;A6C9xRI;EAGI,yBAAgD;A7C+xRxD;;A6C9xRI;EACE,oCAAwC;A7CiyR9C;;A6C7zRE;EACE,yBAAwB;A7Cg0R5B;;A6C/zRE;EAGI,yBAA0C;A7Cg0RhD;;A6C/zRE;EACE,oCAAmC;A7Ck0RvC;;A6C7zRI;EACE,yBAA8B;A7Cg0RpC;;A6C/zRI;EAGI,yBAAgD;A7Cg0RxD;;A6C/zRI;EACE,oCAAyC;A7Ck0R/C;;A6Ch0RI;EACE,yBAA6B;A7Cm0RnC;;A6Cl0RI;EAGI,yBAAgD;A7Cm0RxD;;A6Cl0RI;EACE,oCAAwC;A7Cq0R9C;;A6Cj2RE;EACE,yBAAwB;A7Co2R5B;;A6Cn2RE;EAGI,yBAA0C;A7Co2RhD;;A6Cn2RE;EACE,oCAAmC;A7Cs2RvC;;A6Cj2RI;EACE,yBAA8B;A7Co2RpC;;A6Cn2RI;EAGI,yBAAgD;A7Co2RxD;;A6Cn2RI;EACE,oCAAyC;A7Cs2R/C;;A6Cp2RI;EACE,yBAA6B;A7Cu2RnC;;A6Ct2RI;EAGI,yBAAgD;A7Cu2RxD;;A6Ct2RI;EACE,oCAAwC;A7Cy2R9C;;A6Cr4RE;EACE,yBAAwB;A7Cw4R5B;;A6Cv4RE;EAGI,yBAA0C;A7Cw4RhD;;A6Cv4RE;EACE,oCAAmC;A7C04RvC;;A6Cr4RI;EACE,yBAA8B;A7Cw4RpC;;A6Cv4RI;EAGI,yBAAgD;A7Cw4RxD;;A6Cv4RI;EACE,oCAAyC;A7C04R/C;;A6Cx4RI;EACE,yBAA6B;A7C24RnC;;A6C14RI;EAGI,yBAAgD;A7C24RxD;;A6C14RI;EACE,oCAAwC;A7C64R9C;;A6Cz6RE;EACE,yBAAwB;A7C46R5B;;A6C36RE;EAGI,yBAA0C;A7C46RhD;;A6C36RE;EACE,oCAAmC;A7C86RvC;;A6Cz6RI;EACE,yBAA8B;A7C46RpC;;A6C36RI;EAGI,yBAAgD;A7C46RxD;;A6C36RI;EACE,oCAAyC;A7C86R/C;;A6C56RI;EACE,yBAA6B;A7C+6RnC;;A6C96RI;EAGI,yBAAgD;A7C+6RxD;;A6C96RI;EACE,oCAAwC;A7Ci7R9C;;A6C78RE;EACE,yBAAwB;A7Cg9R5B;;A6C/8RE;EAGI,yBAA0C;A7Cg9RhD;;A6C/8RE;EACE,oCAAmC;A7Ck9RvC;;A6C78RI;EACE,yBAA8B;A7Cg9RpC;;A6C/8RI;EAGI,yBAAgD;A7Cg9RxD;;A6C/8RI;EACE,oCAAyC;A7Ck9R/C;;A6Ch9RI;EACE,yBAA6B;A7Cm9RnC;;A6Cl9RI;EAGI,yBAAgD;A7Cm9RxD;;A6Cl9RI;EACE,oCAAwC;A7Cq9R9C;;A6Cl9RE;EACE,yBAAwB;A7Cq9R5B;;A6Cp9RE;EACE,oCAAmC;A7Cu9RvC;;A6C19RE;EACE,yBAAwB;A7C69R5B;;A6C59RE;EACE,oCAAmC;A7C+9RvC;;A6Cl+RE;EACE,yBAAwB;A7Cq+R5B;;A6Cp+RE;EACE,oCAAmC;A7Cu+RvC;;A6C1+RE;EACE,yBAAwB;A7C6+R5B;;A6C5+RE;EACE,oCAAmC;A7C++RvC;;A6Cl/RE;EACE,yBAAwB;A7Cq/R5B;;A6Cp/RE;EACE,oCAAmC;A7Cu/RvC;;A6C1/RE;EACE,yBAAwB;A7C6/R5B;;A6C5/RE;EACE,oCAAmC;A7C+/RvC;;A6ClgSE;EACE,yBAAwB;A7CqgS5B;;A6CpgSE;EACE,oCAAmC;A7CugSvC;;A6C1gSE;EACE,4BAAwB;A7C6gS5B;;A6C5gSE;EACE,uCAAmC;A7C+gSvC;;A6ClhSE;EACE,yBAAwB;A7CqhS5B;;A6CphSE;EACE,oCAAmC;A7CuhSvC;;A8C3jSE;EACE,8BAAiC;A9C8jSrC;;A8C/jSE;EACE,sCAAiC;A9CkkSrC;;A8CnkSE;EACE,iCAAiC;A9CskSrC;;A8CvkSE;EACE,yCAAiC;A9C0kSrC;;A8CtkSE;EACE,4BAA4B;A9CykShC;;A8C1kSE;EACE,0BAA4B;A9C6kShC;;A8C9kSE;EACE,kCAA4B;A9CilShC;;A8C7kSE;EACE,sCAAkC;A9CglStC;;A8CjlSE;EACE,oCAAkC;A9ColStC;;A8CrlSE;EACE,kCAAkC;A9CwlStC;;A8CzlSE;EACE,yCAAkC;A9C4lStC;;A8C7lSE;EACE,wCAAkC;A9CgmStC;;A8CjmSE;EACE,wCAAkC;A9ComStC;;A8CrmSE;EACE,iCAAkC;A9CwmStC;;A8CzmSE;EACE,+BAAkC;A9C4mStC;;A8C7mSE;EACE,gCAAkC;A9CgnStC;;A8CjnSE;EACE,iCAAkC;A9ConStC;;A8ChnSE;EACE,oCAAgC;A9CmnSpC;;A8CpnSE;EACE,kCAAgC;A9CunSpC;;A8CxnSE;EACE,gCAAgC;A9C2nSpC;;A8C5nSE;EACE,uCAAgC;A9C+nSpC;;A8ChoSE;EACE,sCAAgC;A9CmoSpC;;A8CpoSE;EACE,sCAAgC;A9CuoSpC;;A8CxoSE;EACE,iCAAgC;A9C2oSpC;;A8C5oSE;EACE,+BAAgC;A9C+oSpC;;A8ChpSE;EACE,6BAAgC;A9CmpSpC;;A8CppSE;EACE,kCAAgC;A9CupSpC;;A8CnpSE;EACE,+BAA8B;A9CspSlC;;A8CvpSE;EACE,kCAA8B;A9C0pSlC;;A8C3pSE;EACE,gCAA8B;A9C8pSlC;;A8C/pSE;EACE,8BAA8B;A9CkqSlC;;A8CnqSE;EACE,gCAA8B;A9CsqSlC;;A8CvqSE;EACE,6BAA8B;A9C0qSlC;;A8C3qSE;EACE,2BAA8B;A9C8qSlC;;A8C/qSE;EACE,kCAA8B;A9CkrSlC;;A8CnrSE;EACE,gCAA8B;A9CsrSlC;;A8ClrSE;EACE,2BAA6B;A9CqrSjC;;A8CtrSE;EACE,iCAA6B;A9CyrSjC;;A8C1rSE;EACE,+BAA6B;A9C6rSjC;;A8C9rSE;EACE,6BAA6B;A9CisSjC;;A8ClsSE;EACE,+BAA6B;A9CqsSjC;;A8CtsSE;EACE,8BAA6B;A9CysSjC;;A8CpsSI;EACE,uBAAqC;A9CusS3C;;A8CxsSI;EACE,uBAAqC;A9C2sS3C;;A8C5sSI;EACE,uBAAqC;A9C+sS3C;;A8ChtSI;EACE,uBAAqC;A9CmtS3C;;A8CptSI;EACE,uBAAqC;A9CutS3C;;A8CxtSI;EACE,uBAAqC;A9C2tS3C;;A8C5tSI;EACE,yBAAqC;A9C+tS3C;;A8ChuSI;EACE,yBAAqC;A9CmuS3C;;A8CpuSI;EACE,yBAAqC;A9CuuS3C;;A8CxuSI;EACE,yBAAqC;A9C2uS3C;;A8C5uSI;EACE,yBAAqC;A9C+uS3C;;A8ChvSI;EACE,yBAAqC;A9CmvS3C;;AClxSE;EACE,WAAW;EACX,YAAY;EACZ,cAAc;ADqxSlB;;A+CtxSA;EACE,sBAAsB;A/CyxSxB;;A+CvxSA;EACE,uBAAuB;A/C0xSzB;;AgDjySA;EACE,2BAA2B;AhDoyS7B;;AgDlySA;EACE,2BAA2B;AhDqyS7B;;AgDnySA;EACE,0BAA0B;EAC1B,8BAA8B;AhDsyShC;;AiDhzSA;EACE,2BAA2B;AjDmzS7B;;AkD/ySA;EACE,6BAA6B;AlDkzS/B;;AmDxzSA;EACE,oBAAoB;AnD2zStB;;AmDzzSA;EACE,qBAAqB;AnD4zSvB;;AmDjzSI;EACE,oBAA+B;AnDozSrC;;AmDjzSM;EACE,wBAA8C;AnDozStD;;AmDrzSM;EACE,0BAA8C;AnDwzStD;;AmDzzSM;EACE,2BAA8C;AnD4zStD;;AmD7zSM;EACE,yBAA8C;AnDg0StD;;AmD7zSM;EACE,yBAAyC;EACzC,0BAA2C;AnDg0SnD;;AmD7zSM;EACE,wBAAuC;EACvC,2BAA6C;AnDg0SrD;;AmD/0SI;EACE,0BAA+B;AnDk1SrC;;AmD/0SM;EACE,8BAA8C;AnDk1StD;;AmDn1SM;EACE,gCAA8C;AnDs1StD;;AmDv1SM;EACE,iCAA8C;AnD01StD;;AmD31SM;EACE,+BAA8C;AnD81StD;;AmD31SM;EACE,+BAAyC;EACzC,gCAA2C;AnD81SnD;;AmD31SM;EACE,8BAAuC;EACvC,iCAA6C;AnD81SrD;;AmD72SI;EACE,yBAA+B;AnDg3SrC;;AmD72SM;EACE,6BAA8C;AnDg3StD;;AmDj3SM;EACE,+BAA8C;AnDo3StD;;AmDr3SM;EACE,gCAA8C;AnDw3StD;;AmDz3SM;EACE,8BAA8C;AnD43StD;;AmDz3SM;EACE,8BAAyC;EACzC,+BAA2C;AnD43SnD;;AmDz3SM;EACE,6BAAuC;EACvC,gCAA6C;AnD43SrD;;AmD34SI;EACE,0BAA+B;AnD84SrC;;AmD34SM;EACE,8BAA8C;AnD84StD;;AmD/4SM;EACE,gCAA8C;AnDk5StD;;AmDn5SM;EACE,iCAA8C;AnDs5StD;;AmDv5SM;EACE,+BAA8C;AnD05StD;;AmDv5SM;EACE,+BAAyC;EACzC,gCAA2C;AnD05SnD;;AmDv5SM;EACE,8BAAuC;EACvC,iCAA6C;AnD05SrD;;AmDz6SI;EACE,uBAA+B;AnD46SrC;;AmDz6SM;EACE,2BAA8C;AnD46StD;;AmD76SM;EACE,6BAA8C;AnDg7StD;;AmDj7SM;EACE,8BAA8C;AnDo7StD;;AmDr7SM;EACE,4BAA8C;AnDw7StD;;AmDr7SM;EACE,4BAAyC;EACzC,6BAA2C;AnDw7SnD;;AmDr7SM;EACE,2BAAuC;EACvC,8BAA6C;AnDw7SrD;;AmDv8SI;EACE,yBAA+B;AnD08SrC;;AmDv8SM;EACE,6BAA8C;AnD08StD;;AmD38SM;EACE,+BAA8C;AnD88StD;;AmD/8SM;EACE,gCAA8C;AnDk9StD;;AmDn9SM;EACE,8BAA8C;AnDs9StD;;AmDn9SM;EACE,8BAAyC;EACzC,+BAA2C;AnDs9SnD;;AmDn9SM;EACE,6BAAuC;EACvC,gCAA6C;AnDs9SrD;;AmDr+SI;EACE,uBAA+B;AnDw+SrC;;AmDr+SM;EACE,2BAA8C;AnDw+StD;;AmDz+SM;EACE,6BAA8C;AnD4+StD;;AmD7+SM;EACE,8BAA8C;AnDg/StD;;AmDj/SM;EACE,4BAA8C;AnDo/StD;;AmDj/SM;EACE,4BAAyC;EACzC,6BAA2C;AnDo/SnD;;AmDj/SM;EACE,2BAAuC;EACvC,8BAA6C;AnDo/SrD;;AmDngTI;EACE,uBAA+B;AnDsgTrC;;AmDngTM;EACE,2BAA8C;AnDsgTtD;;AmDvgTM;EACE,6BAA8C;AnD0gTtD;;AmD3gTM;EACE,8BAA8C;AnD8gTtD;;AmD/gTM;EACE,4BAA8C;AnDkhTtD;;AmD/gTM;EACE,4BAAyC;EACzC,6BAA2C;AnDkhTnD;;AmD/gTM;EACE,2BAAuC;EACvC,8BAA6C;AnDkhTrD;;AmDjiTI;EACE,qBAA+B;AnDoiTrC;;AmDjiTM;EACE,yBAA8C;AnDoiTtD;;AmDriTM;EACE,2BAA8C;AnDwiTtD;;AmDziTM;EACE,4BAA8C;AnD4iTtD;;AmD7iTM;EACE,0BAA8C;AnDgjTtD;;AmD7iTM;EACE,0BAAyC;EACzC,2BAA2C;AnDgjTnD;;AmD7iTM;EACE,yBAAuC;EACvC,4BAA6C;AnDgjTrD;;AmD/jTI;EACE,2BAA+B;AnDkkTrC;;AmD/jTM;EACE,+BAA8C;AnDkkTtD;;AmDnkTM;EACE,iCAA8C;AnDskTtD;;AmDvkTM;EACE,kCAA8C;AnD0kTtD;;AmD3kTM;EACE,gCAA8C;AnD8kTtD;;AmD3kTM;EACE,gCAAyC;EACzC,iCAA2C;AnD8kTnD;;AmD3kTM;EACE,+BAAuC;EACvC,kCAA6C;AnD8kTrD;;AmD7lTI;EACE,0BAA+B;AnDgmTrC;;AmD7lTM;EACE,8BAA8C;AnDgmTtD;;AmDjmTM;EACE,gCAA8C;AnDomTtD;;AmDrmTM;EACE,iCAA8C;AnDwmTtD;;AmDzmTM;EACE,+BAA8C;AnD4mTtD;;AmDzmTM;EACE,+BAAyC;EACzC,gCAA2C;AnD4mTnD;;AmDzmTM;EACE,8BAAuC;EACvC,iCAA6C;AnD4mTrD;;AmD3nTI;EACE,2BAA+B;AnD8nTrC;;AmD3nTM;EACE,+BAA8C;AnD8nTtD;;AmD/nTM;EACE,iCAA8C;AnDkoTtD;;AmDnoTM;EACE,kCAA8C;AnDsoTtD;;AmDvoTM;EACE,gCAA8C;AnD0oTtD;;AmDvoTM;EACE,gCAAyC;EACzC,iCAA2C;AnD0oTnD;;AmDvoTM;EACE,+BAAuC;EACvC,kCAA6C;AnD0oTrD;;AmDzpTI;EACE,wBAA+B;AnD4pTrC;;AmDzpTM;EACE,4BAA8C;AnD4pTtD;;AmD7pTM;EACE,8BAA8C;AnDgqTtD;;AmDjqTM;EACE,+BAA8C;AnDoqTtD;;AmDrqTM;EACE,6BAA8C;AnDwqTtD;;AmDrqTM;EACE,6BAAyC;EACzC,8BAA2C;AnDwqTnD;;AmDrqTM;EACE,4BAAuC;EACvC,+BAA6C;AnDwqTrD;;AmDvrTI;EACE,0BAA+B;AnD0rTrC;;AmDvrTM;EACE,8BAA8C;AnD0rTtD;;AmD3rTM;EACE,gCAA8C;AnD8rTtD;;AmD/rTM;EACE,iCAA8C;AnDksTtD;;AmDnsTM;EACE,+BAA8C;AnDssTtD;;AmDnsTM;EACE,+BAAyC;EACzC,gCAA2C;AnDssTnD;;AmDnsTM;EACE,8BAAuC;EACvC,iCAA6C;AnDssTrD;;AmDrtTI;EACE,wBAA+B;AnDwtTrC;;AmDrtTM;EACE,4BAA8C;AnDwtTtD;;AmDztTM;EACE,8BAA8C;AnD4tTtD;;AmD7tTM;EACE,+BAA8C;AnDguTtD;;AmDjuTM;EACE,6BAA8C;AnDouTtD;;AmDjuTM;EACE,6BAAyC;EACzC,8BAA2C;AnDouTnD;;AmDjuTM;EACE,4BAAuC;EACvC,+BAA6C;AnDouTrD;;AmDnvTI;EACE,wBAA+B;AnDsvTrC;;AmDnvTM;EACE,4BAA8C;AnDsvTtD;;AmDvvTM;EACE,8BAA8C;AnD0vTtD;;AmD3vTM;EACE,+BAA8C;AnD8vTtD;;AmD/vTM;EACE,6BAA8C;AnDkwTtD;;AmD/vTM;EACE,6BAAyC;EACzC,8BAA2C;AnDkwTnD;;AmD/vTM;EACE,4BAAuC;EACvC,+BAA6C;AnDkwTrD;;AoD3xTI;EACE,0BAA2B;ApD8xTjC;;AoD/xTI;EACE,4BAA2B;ApDkyTjC;;AoDnyTI;EACE,0BAA2B;ApDsyTjC;;AoDvyTI;EACE,4BAA2B;ApD0yTjC;;AoD3yTI;EACE,6BAA2B;ApD8yTjC;;AoD/yTI;EACE,0BAA2B;ApDkzTjC;;AoDnzTI;EACE,6BAA2B;ApDszTjC;;ACttTE;EmDjGE;IACE,0BAA2B;EpD2zT/B;EoD5zTE;IACE,4BAA2B;EpD8zT/B;EoD/zTE;IACE,0BAA2B;EpDi0T/B;EoDl0TE;IACE,4BAA2B;EpDo0T/B;EoDr0TE;IACE,6BAA2B;EpDu0T/B;EoDx0TE;IACE,0BAA2B;EpD00T/B;EoD30TE;IACE,6BAA2B;EpD60T/B;AACF;;AC1uTE;EmDrGE;IACE,0BAA2B;EpDm1T/B;EoDp1TE;IACE,4BAA2B;EpDs1T/B;EoDv1TE;IACE,0BAA2B;EpDy1T/B;EoD11TE;IACE,4BAA2B;EpD41T/B;EoD71TE;IACE,6BAA2B;EpD+1T/B;EoDh2TE;IACE,0BAA2B;EpDk2T/B;EoDn2TE;IACE,6BAA2B;EpDq2T/B;AACF;;AC1vTE;EmD7GE;IACE,0BAA2B;EpD22T/B;EoD52TE;IACE,4BAA2B;EpD82T/B;EoD/2TE;IACE,0BAA2B;EpDi3T/B;EoDl3TE;IACE,4BAA2B;EpDo3T/B;EoDr3TE;IACE,6BAA2B;EpDu3T/B;EoDx3TE;IACE,0BAA2B;EpD03T/B;EoD33TE;IACE,6BAA2B;EpD63T/B;AACF;;AC9wTE;EmDjHE;IACE,0BAA2B;EpDm4T/B;EoDp4TE;IACE,4BAA2B;EpDs4T/B;EoDv4TE;IACE,0BAA2B;EpDy4T/B;EoD14TE;IACE,4BAA2B;EpD44T/B;EoD74TE;IACE,6BAA2B;EpD+4T/B;EoDh5TE;IACE,0BAA2B;EpDk5T/B;EoDn5TE;IACE,6BAA2B;EpDq5T/B;AACF;;ACvxTI;EmDhIA;IACE,0BAA2B;EpD25T/B;EoD55TE;IACE,4BAA2B;EpD85T/B;EoD/5TE;IACE,0BAA2B;EpDi6T/B;EoDl6TE;IACE,4BAA2B;EpDo6T/B;EoDr6TE;IACE,6BAA2B;EpDu6T/B;EoDx6TE;IACE,0BAA2B;EpD06T/B;EoD36TE;IACE,6BAA2B;EpD66T/B;AACF;;AChyTI;EmD/IA;IACE,0BAA2B;EpDm7T/B;EoDp7TE;IACE,4BAA2B;EpDs7T/B;EoDv7TE;IACE,0BAA2B;EpDy7T/B;EoD17TE;IACE,4BAA2B;EpD47T/B;EoD77TE;IACE,6BAA2B;EpD+7T/B;EoDh8TE;IACE,0BAA2B;EpDk8T/B;EoDn8TE;IACE,6BAA2B;EpDq8T/B;AACF;;AoD76TE;EACE,6BAAqC;ApDg7TzC;;AoDj7TE;EACE,8BAAqC;ApDo7TzC;;AoDr7TE;EACE,2BAAqC;ApDw7TzC;;AoDz7TE;EACE,4BAAqC;ApD47TzC;;ACt3TE;EmDlEE;IACE,6BAAqC;EpD47TzC;AACF;;ACx3TE;EmDnEE;IACE,6BAAqC;EpD+7TzC;AACF;;AC13TE;EmDpEE;IACE,6BAAqC;EpDk8TzC;AACF;;AC53TE;EmDrEE;IACE,6BAAqC;EpDq8TzC;AACF;;AC93TE;EmDtEE;IACE,6BAAqC;EpDw8TzC;AACF;;AC/3TI;EmDxEA;IACE,6BAAqC;EpD28TzC;AACF;;AC33TI;EmD/EA;IACE,6BAAqC;EpD88TzC;AACF;;AC53TI;EmDjFA;IACE,6BAAqC;EpDi9TzC;AACF;;ACx3TI;EmDxFA;IACE,6BAAqC;EpDo9TzC;AACF;;AC56TE;EmDlEE;IACE,8BAAqC;EpDk/TzC;AACF;;AC96TE;EmDnEE;IACE,8BAAqC;EpDq/TzC;AACF;;ACh7TE;EmDpEE;IACE,8BAAqC;EpDw/TzC;AACF;;ACl7TE;EmDrEE;IACE,8BAAqC;EpD2/TzC;AACF;;ACp7TE;EmDtEE;IACE,8BAAqC;EpD8/TzC;AACF;;ACr7TI;EmDxEA;IACE,8BAAqC;EpDigUzC;AACF;;ACj7TI;EmD/EA;IACE,8BAAqC;EpDogUzC;AACF;;ACl7TI;EmDjFA;IACE,8BAAqC;EpDugUzC;AACF;;AC96TI;EmDxFA;IACE,8BAAqC;EpD0gUzC;AACF;;ACl+TE;EmDlEE;IACE,2BAAqC;EpDwiUzC;AACF;;ACp+TE;EmDnEE;IACE,2BAAqC;EpD2iUzC;AACF;;ACt+TE;EmDpEE;IACE,2BAAqC;EpD8iUzC;AACF;;ACx+TE;EmDrEE;IACE,2BAAqC;EpDijUzC;AACF;;AC1+TE;EmDtEE;IACE,2BAAqC;EpDojUzC;AACF;;AC3+TI;EmDxEA;IACE,2BAAqC;EpDujUzC;AACF;;ACv+TI;EmD/EA;IACE,2BAAqC;EpD0jUzC;AACF;;ACx+TI;EmDjFA;IACE,2BAAqC;EpD6jUzC;AACF;;ACp+TI;EmDxFA;IACE,2BAAqC;EpDgkUzC;AACF;;ACxhUE;EmDlEE;IACE,4BAAqC;EpD8lUzC;AACF;;AC1hUE;EmDnEE;IACE,4BAAqC;EpDimUzC;AACF;;AC5hUE;EmDpEE;IACE,4BAAqC;EpDomUzC;AACF;;AC9hUE;EmDrEE;IACE,4BAAqC;EpDumUzC;AACF;;AChiUE;EmDtEE;IACE,4BAAqC;EpD0mUzC;AACF;;ACjiUI;EmDxEA;IACE,4BAAqC;EpD6mUzC;AACF;;AC7hUI;EmD/EA;IACE,4BAAqC;EpDgnUzC;AACF;;AC9hUI;EmDjFA;IACE,4BAAqC;EpDmnUzC;AACF;;AC1hUI;EmDxFA;IACE,4BAAqC;EpDsnUzC;AACF;;AoDrnUA;EACE,qCAAqC;ApDwnUvC;;AoDtnUA;EACE,oCAAoC;ApDynUtC;;AoDvnUA;EACE,oCAAoC;ApD0nUtC;;AoDxnUA;EACE,6BAA6B;ApD2nU/B;;AoDznUA;EACE,qCAAqC;ApD4nUvC;;AoD1nUA;EACE,2BAAqC;ApD6nUvC;;AoD5nUA;EACE,2BAAsC;ApD+nUxC;;AoD9nUA;EACE,2BAAsC;ApDioUxC;;AoDhoUA;EACE,2BAAwC;ApDmoU1C;;AoDloUA;EACE,2BAAoC;ApDqoUtC;;AoDnoUA;EACE,+LAAuC;ApDsoUzC;;AoDpoUA;EACE,+LAAyC;ApDuoU3C;;AoDroUA;EACE,+LAA0C;ApDwoU5C;;AoDtoUA;EACE,iCAAyC;ApDyoU3C;;AoDvoUA;EACE,iCAAoC;ApD0oUtC;;AqD3uUE;EACE,yBAA+B;ArD8uUnC;;AC9oUE;EoD9FE;IACE,yBAA+B;ErDgvUnC;AACF;;AChpUE;EoD/FE;IACE,yBAA+B;ErDmvUnC;AACF;;AClpUE;EoDhGE;IACE,yBAA+B;ErDsvUnC;AACF;;ACppUE;EoDjGE;IACE,yBAA+B;ErDyvUnC;AACF;;ACtpUE;EoDlGE;IACE,yBAA+B;ErD4vUnC;AACF;;ACvpUI;EoDpGA;IACE,yBAA+B;ErD+vUnC;AACF;;ACnpUI;EoD3GA;IACE,yBAA+B;ErDkwUnC;AACF;;ACppUI;EoD7GA;IACE,yBAA+B;ErDqwUnC;AACF;;AChpUI;EoDpHA;IACE,yBAA+B;ErDwwUnC;AACF;;AqDryUE;EACE,wBAA+B;ArDwyUnC;;ACxsUE;EoD9FE;IACE,wBAA+B;ErD0yUnC;AACF;;AC1sUE;EoD/FE;IACE,wBAA+B;ErD6yUnC;AACF;;AC5sUE;EoDhGE;IACE,wBAA+B;ErDgzUnC;AACF;;AC9sUE;EoDjGE;IACE,wBAA+B;ErDmzUnC;AACF;;AChtUE;EoDlGE;IACE,wBAA+B;ErDszUnC;AACF;;ACjtUI;EoDpGA;IACE,wBAA+B;ErDyzUnC;AACF;;AC7sUI;EoD3GA;IACE,wBAA+B;ErD4zUnC;AACF;;AC9sUI;EoD7GA;IACE,wBAA+B;ErD+zUnC;AACF;;AC1sUI;EoDpHA;IACE,wBAA+B;ErDk0UnC;AACF;;AqD/1UE;EACE,0BAA+B;ArDk2UnC;;AClwUE;EoD9FE;IACE,0BAA+B;ErDo2UnC;AACF;;ACpwUE;EoD/FE;IACE,0BAA+B;ErDu2UnC;AACF;;ACtwUE;EoDhGE;IACE,0BAA+B;ErD02UnC;AACF;;ACxwUE;EoDjGE;IACE,0BAA+B;ErD62UnC;AACF;;AC1wUE;EoDlGE;IACE,0BAA+B;ErDg3UnC;AACF;;AC3wUI;EoDpGA;IACE,0BAA+B;ErDm3UnC;AACF;;ACvwUI;EoD3GA;IACE,0BAA+B;ErDs3UnC;AACF;;ACxwUI;EoD7GA;IACE,0BAA+B;ErDy3UnC;AACF;;ACpwUI;EoDpHA;IACE,0BAA+B;ErD43UnC;AACF;;AqDz5UE;EACE,gCAA+B;ArD45UnC;;AC5zUE;EoD9FE;IACE,gCAA+B;ErD85UnC;AACF;;AC9zUE;EoD/FE;IACE,gCAA+B;ErDi6UnC;AACF;;ACh0UE;EoDhGE;IACE,gCAA+B;ErDo6UnC;AACF;;ACl0UE;EoDjGE;IACE,gCAA+B;ErDu6UnC;AACF;;ACp0UE;EoDlGE;IACE,gCAA+B;ErD06UnC;AACF;;ACr0UI;EoDpGA;IACE,gCAA+B;ErD66UnC;AACF;;ACj0UI;EoD3GA;IACE,gCAA+B;ErDg7UnC;AACF;;ACl0UI;EoD7GA;IACE,gCAA+B;ErDm7UnC;AACF;;AC9zUI;EoDpHA;IACE,gCAA+B;ErDs7UnC;AACF;;AqDn9UE;EACE,+BAA+B;ArDs9UnC;;ACt3UE;EoD9FE;IACE,+BAA+B;ErDw9UnC;AACF;;ACx3UE;EoD/FE;IACE,+BAA+B;ErD29UnC;AACF;;AC13UE;EoDhGE;IACE,+BAA+B;ErD89UnC;AACF;;AC53UE;EoDjGE;IACE,+BAA+B;ErDi+UnC;AACF;;AC93UE;EoDlGE;IACE,+BAA+B;ErDo+UnC;AACF;;AC/3UI;EoDpGA;IACE,+BAA+B;ErDu+UnC;AACF;;AC33UI;EoD3GA;IACE,+BAA+B;ErD0+UnC;AACF;;AC53UI;EoD7GA;IACE,+BAA+B;ErD6+UnC;AACF;;ACx3UI;EoDpHA;IACE,+BAA+B;ErDg/UnC;AACF;;AqD/+UA;EACE,wBAAwB;ArDk/U1B;;AqDh/UA;EACE,uBAAuB;EACvB,iCAAiC;EACjC,yBAAyB;EACzB,2BAA2B;EAC3B,qBAAqB;EACrB,6BAA6B;EAC7B,8BAA8B;EAC9B,wBAAwB;ArDm/U1B;;AC37UE;EoDrDA;IACE,wBAAwB;ErDo/U1B;AACF;;AC77UE;EoDrDA;IACE,wBAAwB;ErDs/U1B;AACF;;AC/7UE;EoDrDA;IACE,wBAAwB;ErDw/U1B;AACF;;ACj8UE;EoDrDA;IACE,wBAAwB;ErD0/U1B;AACF;;ACn8UE;EoDrDA;IACE,wBAAwB;ErD4/U1B;AACF;;ACp8UI;EoDtDF;IACE,wBAAwB;ErD8/U1B;AACF;;ACh8UI;EoD5DF;IACE,wBAAwB;ErDggV1B;AACF;;ACj8UI;EoD7DF;IACE,wBAAwB;ErDkgV1B;AACF;;AC77UI;EoDnEF;IACE,wBAAwB;ErDogV1B;AACF;;AqDngVA;EACE,6BAA6B;ArDsgV/B;;ACr/UE;EoDdA;IACE,6BAA6B;ErDugV/B;AACF;;ACv/UE;EoDdA;IACE,6BAA6B;ErDygV/B;AACF;;ACz/UE;EoDdA;IACE,6BAA6B;ErD2gV/B;AACF;;AC3/UE;EoDdA;IACE,6BAA6B;ErD6gV/B;AACF;;AC7/UE;EoDdA;IACE,6BAA6B;ErD+gV/B;AACF;;AC9/UI;EoDfF;IACE,6BAA6B;ErDihV/B;AACF;;AC1/UI;EoDrBF;IACE,6BAA6B;ErDmhV/B;AACF;;AC3/UI;EoDtBF;IACE,6BAA6B;ErDqhV/B;AACF;;ACv/UI;EoD5BF;IACE,6BAA6B;ErDuhV/B;AACF;;AsDjpVA,iBAAA;ACWA;EACE,oBAAoB;EACpB,aAAa;EACb,sBAAsB;EACtB,8BAA8B;AvD0oVhC;;AuD9oVA;EAMI,gBAAgB;AvD4oVpB;;AuDlpVA;EASM,mBAAmB;AvD6oVzB;;AuDtpVA;EAeM,uBxDXyB;EwDYzB,cxDzBuB;ACoqV7B;;AuD3pVA;;EAmBQ,cAAc;AvD6oVtB;;AuDhqVA;EAqBQ,cxD9BqB;AC6qV7B;;AuDpqVA;EAuBQ,4BxDhCqB;ACirV7B;;AuDxqVA;;EA0BU,cxDnCmB;ACsrV7B;;ACtkVE;EsDvGF;IA6BU,uBxDzBqB;EC8qV7B;AACF;;AuDnrVA;;EAgCQ,4BxDzCqB;ACisV7B;;AuDxrVA;;;EAqCU,yB7C4DuB;E6C3DvB,cxD/CmB;ACwsV7B;;AuD/rVA;EAyCU,cxDlDmB;EwDmDnB,YAAY;AvD0pVtB;;AuDpsVA;EA4CY,UAAU;AvD4pVtB;;AuDxsVA;EA+CY,uBAAwB;EACxB,UAAU;AvD6pVtB;;AuD7sVA;EAoDY,cxD7DiB;AC0tV7B;;AuDjtVA;EAsDc,uCxD/De;AC8tV7B;;AuDrtVA;EA0Dc,yBxDnEe;EwDoEf,qBxDpEe;EwDqEf,YxDxDiB;ACutV/B;;AuD3tVA;EAkEU,4EAAyG;AvD6pVnH;;ACpoVE;EsD3FF;IAqEc,4EAAyG;EvD+pVrH;AACF;;AuDruVA;EAeM,yBxDxBuB;EwDyBvB,YxDZyB;ACsuV/B;;AuD1uVA;;EAmBQ,cAAc;AvD4tVtB;;AuD/uVA;EAqBQ,YxDjBuB;AC+uV/B;;AuDnvVA;EAuBQ,+BxDnBuB;ACmvV/B;;AuDvvVA;;EA0BU,YxDtBqB;ACwvV/B;;ACrpVE;EsDvGF;IA6BU,yBxDtCmB;EC0wV3B;AACF;;AuDlwVA;;EAgCQ,+BxD5BuB;ACmwV/B;;AuDvwVA;;;EAqCU,uB7C4DuB;E6C3DvB,YxDlCqB;AC0wV/B;;AuD9wVA;EAyCU,YxDrCqB;EwDsCrB,YAAY;AvDyuVtB;;AuDnxVA;EA4CY,UAAU;AvD2uVtB;;AuDvxVA;EA+CY,yBAAwB;EACxB,UAAU;AvD4uVtB;;AuD5xVA;EAoDY,YxDhDmB;AC4xV/B;;AuDhyVA;EAsDc,uCxD/De;AC6yV7B;;AuDpyVA;EA0Dc,uBxDtDiB;EwDuDjB,mBxDvDiB;EwDwDjB,cxDrEe;ACmzV7B;;AuD1yVA;EAkEU,8EAAyG;AvD4uVnH;;ACntVE;EsD3FF;IAqEc,8EAAyG;EvD8uVrH;AACF;;AuDpzVA;EAeM,4BxDbwB;EwDcxB,yB7CqDe;AVovVrB;;AuDzzVA;;EAmBQ,cAAc;AvD2yVtB;;AuD9zVA;EAqBQ,yB7CgDa;AV6vVrB;;AuDl0VA;EAuBQ,yB7C8Ca;AViwVrB;;AuDt0VA;;EA0BU,yB7C2CW;AVswVrB;;ACpuVE;EsDvGF;IA6BU,4BxD3BoB;EC80V5B;AACF;;AuDj1VA;;EAgCQ,yB7CqCa;AVixVrB;;AuDt1VA;;;EAqCU,yB7C4DuB;E6C3DvB,yB7C+BW;AVwxVrB;;AuD71VA;EAyCU,yB7C4BW;E6C3BX,YAAY;AvDwzVtB;;AuDl2VA;EA4CY,UAAU;AvD0zVtB;;AuDt2VA;EA+CY,4BAAwB;EACxB,UAAU;AvD2zVtB;;AuD32VA;EAoDY,yB7CiBS;AV0yVrB;;AuD/2VA;EAsDc,uCxD/De;AC43V7B;;AuDn3VA;EA0Dc,oC7CWO;E6CVP,gC7CUO;E6CTP,iBxD1DgB;ACu3V9B;;AuDz3VA;EAkEU,iFAAyG;AvD2zVnH;;AClyVE;EsD3FF;IAqEc,iFAAyG;EvD6zVrH;AACF;;AuDn4VA;EAeM,yBxDpBwB;EwDqBxB,W7CuDU;AVi0VhB;;AuDx4VA;;EAmBQ,cAAc;AvD03VtB;;AuD74VA;EAqBQ,W7CkDQ;AV00VhB;;AuDj5VA;EAuBQ,+B7CgDQ;AV80VhB;;AuDr5VA;;EA0BU,W7C6CM;AVm1VhB;;ACnzVE;EsDvGF;IA6BU,yBxDlCoB;ECo6V5B;AACF;;AuDh6VA;;EAgCQ,+B7CuCQ;AV81VhB;;AuDr6VA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVq2VhB;;AuD56VA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDu4VtB;;AuDj7VA;EA4CY,UAAU;AvDy4VtB;;AuDr7VA;EA+CY,yBAAwB;EACxB,UAAU;AvD04VtB;;AuD17VA;EAoDY,W7CmBI;AVu3VhB;;AuD97VA;EAsDc,uCxD/De;AC28V7B;;AuDl8VA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDjEgB;AC68V9B;;AuDx8VA;EAkEU,gFAAyG;AvD04VnH;;ACj3VE;EsD3FF;IAqEc,gFAAyG;EvD44VrH;AACF;;AuDl9VA;EAeM,yBxDN4B;EwDO5B,W7CuDU;AVg5VhB;;AuDv9VA;;EAmBQ,cAAc;AvDy8VtB;;AuD59VA;EAqBQ,W7CkDQ;AVy5VhB;;AuDh+VA;EAuBQ,+B7CgDQ;AV65VhB;;AuDp+VA;;EA0BU,W7C6CM;AVk6VhB;;ACl4VE;EsDvGF;IA6BU,yBxDpBwB;ECq+VhC;AACF;;AuD/+VA;;EAgCQ,+B7CuCQ;AV66VhB;;AuDp/VA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVo7VhB;;AuD3/VA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDs9VtB;;AuDhgWA;EA4CY,UAAU;AvDw9VtB;;AuDpgWA;EA+CY,yBAAwB;EACxB,UAAU;AvDy9VtB;;AuDzgWA;EAoDY,W7CmBI;AVs8VhB;;AuD7gWA;EAsDc,uCxD/De;AC0hW7B;;AuDjhWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDnDoB;AC8gWlC;;AuDvhWA;EAkEU,gFAAyG;AvDy9VnH;;ACh8VE;EsD3FF;IAqEc,gFAAyG;EvD29VrH;AACF;;AuDjiWA;EAeM,yBxDJ4B;EwDK5B,W7CuDU;AV+9VhB;;AuDtiWA;;EAmBQ,cAAc;AvDwhWtB;;AuD3iWA;EAqBQ,W7CkDQ;AVw+VhB;;AuD/iWA;EAuBQ,+B7CgDQ;AV4+VhB;;AuDnjWA;;EA0BU,W7C6CM;AVi/VhB;;ACj9VE;EsDvGF;IA6BU,yBxDlBwB;ECkjWhC;AACF;;AuD9jWA;;EAgCQ,+B7CuCQ;AV4/VhB;;AuDnkWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVmgWhB;;AuD1kWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDqiWtB;;AuD/kWA;EA4CY,UAAU;AvDuiWtB;;AuDnlWA;EA+CY,yBAAwB;EACxB,UAAU;AvDwiWtB;;AuDxlWA;EAoDY,W7CmBI;AVqhWhB;;AuD5lWA;EAsDc,uCxD/De;ACymW7B;;AuDhmWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDjDoB;AC2lWlC;;AuDtmWA;EAkEU,gFAAyG;AvDwiWnH;;AC/gWE;EsD3FF;IAqEc,gFAAyG;EvD0iWrH;AACF;;AuDhnWA;EAeM,yBxDL4B;EwDM5B,W7CuDU;AV8iWhB;;AuDrnWA;;EAmBQ,cAAc;AvDumWtB;;AuD1nWA;EAqBQ,W7CkDQ;AVujWhB;;AuD9nWA;EAuBQ,+B7CgDQ;AV2jWhB;;AuDloWA;;EA0BU,W7C6CM;AVgkWhB;;AChiWE;EsDvGF;IA6BU,yBxDnBwB;ECkoWhC;AACF;;AuD7oWA;;EAgCQ,+B7CuCQ;AV2kWhB;;AuDlpWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVklWhB;;AuDzpWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDonWtB;;AuD9pWA;EA4CY,UAAU;AvDsnWtB;;AuDlqWA;EA+CY,yBAAwB;EACxB,UAAU;AvDunWtB;;AuDvqWA;EAoDY,W7CmBI;AVomWhB;;AuD3qWA;EAsDc,uCxD/De;ACwrW7B;;AuD/qWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDlDoB;AC2qWlC;;AuDrrWA;EAkEU,gFAAyG;AvDunWnH;;AC9lWE;EsD3FF;IAqEc,gFAAyG;EvDynWrH;AACF;;AuD/rWA;EAeM,yBxDP4B;EwDQ5B,W7CuDU;AV6nWhB;;AuDpsWA;;EAmBQ,cAAc;AvDsrWtB;;AuDzsWA;EAqBQ,W7CkDQ;AVsoWhB;;AuD7sWA;EAuBQ,+B7CgDQ;AV0oWhB;;AuDjtWA;;EA0BU,W7C6CM;AV+oWhB;;AC/mWE;EsDvGF;IA6BU,yBxDrBwB;ECmtWhC;AACF;;AuD5tWA;;EAgCQ,+B7CuCQ;AV0pWhB;;AuDjuWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AViqWhB;;AuDxuWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDmsWtB;;AuD7uWA;EA4CY,UAAU;AvDqsWtB;;AuDjvWA;EA+CY,yBAAwB;EACxB,UAAU;AvDssWtB;;AuDtvWA;EAoDY,W7CmBI;AVmrWhB;;AuD1vWA;EAsDc,uCxD/De;ACuwW7B;;AuD9vWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDpDoB;AC4vWlC;;AuDpwWA;EAkEU,gFAAyG;AvDssWnH;;AC7qWE;EsD3FF;IAqEc,gFAAyG;EvDwsWrH;AACF;;AuD9wWA;EAeM,yBxDR4B;EwDS5B,yB7CqDe;AV8sWrB;;AuDnxWA;;EAmBQ,cAAc;AvDqwWtB;;AuDxxWA;EAqBQ,yB7CgDa;AVutWrB;;AuD5xWA;EAuBQ,yB7C8Ca;AV2tWrB;;AuDhyWA;;EA0BU,yB7C2CW;AVguWrB;;AC9rWE;EsDvGF;IA6BU,yBxDtBwB;ECmyWhC;AACF;;AuD3yWA;;EAgCQ,yB7CqCa;AV2uWrB;;AuDhzWA;;;EAqCU,yB7C4DuB;E6C3DvB,yB7C+BW;AVkvWrB;;AuDvzWA;EAyCU,yB7C4BW;E6C3BX,YAAY;AvDkxWtB;;AuD5zWA;EA4CY,UAAU;AvDoxWtB;;AuDh0WA;EA+CY,yBAAwB;EACxB,UAAU;AvDqxWtB;;AuDr0WA;EAoDY,yB7CiBS;AVowWrB;;AuDz0WA;EAsDc,uCxD/De;ACs1W7B;;AuD70WA;EA0Dc,oC7CWO;E6CVP,gC7CUO;E6CTP,cxDrDoB;AC40WlC;;AuDn1WA;EAkEU,gFAAyG;AvDqxWnH;;AC5vWE;EsD3FF;IAqEc,gFAAyG;EvDuxWrH;AACF;;AuD71WA;EAeM,yBxDF2B;EwDG3B,W7CuDU;AV2xWhB;;AuDl2WA;;EAmBQ,cAAc;AvDo1WtB;;AuDv2WA;EAqBQ,W7CkDQ;AVoyWhB;;AuD32WA;EAuBQ,+B7CgDQ;AVwyWhB;;AuD/2WA;;EA0BU,W7C6CM;AV6yWhB;;AC7wWE;EsDvGF;IA6BU,yBxDhBuB;EC42W/B;AACF;;AuD13WA;;EAgCQ,+B7CuCQ;AVwzWhB;;AuD/3WA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AV+zWhB;;AuDt4WA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDi2WtB;;AuD34WA;EA4CY,UAAU;AvDm2WtB;;AuD/4WA;EA+CY,yBAAwB;EACxB,UAAU;AvDo2WtB;;AuDp5WA;EAoDY,W7CmBI;AVi1WhB;;AuDx5WA;EAsDc,uCxD/De;ACq6W7B;;AuD55WA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxD/CmB;ACq5WjC;;AuDl6WA;EAkEU,gFAAyG;AvDo2WnH;;AC30WE;EsD3FF;IAqEc,gFAAyG;EvDs2WrH;AACF;;AuD56WA;EAyEM,eAhF0B;AvDu7WhC;;ACj1WE;EsD/FF;IA6EQ,oBAnF8B;EvD27WpC;AACF;;ACv1WE;EsD/FF;IAiFQ,mBAtF4B;EvDg8WlC;AACF;;AuD57WA;EAsFM,mBAAmB;EACnB,aAAa;AvD02WnB;;AuDj8WA;EAyFQ,YAAY;EACZ,cAAc;AvD42WtB;;AuDt8WA;EA4FI,gBAAgB;AvD82WpB;;AuD18WA;EA8FI,iBAAiB;AvDg3WrB;;AuD52WA;EAEE,gBAAgB;AvD82WlB;;AuDh3WA;EAII,SAAS;EACT,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,QAAQ;EACR,qCAAqC;AvDg3WzC;;AuDz3WA;EAYI,YAAY;AvDi3WhB;;ACp4WE;EsDOF;IAeI,aAAa;EvDm3Wf;AACF;;AuDl3WA;EACE,kBAAkB;AvDq3WpB;;AC94WE;EsDwBF;IAKM,aAAa;EvDs3WjB;EuD33WF;IAOQ,sBAAsB;EvDu3W5B;AACF;;ACn5WE;EsDoBF;IASI,aAAa;IACb,uBAAuB;EvD23WzB;EuDr4WF;ItDsDI,oBsD1CwC;EvD43W1C;AACF;;AuDz3WA;;EAEE,YAAY;EACZ,cAAc;AvD43WhB;;AuD13WA;EACE,YAAY;EACZ,cAAc;EACd,oBApJ6B;AvDihX/B;;ACz6WE;EsDyCF;IAKI,kBArJgC;EvDqhXlC;AACF;;AwDlhXA;EACE,oBAN2B;AxD2hX7B;;ACv6WE;EuD/GF;IAII,kBAR+B;ExD+hXjC;EwD3hXF;IAOM,oBAV8B;ExDiiXlC;EwD9hXF;IASM,mBAX4B;ExDmiXhC;AACF;;AyDniXA;EACE,yB1DO4B;E0DN5B,yBAJ+B;AzD0iXjC","file":"bulma.css"} \ No newline at end of file diff --git a/mc_openapi/assets/static/bulma.min.css b/mc_openapi/assets/static/bulma.min.css new file mode 100644 index 0000000000000000000000000000000000000000..86ad2ff1408bdec4069ed2ea355bb5e32e356d96 --- /dev/null +++ b/mc_openapi/assets/static/bulma.min.css @@ -0,0 +1 @@ +/*! bulma.io v0.9.4 | MIT License | github.com/jgthms/bulma */.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.5em - 1px);padding-left:calc(.75em - 1px);padding-right:calc(.75em - 1px);padding-top:calc(.5em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}.breadcrumb,.button,.file,.is-unselectable,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.level:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.pagination:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1em;font-weight:400;line-height:1.5}a{color:#485fc7;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#da1039;font-size:.875em;font-weight:400;padding:.25em .5em .25em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type=checkbox],input[type=radio]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#363636}@-webkit-keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px #485fc7}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #485fc7}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.5em - 1px);margin-right:calc(-.5em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#485fc7;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-ghost{background:0 0;border-color:transparent;color:#485fc7;text-decoration:none}.button.is-ghost.is-hovered,.button.is-ghost:hover{color:#485fc7;text-decoration:underline}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-hovered,.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined.is-focused,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined.is-loading.is-focused::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined.is-focused,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-hovered,.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined.is-focused,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined.is-loading.is-focused::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined.is-focused,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-hovered,.button.is-light.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined.is-focused,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined.is-loading.is-focused::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-light.is-inverted.is-outlined.is-focused,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-dark{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#fff}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:#363636;box-shadow:none}.button.is-dark.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-hovered,.button.is-dark.is-inverted:hover{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined.is-focused,.button.is-dark.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined.is-loading.is-focused::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined.is-focused,.button.is-dark.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:#00d1b2;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-hovered,.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined.is-focused,.button.is-primary.is-outlined.is-hovered,.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined.is-loading.is-focused::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-outlined.is-loading:focus::after,.button.is-primary.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined.is-focused,.button.is-primary.is-inverted.is-outlined.is-hovered,.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light{background-color:#ebfffc;color:#00947e}.button.is-primary.is-light.is-hovered,.button.is-primary.is-light:hover{background-color:#defffa;border-color:transparent;color:#00947e}.button.is-primary.is-light.is-active,.button.is-primary.is-light:active{background-color:#d1fff8;border-color:transparent;color:#00947e}.button.is-link{background-color:#485fc7;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#3e56c4;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#3a51bb;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#485fc7;border-color:#485fc7;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#485fc7}.button.is-link.is-inverted.is-hovered,.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#485fc7}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#485fc7;color:#485fc7}.button.is-link.is-outlined.is-focused,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#485fc7;border-color:#485fc7;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #485fc7 #485fc7!important}.button.is-link.is-outlined.is-loading.is-focused::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#485fc7;box-shadow:none;color:#485fc7}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined.is-focused,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#485fc7}.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #485fc7 #485fc7!important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eff1fa;color:#3850b7}.button.is-link.is-light.is-hovered,.button.is-link.is-light:hover{background-color:#e6e9f7;border-color:transparent;color:#3850b7}.button.is-link.is-light.is-active,.button.is-link.is-light:active{background-color:#dce0f4;border-color:transparent;color:#3850b7}.button.is-info{background-color:#3e8ed0;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#3488ce;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#3082c5;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3e8ed0;border-color:#3e8ed0;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3e8ed0}.button.is-info.is-inverted.is-hovered,.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3e8ed0}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#3e8ed0;color:#3e8ed0}.button.is-info.is-outlined.is-focused,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#3e8ed0;border-color:#3e8ed0;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3e8ed0 #3e8ed0!important}.button.is-info.is-outlined.is-loading.is-focused::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#3e8ed0;box-shadow:none;color:#3e8ed0}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined.is-focused,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#3e8ed0}.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #3e8ed0 #3e8ed0!important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#eff5fb;color:#296fa8}.button.is-info.is-light.is-hovered,.button.is-info.is-light:hover{background-color:#e4eff9;border-color:transparent;color:#296fa8}.button.is-info.is-light.is-active,.button.is-info.is-light:active{background-color:#dae9f6;border-color:transparent;color:#296fa8}.button.is-success{background-color:#48c78e;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#3ec487;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#3abb81;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#48c78e;border-color:#48c78e;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#48c78e}.button.is-success.is-inverted.is-hovered,.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#48c78e}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#48c78e;color:#48c78e}.button.is-success.is-outlined.is-focused,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#48c78e;border-color:#48c78e;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #48c78e #48c78e!important}.button.is-success.is-outlined.is-loading.is-focused::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#48c78e;box-shadow:none;color:#48c78e}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined.is-focused,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#48c78e}.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #48c78e #48c78e!important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#effaf5;color:#257953}.button.is-success.is-light.is-hovered,.button.is-success.is-light:hover{background-color:#e6f7ef;border-color:transparent;color:#257953}.button.is-success.is-light.is-active,.button.is-success.is-light:active{background-color:#dcf4e9;border-color:transparent;color:#257953}.button.is-warning{background-color:#ffe08a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdc7d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd970;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffe08a;border-color:#ffe08a;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffe08a}.button.is-warning.is-inverted.is-hovered,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#ffe08a}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffe08a;color:#ffe08a}.button.is-warning.is-outlined.is-focused,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffe08a;border-color:#ffe08a;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffe08a #ffe08a!important}.button.is-warning.is-outlined.is-loading.is-focused::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffe08a;box-shadow:none;color:#ffe08a}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined.is-focused,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffe08a}.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #ffe08a #ffe08a!important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-warning.is-light{background-color:#fffaeb;color:#946c00}.button.is-warning.is-light.is-hovered,.button.is-warning.is-light:hover{background-color:#fff6de;border-color:transparent;color:#946c00}.button.is-warning.is-light.is-active,.button.is-warning.is-light:active{background-color:#fff3d1;border-color:transparent;color:#946c00}.button.is-danger{background-color:#f14668;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#f03a5f;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ef2e55;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#f14668;border-color:#f14668;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-hovered,.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#f14668}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;color:#f14668}.button.is-danger.is-outlined.is-focused,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#f14668;border-color:#f14668;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-outlined.is-loading.is-focused::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;box-shadow:none;color:#f14668}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined.is-focused,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.button.is-danger.is-light.is-hovered,.button.is-danger.is-light:hover{background-color:#fde0e6;border-color:transparent;color:#cc0f35}.button.is-danger.is-light.is-active,.button.is-danger.is-light:active{background-color:#fcd4dc;border-color:transparent;color:#cc0f35}.button.is-small{font-size:.75rem}.button.is-small:not(.is-rounded){border-radius:2px}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em * .5));top:calc(50% - (1em * .5));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:9999px;padding-left:calc(1em + .25em);padding-right:calc(1em + .25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}@media screen and (max-width:768px){.button.is-responsive.is-small{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.button.is-responsive.is-small{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none!important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width:1024px){.container{max-width:960px}}@media screen and (max-width:1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width:1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width:1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width:1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small{font-size:.75rem}.content.is-normal{font-size:1rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:9999px}.image.is-fullwidth{width:100%}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:0 0}.notification>.delete{right:.5rem;position:absolute;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.notification.is-dark{background-color:#363636;color:#fff}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-primary.is-light{background-color:#ebfffc;color:#00947e}.notification.is-link{background-color:#485fc7;color:#fff}.notification.is-link.is-light{background-color:#eff1fa;color:#3850b7}.notification.is-info{background-color:#3e8ed0;color:#fff}.notification.is-info.is-light{background-color:#eff5fb;color:#296fa8}.notification.is-success{background-color:#48c78e;color:#fff}.notification.is-success.is-light{background-color:#effaf5;color:#257953}.notification.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.notification.is-warning.is-light{background-color:#fffaeb;color:#946c00}.notification.is-danger{background-color:#f14668;color:#fff}.notification.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right,#fff 30%,#ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right,#0a0a0a 30%,#ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right,#f5f5f5 30%,#ededed 30%)}.progress.is-dark::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#ededed 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#485fc7}.progress.is-link::-moz-progress-bar{background-color:#485fc7}.progress.is-link::-ms-fill{background-color:#485fc7}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#485fc7 30%,#ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3e8ed0}.progress.is-info::-moz-progress-bar{background-color:#3e8ed0}.progress.is-info::-ms-fill{background-color:#3e8ed0}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#3e8ed0 30%,#ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#48c78e}.progress.is-success::-moz-progress-bar{background-color:#48c78e}.progress.is-success::-ms-fill{background-color:#48c78e}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#48c78e 30%,#ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffe08a}.progress.is-warning::-moz-progress-bar{background-color:#ffe08a}.progress.is-warning::-ms-fill{background-color:#ffe08a}.progress.is-warning:indeterminate{background-image:linear-gradient(to right,#ffe08a 30%,#ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#f14668}.progress.is-danger::-moz-progress-bar{background-color:#f14668}.progress.is-danger::-ms-fill{background-color:#f14668}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#f14668 30%,#ededed 30%)}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right,#4a4a4a 30%,#ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress:indeterminate::-ms-fill{animation-name:none}.progress.is-small{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#485fc7;border-color:#485fc7;color:#fff}.table td.is-info,.table th.is-info{background-color:#3e8ed0;border-color:#3e8ed0;color:#fff}.table td.is-success,.table th.is-success{background-color:#48c78e;border-color:#48c78e;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffe08a;border-color:#ffe08a;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#f14668;border-color:#f14668;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#00d1b2;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#363636}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#00d1b2;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(2n){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:.25em .5em}.table.is-striped tbody tr:not(.is-selected):nth-child(2n){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.tag:not(body).is-dark{background-color:#363636;color:#fff}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-primary.is-light{background-color:#ebfffc;color:#00947e}.tag:not(body).is-link{background-color:#485fc7;color:#fff}.tag:not(body).is-link.is-light{background-color:#eff1fa;color:#3850b7}.tag:not(body).is-info{background-color:#3e8ed0;color:#fff}.tag:not(body).is-info.is-light{background-color:#eff5fb;color:#296fa8}.tag:not(body).is-success{background-color:#48c78e;color:#fff}.tag:not(body).is-success.is-light{background-color:#effaf5;color:#257953}.tag:not(body).is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.tag:not(body).is-warning.is-light{background-color:#fffaeb;color:#946c00}.tag:not(body).is-danger{background-color:#f14668;color:#fff}.tag:not(body).is-danger.is-light{background-color:#feecf0;color:#cc0f35}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:9999px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.number{align-items:center;background-color:#f5f5f5;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.input,.select select,.textarea{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.input::-moz-placeholder,.select select::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.select select:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input:hover,.is-hovered.input,.is-hovered.textarea,.select select.is-hovered,.select select:hover,.textarea:hover{border-color:#b5b5b5}.input:active,.input:focus,.is-active.input,.is-active.textarea,.is-focused.input,.is-focused.textarea,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{border-color:#485fc7;box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.input[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .select select,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input,.textarea{box-shadow:inset 0 .0625em .125em rgba(10,10,10,.05);max-width:100%;width:100%}.input[readonly],.textarea[readonly]{box-shadow:none}.is-white.input,.is-white.textarea{border-color:#fff}.is-white.input:active,.is-white.input:focus,.is-white.is-active.input,.is-white.is-active.textarea,.is-white.is-focused.input,.is-white.is-focused.textarea,.is-white.textarea:active,.is-white.textarea:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.is-black.input,.is-black.textarea{border-color:#0a0a0a}.is-black.input:active,.is-black.input:focus,.is-black.is-active.input,.is-black.is-active.textarea,.is-black.is-focused.input,.is-black.is-focused.textarea,.is-black.textarea:active,.is-black.textarea:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.is-light.input,.is-light.textarea{border-color:#f5f5f5}.is-light.input:active,.is-light.input:focus,.is-light.is-active.input,.is-light.is-active.textarea,.is-light.is-focused.input,.is-light.is-focused.textarea,.is-light.textarea:active,.is-light.textarea:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.is-dark.input,.is-dark.textarea{border-color:#363636}.is-dark.input:active,.is-dark.input:focus,.is-dark.is-active.input,.is-dark.is-active.textarea,.is-dark.is-focused.input,.is-dark.is-focused.textarea,.is-dark.textarea:active,.is-dark.textarea:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.is-primary.input,.is-primary.textarea{border-color:#00d1b2}.is-primary.input:active,.is-primary.input:focus,.is-primary.is-active.input,.is-primary.is-active.textarea,.is-primary.is-focused.input,.is-primary.is-focused.textarea,.is-primary.textarea:active,.is-primary.textarea:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.is-link.input,.is-link.textarea{border-color:#485fc7}.is-link.input:active,.is-link.input:focus,.is-link.is-active.input,.is-link.is-active.textarea,.is-link.is-focused.input,.is-link.is-focused.textarea,.is-link.textarea:active,.is-link.textarea:focus{box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.is-info.input,.is-info.textarea{border-color:#3e8ed0}.is-info.input:active,.is-info.input:focus,.is-info.is-active.input,.is-info.is-active.textarea,.is-info.is-focused.input,.is-info.is-focused.textarea,.is-info.textarea:active,.is-info.textarea:focus{box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.is-success.input,.is-success.textarea{border-color:#48c78e}.is-success.input:active,.is-success.input:focus,.is-success.is-active.input,.is-success.is-active.textarea,.is-success.is-focused.input,.is-success.is-focused.textarea,.is-success.textarea:active,.is-success.textarea:focus{box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.is-warning.input,.is-warning.textarea{border-color:#ffe08a}.is-warning.input:active,.is-warning.input:focus,.is-warning.is-active.input,.is-warning.is-active.textarea,.is-warning.is-focused.input,.is-warning.is-focused.textarea,.is-warning.textarea:active,.is-warning.textarea:focus{box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.is-danger.input,.is-danger.textarea{border-color:#f14668}.is-danger.input:active,.is-danger.input:focus,.is-danger.is-active.input,.is-danger.is-active.textarea,.is-danger.is-focused.input,.is-danger.is-focused.textarea,.is-danger.textarea:active,.is-danger.textarea:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.is-small.input,.is-small.textarea{border-radius:2px;font-size:.75rem}.is-medium.input,.is-medium.textarea{font-size:1.25rem}.is-large.input,.is-large.textarea{font-size:1.5rem}.is-fullwidth.input,.is-fullwidth.textarea{display:block;width:100%}.is-inline.input,.is-inline.textarea{display:inline;width:auto}.input.is-rounded{border-radius:9999px;padding-left:calc(calc(.75em - 1px) + .375em);padding-right:calc(calc(.75em - 1px) + .375em)}.input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox input[disabled],.checkbox[disabled],.radio input[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#485fc7;right:1.125em;z-index:4}.select.is-rounded select{border-radius:9999px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#485fc7}.select.is-link select{border-color:#485fc7}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#3a51bb}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.select.is-info:not(:hover)::after{border-color:#3e8ed0}.select.is-info select{border-color:#3e8ed0}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#3082c5}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.select.is-success:not(:hover)::after{border-color:#48c78e}.select.is-success select{border-color:#48c78e}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#3abb81}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.select.is-warning:not(:hover)::after{border-color:#ffe08a}.select.is-warning select{border-color:#ffe08a}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd970}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.select.is-danger:not(:hover)::after{border-color:#f14668}.select.is-danger select{border-color:#f14668}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ef2e55}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.select.is-small{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#7a7a7a!important;opacity:.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;transform:none}.select.is-loading.is-small:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:rgba(0,0,0,.7)}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#fff}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#485fc7;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#3e56c4;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,95,199,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#3a51bb;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#3e8ed0;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#3488ce;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(62,142,208,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#3082c5;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#48c78e;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#3ec487;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,199,142,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#3abb81;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffe08a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdc7d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,224,138,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd970;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#f14668;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#f03a5f;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(241,70,104,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ef2e55;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.file.is-normal{font-size:1rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#485fc7}.help.is-info{color:#3e8ed0}.help.is-success{color:#48c78e}.help.is-warning{color:#ffe08a}.help.is-danger{color:#f14668}.field:not(:last-child){margin-bottom:.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus:hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width:769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width:768px){.field-label{margin-bottom:.5rem}}@media screen and (min-width:769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width:769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#4a4a4a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute!important;right:.625em;top:.625em;z-index:4}.control.is-loading.is-small:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#485fc7;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;border-radius:.25rem;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;max-width:100%;position:relative}.card-content:first-child,.card-footer:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-content:last-child,.card-footer:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 .125em .25em rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem 1rem}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#485fc7;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width:769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .subtitle,.level-item .title{margin-bottom:0}@media screen and (max-width:768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width:769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width:768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width:769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width:769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width:768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#485fc7;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body{border-color:#363636}.message.is-primary{background-color:#ebfffc}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#00947e}.message.is-link{background-color:#eff1fa}.message.is-link .message-header{background-color:#485fc7;color:#fff}.message.is-link .message-body{border-color:#485fc7;color:#3850b7}.message.is-info{background-color:#eff5fb}.message.is-info .message-header{background-color:#3e8ed0;color:#fff}.message.is-info .message-body{border-color:#3e8ed0;color:#296fa8}.message.is-success{background-color:#effaf5}.message.is-success .message-header{background-color:#48c78e;color:#fff}.message.is-success .message-body{border-color:#48c78e;color:#257953}.message.is-warning{background-color:#fffaeb}.message.is-warning .message-header{background-color:#ffe08a;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffe08a;color:#946c00}.message.is-danger{background-color:#feecf0}.message.is-danger .message-header{background-color:#f14668;color:#fff}.message.is-danger .message-body{border-color:#f14668;color:#cc0f35}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px){.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-foot,.modal-card-head{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#363636;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width:1024px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand .navbar-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,.7)}}.navbar.is-dark{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#fff}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#fff}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#485fc7;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#485fc7;color:#fff}}.navbar.is-info{background-color:#3e8ed0;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3e8ed0;color:#fff}}.navbar.is-success{background-color:#48c78e;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#48c78e;color:#fff}}.navbar.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffe08a;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#f14668;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f14668;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:first-child{top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:first-child{transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#485fc7}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#485fc7}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#485fc7;border-bottom-style:solid;border-bottom-width:3px;color:#485fc7;padding-bottom:calc(.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#485fc7;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:.5rem 0}@media screen and (max-width:1023px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover{background-color:transparent!important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent!important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#485fc7}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(.25em,-.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#485fc7}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity,transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:focus):not(:hover),a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:9999px}.pagination.is-rounded .pagination-link{border-radius:9999px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.5em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#485fc7}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link.is-disabled,.pagination-link[disabled],.pagination-next.is-disabled,.pagination-next[disabled],.pagination-previous.is-disabled,.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#485fc7;border-color:#485fc7;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}.pagination-list li{list-style:none}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width:769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading{background-color:#00d1b2;color:#fff}.panel.is-primary .panel-tabs a.is-active{border-bottom-color:#00d1b2}.panel.is-primary .panel-block.is-active .panel-icon{color:#00d1b2}.panel.is-link .panel-heading{background-color:#485fc7;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#485fc7}.panel.is-link .panel-block.is-active .panel-icon{color:#485fc7}.panel.is-info .panel-heading{background-color:#3e8ed0;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3e8ed0}.panel.is-info .panel-block.is-active .panel-icon{color:#3e8ed0}.panel.is-success .panel-heading{background-color:#48c78e;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#48c78e}.panel.is-success .panel-block.is-active .panel-icon{color:#48c78e}.panel.is-warning .panel-heading{background-color:#ffe08a;color:rgba(0,0,0,.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffe08a}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffe08a}.panel.is-danger .panel-heading{background-color:#f14668;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f14668}.panel.is-danger .panel-block.is-active .panel-icon{color:#f14668}.panel-block:not(:last-child),.panel-tabs:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#363636;font-size:1.25em;font-weight:700;line-height:1.25;padding:.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#485fc7}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .75em}.panel-block input[type=checkbox]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#485fc7;color:#363636}.panel-block.is-active .panel-icon{color:#485fc7}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#7a7a7a;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#485fc7;color:#485fc7}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:transparent!important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#485fc7;border-color:#485fc7;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}.tabs.is-small{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none;width:unset}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0}.columns.is-mobile>.column.is-1{flex:none;width:8.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width:768px){.column.is-narrow-mobile{flex:none;width:unset}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0}.column.is-1-mobile{flex:none;width:8.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width:769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none;width:unset}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width:1023px){.column.is-narrow-touch{flex:none;width:unset}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0}.column.is-1-touch{flex:none;width:8.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1024px){.column.is-narrow-desktop{flex:none;width:unset}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0}.column.is-1-desktop{flex:none;width:8.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width:1216px){.column.is-narrow-widescreen{flex:none;width:unset}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0}.column.is-1-widescreen{flex:none;width:8.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width:1408px){.column.is-narrow-fullhd{flex:none;width:unset}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0}.column.is-1-fullhd{flex:none;width:8.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0!important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap:0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap:0rem}@media screen and (max-width:768px){.columns.is-variable.is-0-mobile{--columnGap:0rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-0-tablet{--columnGap:0rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1023px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1024px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-0-desktop-only{--columnGap:0rem}}@media screen and (min-width:1216px){.columns.is-variable.is-0-widescreen{--columnGap:0rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-0-widescreen-only{--columnGap:0rem}}@media screen and (min-width:1408px){.columns.is-variable.is-0-fullhd{--columnGap:0rem}}.columns.is-variable.is-1{--columnGap:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-3-fullhd{--columnGap:0.75rem}}.columns.is-variable.is-4{--columnGap:1rem}@media screen and (max-width:768px){.columns.is-variable.is-4-mobile{--columnGap:1rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-4-tablet{--columnGap:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1023px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1024px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-4-desktop-only{--columnGap:1rem}}@media screen and (min-width:1216px){.columns.is-variable.is-4-widescreen{--columnGap:1rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-4-widescreen-only{--columnGap:1rem}}@media screen and (min-width:1408px){.columns.is-variable.is-4-fullhd{--columnGap:1rem}}.columns.is-variable.is-5{--columnGap:1.25rem}@media screen and (max-width:768px){.columns.is-variable.is-5-mobile{--columnGap:1.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-5-tablet{--columnGap:1.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-5-desktop-only{--columnGap:1.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-5-widescreen{--columnGap:1.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-5-widescreen-only{--columnGap:1.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-5-fullhd{--columnGap:1.25rem}}.columns.is-variable.is-6{--columnGap:1.5rem}@media screen and (max-width:768px){.columns.is-variable.is-6-mobile{--columnGap:1.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-6-tablet{--columnGap:1.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-6-desktop-only{--columnGap:1.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-6-widescreen{--columnGap:1.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-6-widescreen-only{--columnGap:1.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-6-fullhd{--columnGap:1.5rem}}.columns.is-variable.is-7{--columnGap:1.75rem}@media screen and (max-width:768px){.columns.is-variable.is-7-mobile{--columnGap:1.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-7-tablet{--columnGap:1.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-7-desktop-only{--columnGap:1.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-7-widescreen{--columnGap:1.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-7-widescreen-only{--columnGap:1.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-7-fullhd{--columnGap:1.75rem}}.columns.is-variable.is-8{--columnGap:2rem}@media screen and (max-width:768px){.columns.is-variable.is-8-mobile{--columnGap:2rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-8-tablet{--columnGap:2rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1023px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1024px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-8-desktop-only{--columnGap:2rem}}@media screen and (min-width:1216px){.columns.is-variable.is-8-widescreen{--columnGap:2rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-8-widescreen-only{--columnGap:2rem}}@media screen and (min-width:1408px){.columns.is-variable.is-8-fullhd{--columnGap:2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0!important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem!important}@media screen and (min-width:769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-primary-light{color:#ebfffc!important}a.has-text-primary-light:focus,a.has-text-primary-light:hover{color:#b8fff4!important}.has-background-primary-light{background-color:#ebfffc!important}.has-text-primary-dark{color:#00947e!important}a.has-text-primary-dark:focus,a.has-text-primary-dark:hover{color:#00c7a9!important}.has-background-primary-dark{background-color:#00947e!important}.has-text-link{color:#485fc7!important}a.has-text-link:focus,a.has-text-link:hover{color:#3449a8!important}.has-background-link{background-color:#485fc7!important}.has-text-link-light{color:#eff1fa!important}a.has-text-link-light:focus,a.has-text-link-light:hover{color:#c8cfee!important}.has-background-link-light{background-color:#eff1fa!important}.has-text-link-dark{color:#3850b7!important}a.has-text-link-dark:focus,a.has-text-link-dark:hover{color:#576dcb!important}.has-background-link-dark{background-color:#3850b7!important}.has-text-info{color:#3e8ed0!important}a.has-text-info:focus,a.has-text-info:hover{color:#2b74b1!important}.has-background-info{background-color:#3e8ed0!important}.has-text-info-light{color:#eff5fb!important}a.has-text-info-light:focus,a.has-text-info-light:hover{color:#c6ddf1!important}.has-background-info-light{background-color:#eff5fb!important}.has-text-info-dark{color:#296fa8!important}a.has-text-info-dark:focus,a.has-text-info-dark:hover{color:#368ace!important}.has-background-info-dark{background-color:#296fa8!important}.has-text-success{color:#48c78e!important}a.has-text-success:focus,a.has-text-success:hover{color:#34a873!important}.has-background-success{background-color:#48c78e!important}.has-text-success-light{color:#effaf5!important}a.has-text-success-light:focus,a.has-text-success-light:hover{color:#c8eedd!important}.has-background-success-light{background-color:#effaf5!important}.has-text-success-dark{color:#257953!important}a.has-text-success-dark:focus,a.has-text-success-dark:hover{color:#31a06e!important}.has-background-success-dark{background-color:#257953!important}.has-text-warning{color:#ffe08a!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd257!important}.has-background-warning{background-color:#ffe08a!important}.has-text-warning-light{color:#fffaeb!important}a.has-text-warning-light:focus,a.has-text-warning-light:hover{color:#ffecb8!important}.has-background-warning-light{background-color:#fffaeb!important}.has-text-warning-dark{color:#946c00!important}a.has-text-warning-dark:focus,a.has-text-warning-dark:hover{color:#c79200!important}.has-background-warning-dark{background-color:#946c00!important}.has-text-danger{color:#f14668!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ee1742!important}.has-background-danger{background-color:#f14668!important}.has-text-danger-light{color:#feecf0!important}a.has-text-danger-light:focus,a.has-text-danger-light:hover{color:#fabdc9!important}.has-background-danger-light{background-color:#feecf0!important}.has-text-danger-dark{color:#cc0f35!important}a.has-text-danger-dark:focus,a.has-text-danger-dark:hover{color:#ee2049!important}.has-background-danger-dark{background-color:#cc0f35!important}.has-text-black-bis{color:#121212!important}.has-background-black-bis{background-color:#121212!important}.has-text-black-ter{color:#242424!important}.has-background-black-ter{background-color:#242424!important}.has-text-grey-darker{color:#363636!important}.has-background-grey-darker{background-color:#363636!important}.has-text-grey-dark{color:#4a4a4a!important}.has-background-grey-dark{background-color:#4a4a4a!important}.has-text-grey{color:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!important}.has-text-grey-light{color:#b5b5b5!important}.has-background-grey-light{background-color:#b5b5b5!important}.has-text-grey-lighter{color:#dbdbdb!important}.has-background-grey-lighter{background-color:#dbdbdb!important}.has-text-white-ter{color:#f5f5f5!important}.has-background-white-ter{background-color:#f5f5f5!important}.has-text-white-bis{color:#fafafa!important}.has-background-white-bis{background-color:#fafafa!important}.is-flex-direction-row{flex-direction:row!important}.is-flex-direction-row-reverse{flex-direction:row-reverse!important}.is-flex-direction-column{flex-direction:column!important}.is-flex-direction-column-reverse{flex-direction:column-reverse!important}.is-flex-wrap-nowrap{flex-wrap:nowrap!important}.is-flex-wrap-wrap{flex-wrap:wrap!important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse!important}.is-justify-content-flex-start{justify-content:flex-start!important}.is-justify-content-flex-end{justify-content:flex-end!important}.is-justify-content-center{justify-content:center!important}.is-justify-content-space-between{justify-content:space-between!important}.is-justify-content-space-around{justify-content:space-around!important}.is-justify-content-space-evenly{justify-content:space-evenly!important}.is-justify-content-start{justify-content:start!important}.is-justify-content-end{justify-content:end!important}.is-justify-content-left{justify-content:left!important}.is-justify-content-right{justify-content:right!important}.is-align-content-flex-start{align-content:flex-start!important}.is-align-content-flex-end{align-content:flex-end!important}.is-align-content-center{align-content:center!important}.is-align-content-space-between{align-content:space-between!important}.is-align-content-space-around{align-content:space-around!important}.is-align-content-space-evenly{align-content:space-evenly!important}.is-align-content-stretch{align-content:stretch!important}.is-align-content-start{align-content:start!important}.is-align-content-end{align-content:end!important}.is-align-content-baseline{align-content:baseline!important}.is-align-items-stretch{align-items:stretch!important}.is-align-items-flex-start{align-items:flex-start!important}.is-align-items-flex-end{align-items:flex-end!important}.is-align-items-center{align-items:center!important}.is-align-items-baseline{align-items:baseline!important}.is-align-items-start{align-items:start!important}.is-align-items-end{align-items:end!important}.is-align-items-self-start{align-items:self-start!important}.is-align-items-self-end{align-items:self-end!important}.is-align-self-auto{align-self:auto!important}.is-align-self-flex-start{align-self:flex-start!important}.is-align-self-flex-end{align-self:flex-end!important}.is-align-self-center{align-self:center!important}.is-align-self-baseline{align-self:baseline!important}.is-align-self-stretch{align-self:stretch!important}.is-flex-grow-0{flex-grow:0!important}.is-flex-grow-1{flex-grow:1!important}.is-flex-grow-2{flex-grow:2!important}.is-flex-grow-3{flex-grow:3!important}.is-flex-grow-4{flex-grow:4!important}.is-flex-grow-5{flex-grow:5!important}.is-flex-shrink-0{flex-shrink:0!important}.is-flex-shrink-1{flex-shrink:1!important}.is-flex-shrink-2{flex-shrink:2!important}.is-flex-shrink-3{flex-shrink:3!important}.is-flex-shrink-4{flex-shrink:4!important}.is-flex-shrink-5{flex-shrink:5!important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left!important}.is-pulled-right{float:right!important}.is-radiusless{border-radius:0!important}.is-shadowless{box-shadow:none!important}.is-clickable{cursor:pointer!important;pointer-events:all!important}.is-clipped{overflow:hidden!important}.is-relative{position:relative!important}.is-marginless{margin:0!important}.is-paddingless{padding:0!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:.25rem!important}.mt-1{margin-top:.25rem!important}.mr-1{margin-right:.25rem!important}.mb-1{margin-bottom:.25rem!important}.ml-1{margin-left:.25rem!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-2{margin:.5rem!important}.mt-2{margin-top:.5rem!important}.mr-2{margin-right:.5rem!important}.mb-2{margin-bottom:.5rem!important}.ml-2{margin-left:.5rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-3{margin:.75rem!important}.mt-3{margin-top:.75rem!important}.mr-3{margin-right:.75rem!important}.mb-3{margin-bottom:.75rem!important}.ml-3{margin-left:.75rem!important}.mx-3{margin-left:.75rem!important;margin-right:.75rem!important}.my-3{margin-top:.75rem!important;margin-bottom:.75rem!important}.m-4{margin:1rem!important}.mt-4{margin-top:1rem!important}.mr-4{margin-right:1rem!important}.mb-4{margin-bottom:1rem!important}.ml-4{margin-left:1rem!important}.mx-4{margin-left:1rem!important;margin-right:1rem!important}.my-4{margin-top:1rem!important;margin-bottom:1rem!important}.m-5{margin:1.5rem!important}.mt-5{margin-top:1.5rem!important}.mr-5{margin-right:1.5rem!important}.mb-5{margin-bottom:1.5rem!important}.ml-5{margin-left:1.5rem!important}.mx-5{margin-left:1.5rem!important;margin-right:1.5rem!important}.my-5{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-6{margin:3rem!important}.mt-6{margin-top:3rem!important}.mr-6{margin-right:3rem!important}.mb-6{margin-bottom:3rem!important}.ml-6{margin-left:3rem!important}.mx-6{margin-left:3rem!important;margin-right:3rem!important}.my-6{margin-top:3rem!important;margin-bottom:3rem!important}.m-auto{margin:auto!important}.mt-auto{margin-top:auto!important}.mr-auto{margin-right:auto!important}.mb-auto{margin-bottom:auto!important}.ml-auto{margin-left:auto!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:.25rem!important}.pt-1{padding-top:.25rem!important}.pr-1{padding-right:.25rem!important}.pb-1{padding-bottom:.25rem!important}.pl-1{padding-left:.25rem!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-2{padding:.5rem!important}.pt-2{padding-top:.5rem!important}.pr-2{padding-right:.5rem!important}.pb-2{padding-bottom:.5rem!important}.pl-2{padding-left:.5rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-3{padding:.75rem!important}.pt-3{padding-top:.75rem!important}.pr-3{padding-right:.75rem!important}.pb-3{padding-bottom:.75rem!important}.pl-3{padding-left:.75rem!important}.px-3{padding-left:.75rem!important;padding-right:.75rem!important}.py-3{padding-top:.75rem!important;padding-bottom:.75rem!important}.p-4{padding:1rem!important}.pt-4{padding-top:1rem!important}.pr-4{padding-right:1rem!important}.pb-4{padding-bottom:1rem!important}.pl-4{padding-left:1rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.p-5{padding:1.5rem!important}.pt-5{padding-top:1.5rem!important}.pr-5{padding-right:1.5rem!important}.pb-5{padding-bottom:1.5rem!important}.pl-5{padding-left:1.5rem!important}.px-5{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-5{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-6{padding:3rem!important}.pt-6{padding-top:3rem!important}.pr-6{padding-right:3rem!important}.pb-6{padding-bottom:3rem!important}.pl-6{padding-left:3rem!important}.px-6{padding-left:3rem!important;padding-right:3rem!important}.py-6{padding-top:3rem!important;padding-bottom:3rem!important}.p-auto{padding:auto!important}.pt-auto{padding-top:auto!important}.pr-auto{padding-right:auto!important}.pb-auto{padding-bottom:auto!important}.pl-auto{padding-left:auto!important}.px-auto{padding-left:auto!important;padding-right:auto!important}.py-auto{padding-top:auto!important;padding-bottom:auto!important}.is-size-1{font-size:3rem!important}.is-size-2{font-size:2.5rem!important}.is-size-3{font-size:2rem!important}.is-size-4{font-size:1.5rem!important}.is-size-5{font-size:1.25rem!important}.is-size-6{font-size:1rem!important}.is-size-7{font-size:.75rem!important}@media screen and (max-width:768px){.is-size-1-mobile{font-size:3rem!important}.is-size-2-mobile{font-size:2.5rem!important}.is-size-3-mobile{font-size:2rem!important}.is-size-4-mobile{font-size:1.5rem!important}.is-size-5-mobile{font-size:1.25rem!important}.is-size-6-mobile{font-size:1rem!important}.is-size-7-mobile{font-size:.75rem!important}}@media screen and (min-width:769px),print{.is-size-1-tablet{font-size:3rem!important}.is-size-2-tablet{font-size:2.5rem!important}.is-size-3-tablet{font-size:2rem!important}.is-size-4-tablet{font-size:1.5rem!important}.is-size-5-tablet{font-size:1.25rem!important}.is-size-6-tablet{font-size:1rem!important}.is-size-7-tablet{font-size:.75rem!important}}@media screen and (max-width:1023px){.is-size-1-touch{font-size:3rem!important}.is-size-2-touch{font-size:2.5rem!important}.is-size-3-touch{font-size:2rem!important}.is-size-4-touch{font-size:1.5rem!important}.is-size-5-touch{font-size:1.25rem!important}.is-size-6-touch{font-size:1rem!important}.is-size-7-touch{font-size:.75rem!important}}@media screen and (min-width:1024px){.is-size-1-desktop{font-size:3rem!important}.is-size-2-desktop{font-size:2.5rem!important}.is-size-3-desktop{font-size:2rem!important}.is-size-4-desktop{font-size:1.5rem!important}.is-size-5-desktop{font-size:1.25rem!important}.is-size-6-desktop{font-size:1rem!important}.is-size-7-desktop{font-size:.75rem!important}}@media screen and (min-width:1216px){.is-size-1-widescreen{font-size:3rem!important}.is-size-2-widescreen{font-size:2.5rem!important}.is-size-3-widescreen{font-size:2rem!important}.is-size-4-widescreen{font-size:1.5rem!important}.is-size-5-widescreen{font-size:1.25rem!important}.is-size-6-widescreen{font-size:1rem!important}.is-size-7-widescreen{font-size:.75rem!important}}@media screen and (min-width:1408px){.is-size-1-fullhd{font-size:3rem!important}.is-size-2-fullhd{font-size:2.5rem!important}.is-size-3-fullhd{font-size:2rem!important}.is-size-4-fullhd{font-size:1.5rem!important}.is-size-5-fullhd{font-size:1.25rem!important}.is-size-6-fullhd{font-size:1rem!important}.is-size-7-fullhd{font-size:.75rem!important}}.has-text-centered{text-align:center!important}.has-text-justified{text-align:justify!important}.has-text-left{text-align:left!important}.has-text-right{text-align:right!important}@media screen and (max-width:768px){.has-text-centered-mobile{text-align:center!important}}@media screen and (min-width:769px),print{.has-text-centered-tablet{text-align:center!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1023px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1024px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-centered-desktop-only{text-align:center!important}}@media screen and (min-width:1216px){.has-text-centered-widescreen{text-align:center!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-centered-widescreen-only{text-align:center!important}}@media screen and (min-width:1408px){.has-text-centered-fullhd{text-align:center!important}}@media screen and (max-width:768px){.has-text-justified-mobile{text-align:justify!important}}@media screen and (min-width:769px),print{.has-text-justified-tablet{text-align:justify!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1023px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1024px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-justified-desktop-only{text-align:justify!important}}@media screen and (min-width:1216px){.has-text-justified-widescreen{text-align:justify!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-justified-widescreen-only{text-align:justify!important}}@media screen and (min-width:1408px){.has-text-justified-fullhd{text-align:justify!important}}@media screen and (max-width:768px){.has-text-left-mobile{text-align:left!important}}@media screen and (min-width:769px),print{.has-text-left-tablet{text-align:left!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1023px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1024px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-left-desktop-only{text-align:left!important}}@media screen and (min-width:1216px){.has-text-left-widescreen{text-align:left!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-left-widescreen-only{text-align:left!important}}@media screen and (min-width:1408px){.has-text-left-fullhd{text-align:left!important}}@media screen and (max-width:768px){.has-text-right-mobile{text-align:right!important}}@media screen and (min-width:769px),print{.has-text-right-tablet{text-align:right!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1023px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1024px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-right-desktop-only{text-align:right!important}}@media screen and (min-width:1216px){.has-text-right-widescreen{text-align:right!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-right-widescreen-only{text-align:right!important}}@media screen and (min-width:1408px){.has-text-right-fullhd{text-align:right!important}}.is-capitalized{text-transform:capitalize!important}.is-lowercase{text-transform:lowercase!important}.is-uppercase{text-transform:uppercase!important}.is-italic{font-style:italic!important}.is-underlined{text-decoration:underline!important}.has-text-weight-light{font-weight:300!important}.has-text-weight-normal{font-weight:400!important}.has-text-weight-medium{font-weight:500!important}.has-text-weight-semibold{font-weight:600!important}.has-text-weight-bold{font-weight:700!important}.is-family-primary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family:monospace!important}.is-block{display:block!important}@media screen and (max-width:768px){.is-block-mobile{display:block!important}}@media screen and (min-width:769px),print{.is-block-tablet{display:block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1023px){.is-block-touch{display:block!important}}@media screen and (min-width:1024px){.is-block-desktop{display:block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-block-desktop-only{display:block!important}}@media screen and (min-width:1216px){.is-block-widescreen{display:block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-block-widescreen-only{display:block!important}}@media screen and (min-width:1408px){.is-block-fullhd{display:block!important}}.is-flex{display:flex!important}@media screen and (max-width:768px){.is-flex-mobile{display:flex!important}}@media screen and (min-width:769px),print{.is-flex-tablet{display:flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1023px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1024px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-flex-desktop-only{display:flex!important}}@media screen and (min-width:1216px){.is-flex-widescreen{display:flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-flex-widescreen-only{display:flex!important}}@media screen and (min-width:1408px){.is-flex-fullhd{display:flex!important}}.is-inline{display:inline!important}@media screen and (max-width:768px){.is-inline-mobile{display:inline!important}}@media screen and (min-width:769px),print{.is-inline-tablet{display:inline!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1023px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1024px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-desktop-only{display:inline!important}}@media screen and (min-width:1216px){.is-inline-widescreen{display:inline!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-widescreen-only{display:inline!important}}@media screen and (min-width:1408px){.is-inline-fullhd{display:inline!important}}.is-inline-block{display:inline-block!important}@media screen and (max-width:768px){.is-inline-block-mobile{display:inline-block!important}}@media screen and (min-width:769px),print{.is-inline-block-tablet{display:inline-block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1023px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1024px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-block-desktop-only{display:inline-block!important}}@media screen and (min-width:1216px){.is-inline-block-widescreen{display:inline-block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-block-widescreen-only{display:inline-block!important}}@media screen and (min-width:1408px){.is-inline-block-fullhd{display:inline-block!important}}.is-inline-flex{display:inline-flex!important}@media screen and (max-width:768px){.is-inline-flex-mobile{display:inline-flex!important}}@media screen and (min-width:769px),print{.is-inline-flex-tablet{display:inline-flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1023px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1024px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-flex-desktop-only{display:inline-flex!important}}@media screen and (min-width:1216px){.is-inline-flex-widescreen{display:inline-flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-flex-widescreen-only{display:inline-flex!important}}@media screen and (min-width:1408px){.is-inline-flex-fullhd{display:inline-flex!important}}.is-hidden{display:none!important}.is-sr-only{border:none!important;clip:rect(0,0,0,0)!important;height:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.01em!important}@media screen and (max-width:768px){.is-hidden-mobile{display:none!important}}@media screen and (min-width:769px),print{.is-hidden-tablet{display:none!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1023px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1024px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-hidden-desktop-only{display:none!important}}@media screen and (min-width:1216px){.is-hidden-widescreen{display:none!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-hidden-widescreen-only{display:none!important}}@media screen and (min-width:1408px){.is-hidden-fullhd{display:none!important}}.is-invisible{visibility:hidden!important}@media screen and (max-width:768px){.is-invisible-mobile{visibility:hidden!important}}@media screen and (min-width:769px),print{.is-invisible-tablet{visibility:hidden!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1023px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1024px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-invisible-desktop-only{visibility:hidden!important}}@media screen and (min-width:1216px){.is-invisible-widescreen{visibility:hidden!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-invisible-widescreen-only{visibility:hidden!important}}@media screen and (min-width:1408px){.is-invisible-fullhd{visibility:hidden!important}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1023px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{color:#fff!important;opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{color:#0a0a0a!important;opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}@media screen and (max-width:768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,.7)}.hero.is-light .subtitle{color:rgba(0,0,0,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.hero.is-light .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5!important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}}.hero.is-dark{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#fff}.hero.is-dark .subtitle{color:rgba(255,255,255,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(255,255,255,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#fff}.hero.is-dark .tabs a{color:#fff;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{color:#363636!important;opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}@media screen and (max-width:768px){.hero.is-dark.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{color:#00d1b2!important;opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#485fc7;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-link .navbar-menu{background-color:#485fc7}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#3a51bb;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{color:#485fc7!important;opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#485fc7}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#2959b3 0,#485fc7 71%,#5658d2 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#2959b3 0,#485fc7 71%,#5658d2 100%)}}.hero.is-info{background-color:#3e8ed0;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-info .navbar-menu{background-color:#3e8ed0}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#3082c5;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{color:#3e8ed0!important;opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3e8ed0}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#208fbc 0,#3e8ed0 71%,#4d83db 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#208fbc 0,#3e8ed0 71%,#4d83db 100%)}}.hero.is-success{background-color:#48c78e;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-success .navbar-menu{background-color:#48c78e}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#3abb81;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{color:#48c78e!important;opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#48c78e}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#29b35e 0,#48c78e 71%,#56d2af 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#29b35e 0,#48c78e 71%,#56d2af 100%)}}.hero.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-warning .navbar-menu{background-color:#ffe08a}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#ffe08a!important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#ffe08a}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffb657 0,#ffe08a 71%,#fff6a3 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffb657 0,#ffe08a 71%,#fff6a3 100%)}}.hero.is-danger{background-color:#f14668;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-danger .navbar-menu{background-color:#f14668}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ef2e55;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{color:#f14668!important;opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#f14668}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}}.hero.is-small .hero-body{padding:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%,-50%,0)}.hero-video.is-transparent{opacity:.3}@media screen and (max-width:768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width:768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:.75rem}}@media screen and (min-width:769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width:769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem} \ No newline at end of file diff --git a/mc_openapi/assets/templates/base.html b/mc_openapi/assets/templates/base.html new file mode 100644 index 0000000000000000000000000000000000000000..0f74a00ba295bc47d253b1ca5cc8855a0e60f334 --- /dev/null +++ b/mc_openapi/assets/templates/base.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>DOML Model Checker</title> + <link href="{{ url_for('static', path='/bulma.min.css') }}" rel="stylesheet"> +</head> + +<body> + <section class="section"> + <div class="container"> + {% block content %} + {% endblock %} + </div> + </section> +</body> + +</html> \ No newline at end of file diff --git a/mc_openapi/assets/templates/csp.html b/mc_openapi/assets/templates/csp.html new file mode 100644 index 0000000000000000000000000000000000000000..441abc63e7886e1d3197759005162b4eea8dfe83 --- /dev/null +++ b/mc_openapi/assets/templates/csp.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block content %} +{% include "csp_content.html" %} +{% endblock content %} \ No newline at end of file diff --git a/mc_openapi/assets/templates/csp_content.html b/mc_openapi/assets/templates/csp_content.html new file mode 100644 index 0000000000000000000000000000000000000000..06d643f9b43a2eb9761fef5878c585f66a248643 --- /dev/null +++ b/mc_openapi/assets/templates/csp_content.html @@ -0,0 +1,98 @@ +<h1 class="title">CSP Compatibility Results</h1> +{# FIX IMPORTS FOR MC #} +{% if csp %} +{% set keypairs = csp.keypairs %} +{% set os = csp.os %} +{% set arch = csp.arch %} +{% set minreq = csp.minreq %} +{% endif %} + +<div class="box"> + {% if keypairs %} + <h2 class="title is-4">Keypairs</h2> + <div class="table-container"> + <table class="table is-bordered is-striped is-hoverable"> + {% for row in keypairs %} + {% set outer_loop = loop %} + <tr> + {% for column in row %} + {% if outer_loop.first or loop.first %} + <th>{{ column }}</th> + {% else %} + <td>{{ column }}</td> + {% endif %} + {% endfor %} + </tr> + {% endfor %} + </table> + </div> + {% endif %} + + {% if os %} + <h2 class="title is-4">OS</h2> + <div class="table-container"> + <table class="table is-bordered is-striped is-hoverable"> + {% for row in os %} + {% set outer_loop = loop %} + <tr> + {% for column in row %} + {% if outer_loop.first or loop.first %} + <th>{{ column }}</th> + {% else %} + <td>{{ column }}</td> + {% endif %} + {% endfor %} + </tr> + {% endfor %} + </table> + </div> + {% endif %} + + {% if arch %} + <h2 class="title is-4">Architectures</h2> + <div class="table-container"> + <table class="table is-bordered is-striped is-hoverable"> + {% for row in arch %} + {% set outer_loop = loop %} + <tr> + {% for column in row %} + {% if outer_loop.first or loop.first %} + <th>{{ column }}</th> + {% else %} + <td>{{ column }}</td> + {% endif %} + {% endfor %} + </tr> + {% endfor %} + </table> + </div> + {% endif %} + + {% if minreq %} + <h2 class="title is-4">Minimum Requirements</h2> + <div class="table-container"> + <table class="table is-bordered is-striped is-hoverable"> + {% for row in minreq %} + {% set outer_loop = loop %} + <tr> + {% for column in row %} + {% if outer_loop.first or loop.first %} + <th>{{ column }}</th> + {% else %} + <td> + <ul> + {% for item in column %} + <li> + {{ item }} + </li> + {% endfor %} + </ul> + </td> + {% endif %} + {% endfor %} + </tr> + {% endfor %} + </table> + </div> +</div> +{% endif %} \ No newline at end of file diff --git a/mc_openapi/assets/templates/error.html b/mc_openapi/assets/templates/error.html new file mode 100644 index 0000000000000000000000000000000000000000..bf76d60a5de0392e59b0f24b2803eae5acbcc525 --- /dev/null +++ b/mc_openapi/assets/templates/error.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block content %} + +<h1 class="title">Error</h1> +<div class="message is-danger"> + <div class="message-header"> + <p> + An error occurred while validating the DOML + </p> + </div> + <div class="message-body"> + <h2 class="title is-6 my-2">Description</h2> + <pre class="is-family-monospace message-body">{{message}}</pre> + <details> + <summary class="title is-6 my-2">Debug Message</summary> + <pre class="is-family-monospace message-body"> + {{debug_message}} + </pre> + </details> + </div> +</div> + +{% endblock content %} \ No newline at end of file diff --git a/mc_openapi/assets/templates/home.html b/mc_openapi/assets/templates/home.html new file mode 100644 index 0000000000000000000000000000000000000000..10944849bebc3a32dd9d7d1d04549e14dd04ca6a --- /dev/null +++ b/mc_openapi/assets/templates/home.html @@ -0,0 +1,92 @@ +{% extends "base.html" %} + +{% block content %} +<div class="box"> + <h1 class="title">DOML Model Checker</h1> + <p>Upload a DOMLX file (in PIACERE IDE, <i>Right click > PIACERE > Generate DOMLX</i>) to either validate it with + the + model checker or the CSP compatibility tool.</p> + <br> + <div class="columns"> + <div class="column"> + <h2 class="subtitle">Model Checker</h2> + <div class="file is-boxed"> + <label class="file-label"> + <input class="file-input" type="file" name="resume" id="domlx-mc"> + <span class="file-cta"> + <span class="file-label"> + Choose a file to validate + </span> + </span> + </label> + </div> + </div> + <div class="column"> + <h2 class="subtitle">CSP Compatibility</h2> + <div class="file is-boxed"> + <label class="file-label"> + <input class="file-input" type="file" name="resume" id="domlx-csp"> + <span class="file-cta"> + <span class="file-label"> + Choose a file to validate + </span> + </span> + </label> + </div> + </div> + </div> + <progress id="loading" class="is-hidden progress is-small is-primary" max="100">Loading...</progress> + <div id="error" class="notification is-danger is-hidden"> + There was an issue with the file you uploaded. Is it a DOMLX file? + <br> + DOML files are not supported! + </div> +</div> +<script> + const input_csp = document.querySelector("#domlx-csp") + input_csp.addEventListener('change', readFileCSP, false) + + const input_mc = document.querySelector("#domlx-mc") + input_mc.addEventListener('change', readFileMC, false) + + const loadingBar = document.querySelector("#loading") + const errorBox = document.querySelector("#error") + + async function readFile(event, url) { + const file = event.target.files[0] + if (file) { + loadingBar.classList.remove("is-hidden") + const res = await fetch(url, { + method: 'POST', + headers: { + "Content-Type": "application/xml", + }, + redirect: "follow", + body: await file.text() + }) + if (res.status === 200) { + newHtml = await res.text() + // Fix escaped quotes for tags + // Unescape emojis + // See: https://stackoverflow.com/questions/51640509/ + newHtml = newHtml.replace(/\\u[\dA-F]{4}/gi, function (match) { + return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16)); + }) + // Remove trailing and heading " + document.write(newHtml) + } else { + loadingBar.classList.add("is-hidden") + errorBox.classList.remove("is-hidden") + } + } + } + + async function readFileCSP(event) { + readFile(event, '/csp_html') + } + + async function readFileMC(event) { + readFile(event, '/modelcheck_html') + } +</script> +{% endblock content %} \ No newline at end of file diff --git a/mc_openapi/assets/templates/mc.html b/mc_openapi/assets/templates/mc.html new file mode 100644 index 0000000000000000000000000000000000000000..019b39595d705c827852170d4a4f68012bb7c913 --- /dev/null +++ b/mc_openapi/assets/templates/mc.html @@ -0,0 +1,120 @@ +{% extends "base.html" %} + +{% block content %} +<h1 class="title">DOML Model Checker Results + <span class="tags has-addons"> + <span class="tag is-dark">DOML Version</span> + <span class="tag is-info">{{doml_version}}</span> + </span> +</h1> +<div class="box"> + <h2 class="title is-4">Result: + {% if result == "sat" %} + <span class="tag is-success is-medium">Satisfied</span> + {% else %} + <span class="tag is-danger is-medium">Unsatisfied</span> + {% endif %} + </h2> + <div class="control"> + <p>Model validated in {{elapsed_time}}s.</p> + </div> + {% if all_reqs %} + <label class="checkbox my-4"> + <input type="checkbox" id="show-sat-reqs"> + Show satisfied requirements + </label> + <ul class=""> + {% for req in all_reqs %} + {% if req.result == "unsat" %} + <li class="message is-danger"> + <div class="message-header"> + <p> + Unsatisfied ({{req.time}}s) + </p> + <p> + <span class="tag is-family-monospace is-danger is-light"> + {{req.id}} + </span> + <span class="tag is-danger is-light">{{req.type}}</span> + </p> + </div> + <div class="message-body"> + <h2 class="title is-6 my-2">Description</h2> + <p>{{req.description}}</p> + <h2 class="title is-6 my-2">Error message:</h2> + <p>{{req.message}}</p> + </div> + </li> + {% else %} + <li class="message is-success sat-req is-hidden"> + <div class="message-header"> + <p> + <span class="tag is-family-monospace is-success is-light"> + {{req.id}} + </span> + <span class="tag is-success is-light">{{req.type}}</span> + </p> + <p> + satisfied ({{req.time}}s) + </p> + </div> + <div class="message-body"> + <h2 class="title is-6 my-2">Description</h2> + <p>{{req.description}}</p> + </div> + </li> + {% endif %} + {% endfor %} + </ul> + {% endif %} + + {% if user %} + <h3 class="title is-5">User Requirements</h3> + <ul class=""> + {% for req in user %} + <li class=""> + <h4>{{req[0]}}</h4> + <p>{{req[1]}}</p> + <ul class="notes"> + {% for note in req[2] %} + <li>{{note}}</li> + {% endfor %} + </ul> + </li> + {% endfor %} + </ul> + {% endif %} + + {% if dontknow %} + <article class="message is-warning"> + <div class="message-header"> + <p>Timeout!</p> + </div> + <div class="message-body"> + There's been a timeout during the validation, so some requirements couldn't be verified.<br> + This is not the expected behaviour unless you are using custom requirements or/and very large DOML + models.<br> + Please report the issue if possible! + </div> + </article> + {% endif %} + + {% if net_validation %} + {% include "net.html" %} + {% else %} + <h3 class="title is-5">Network Validation</h3> + No issue detected within the model network configuration. + {% endif %} +</div> +<script> + const checkbox = document.querySelector("#show-sat-reqs") + const satReqs = document.querySelectorAll(".sat-req") + + checkbox.addEventListener("click", () => { + satReqs.forEach(el => el.classList.toggle('is-hidden')) + }) +</script> +{% if csp %} +{% include "csp_content.html" %} +{% endif %} +{% endblock content %} \ No newline at end of file diff --git a/mc_openapi/assets/templates/net.html b/mc_openapi/assets/templates/net.html new file mode 100644 index 0000000000000000000000000000000000000000..ec8371c861bbd7baae79b25d5d6b707c50e18ab8 --- /dev/null +++ b/mc_openapi/assets/templates/net.html @@ -0,0 +1,10 @@ +<h3 class="title is-5">Network Validation</h3> +<ul> + {% for warn in net_validation %} + <li class="message"> + <div class="message-body"> + {{warn}} + </div> + </li> + {% endfor %} +</ul> \ No newline at end of file diff --git a/mc_openapi/doml_mc/__init__.py b/mc_openapi/doml_mc/__init__.py index 4bbe1a24dc55d99980d2661e0bcb47d1a011803a..62db218186b30bcc40496d93a14a162c71df83dc 100644 --- a/mc_openapi/doml_mc/__init__.py +++ b/mc_openapi/doml_mc/__init__.py @@ -1,5 +1,17 @@ from .mc import ModelChecker # noqa: F401 from .mc_result import MCResult, MCResults # noqa: F401 +from .intermediate_model.metamodel import DOMLVersion, init_metamodels # noqa: F401 +from .xmi_parser.doml_model import init_doml_rsets +from .xmi_parser.special_parsers import init_special_parsers +from .main import init_model, verify_csp_compatibility, verify_model, synthesize_model -# Load metamodel -ModelChecker.init_metamodel() +__all__ = ["ModelChecker", "MCResult", "MCResults", "DOMLVersion"] + +# Load metamodels +init_metamodels() + +# Load ecores +init_doml_rsets() + +# Generate SpecialParsers +init_special_parsers() diff --git a/mc_openapi/doml_mc/builtin_requirements/__init__.py b/mc_openapi/doml_mc/builtin_requirements/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3f67bf2dc0630730dc6f61f2c9b6f0698f7025ef --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/__init__.py @@ -0,0 +1,43 @@ +CELEMS_V2_0 = [ + ("infrastructure_VirtualMachine", "concrete_RuntimeProvider::vms", "concrete_VirtualMachine::maps"), + ("infrastructure_VMImage", "concrete_RuntimeProvider::vmImages", "concrete_VMImage::maps"), + ("infrastructure_Network", "concrete_RuntimeProvider::networks", "concrete_Network::maps"), + ("infrastructure_Storage", "concrete_RuntimeProvider::storages", "concrete_Storage::maps"), + ("infrastructure_FunctionAsAService", "concrete_RuntimeProvider::faas","concrete_FunctionAsAService::maps"), + ("infrastructure_ComputingGroup", "concrete_RuntimeProvider::group","concrete_ComputingGroup::maps"), +] + +CELEMS_V3_1 = [ + *CELEMS_V2_0[0:5], + ("infrastructure_ComputingGroup", "concrete_RuntimeProvider::autoScalingGroups","concrete_AutoScalingGroup::maps") +] + +from .vm_has_iface import VM_HAS_IFACE, VM_HAS_IFACE_V2_3 +from .software_package_iface_net import SOFTWARE_PACKAGE_IFACE_NET, SOFTWARE_PACKAGE_IFACE_NET_V2_1, SOFTWARE_PACKAGE_IFACE_NET_V2_3, SOFTWARE_PACKAGE_IFACE_NET_V3_1 +from .iface_uniq import IFACE_UNIQ +from .all_software_components_deployed import ALL_SOFTWARE_COMPONENTS_DEPLOYED +from .all_infrastructure_elements_deployed import ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1 +from .all_concrete_maps_something import ALL_CONCRETE_MAP_SOMETHING, ALL_CONCRETE_MAP_SOMETHING_V3_1 +from .security_group_must_have_iface import SECURITY_GROUP_MUST_HAVE_IFACE, SECURITY_GROUP_MUST_HAVE_IFACE_V3_1 +from .concrete_asg_no_vm import CONCRETE_ASG_NO_VM +from .vm_os_required import VM_OS_REQUIRED, VM_OS_REQUIRED_V3_1 + +__ALL__ = [ + VM_HAS_IFACE, + VM_HAS_IFACE_V2_3, + SOFTWARE_PACKAGE_IFACE_NET, + SOFTWARE_PACKAGE_IFACE_NET_V2_1, + SOFTWARE_PACKAGE_IFACE_NET_V2_3, + SOFTWARE_PACKAGE_IFACE_NET_V3_1, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1, + ALL_CONCRETE_MAP_SOMETHING, + ALL_CONCRETE_MAP_SOMETHING_V3_1, + SECURITY_GROUP_MUST_HAVE_IFACE, + SECURITY_GROUP_MUST_HAVE_IFACE_V3_1, + CONCRETE_ASG_NO_VM, + VM_OS_REQUIRED, + VM_OS_REQUIRED_V3_1 +] \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py b/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py new file mode 100644 index 0000000000000000000000000000000000000000..01e2f1e7ce243a895b3ef48369ccfc4975c5ce8b --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py @@ -0,0 +1,98 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name +from . import CELEMS_V2_0, CELEMS_V3_1 + +# All elements in the active concretization are mapped to some abstract infrastructure element. + +def all_concrete_map_something(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + def checkOneClass(ielem, provider, celem, providerAssoc, celemAssoc): + return And( + smtenc.association_rel( + provider, smtenc.associations[providerAssoc], celem), + Not( + Exists( + [ielem], + smtenc.association_rel( + celem, smtenc.associations[celemAssoc], ielem) + ) + ) + ) + + ielem, concr, provider, celem = Consts( + "ielem concr provider celem", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + concr) == smtenc.classes["concrete_ConcreteInfrastructure"], + smtenc.association_rel( + concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + Or( + *( + checkOneClass( + ielem, provider, celem, + providerAssoc, celemAssoc + ) + for _, providerAssoc, celemAssoc in CELEMS_V2_0 + ) + ) + ) + +def all_concrete_map_something_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + def checkOneClass(ielem, provider, celem, providerAssoc, celemAssoc): + return And( + smtenc.association_rel( + provider, smtenc.associations[providerAssoc], celem), + Not( + Exists( + [ielem], + smtenc.association_rel( + celem, smtenc.associations[celemAssoc], ielem) + ) + ) + ) + + ielem, concr, provider, celem = Consts( + "ielem concr provider celem", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + concr) == smtenc.classes["concrete_ConcreteInfrastructure"], + smtenc.association_rel( + concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + Or( + *( + checkOneClass( + ielem, provider, celem, + providerAssoc, celemAssoc + ) + for _, providerAssoc, celemAssoc in CELEMS_V3_1 + ) + ) + ) + + +def ed_all_concrete_map_something(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + celem = Const("celem", smtsorts.element_sort) + celem_name = get_user_friendly_name( + intermediate_model, solver.model(), celem) + if celem_name: + return f"Concrete infrastructure element '{celem_name}' is not mapped to any abstract infrastructure element." + except: + return "A concrete infrastructure element is not mapped to any abstract infrastructure element." + +MSG = "All elements in the active concretization are mapped to some abstract infrastructure element." + +ALL_CONCRETE_MAP_SOMETHING = ( + all_concrete_map_something, + "all_concrete_map_something", + MSG, + ed_all_concrete_map_something +) + +ALL_CONCRETE_MAP_SOMETHING_V3_1 = ( + all_concrete_map_something_v3_1, + "all_concrete_map_something", + MSG, + ed_all_concrete_map_something +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py b/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py new file mode 100644 index 0000000000000000000000000000000000000000..7e4b4e300caa546a06f9f110de3f34af7d0e8a27 --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py @@ -0,0 +1,167 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name +from . import CELEMS_V2_0, CELEMS_V3_1 + +# Provider > elements generated by IOP only have "commons_DOMLElement::annotations" as an association +# and do not have maps. Also networks are not generated by the IOP. But they are the same class +# (concrete_infrastructure), so I can't make distinction. + +def all_infrastructure_elements_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + """Checks: + - infrastructure_VMImage + - infrastructure_Network + - infrastructure_Storage + - infrastructure_FunctionAsAService + - infrastructure_ComputingGroup + """ + def checkOneClass(ielem, cinfr, provider, celem, ielemClass, providerAssoc, celemAssoc): + return And( + smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass], + Not( + Exists( + [provider, celem], + And( + smtenc.association_rel( + cinfr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + smtenc.association_rel( + provider, smtenc.associations[providerAssoc], celem), + smtenc.association_rel( + celem, smtenc.associations[celemAssoc], ielem) + ) + ) + ) + ) + + ielem, concr, provider, celem, asg = Consts("ielem concr provider celem asg", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + concr) == smtenc.classes["concrete_ConcreteInfrastructure"], + Or( + *( + checkOneClass( + ielem, concr, provider, celem, + ielemClass, providerAssoc, celemAssoc + ) + for ielemClass, providerAssoc, celemAssoc in CELEMS_V2_0 + if ielemClass != 'infrastructure_VirtualMachine' # handle special case separately in concrete_asg_no_vm and below + ), + And( + smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"], + Not(Exists([asg], + Or( + smtenc.association_rel( + asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem), + Exists( + [provider, celem], + And( + smtenc.association_rel( + concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + smtenc.association_rel( + provider, smtenc.associations["concrete_RuntimeProvider::vms"], celem), + smtenc.association_rel( + celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem) + ) + ) + ) + )) + ) + ) + ) + +def all_infrastructure_elements_deployed_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + def checkOneClass(ielem, cinfr, provider, celem, ielemClass, providerAssoc, celemAssoc): + return And( + smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass], + Not( + Exists( + [provider, celem], + And( + smtenc.association_rel( + cinfr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + smtenc.association_rel( + provider, smtenc.associations[providerAssoc], celem), + smtenc.association_rel( + celem, smtenc.associations[celemAssoc], ielem) + ) + ) + ) + ) + + ielem, concr, provider, celem, net, asg = Consts("ielem concr provider celem net asg", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + concr) == smtenc.classes["concrete_ConcreteInfrastructure"], + Or( + *( + checkOneClass( + ielem, concr, provider, celem, + ielemClass, providerAssoc, celemAssoc + ) + for ielemClass, providerAssoc, celemAssoc in CELEMS_V3_1 + if ielemClass != 'infrastructure_VirtualMachine' # handle special case separately in concrete_asg_no_vm and below + ), + And( + smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"], + Not(Exists([asg], + Or( + smtenc.association_rel( + asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem), + Exists( + [provider, celem], + And( + smtenc.association_rel( + concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + smtenc.association_rel( + provider, smtenc.associations["concrete_RuntimeProvider::vms"], celem), + smtenc.association_rel( + celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem) + ) + ) + ) + )) + ), + And( + smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_Subnet"], + Not(Exists([provider, net, celem], + And( + smtenc.association_rel( + concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), + smtenc.association_rel( + provider, smtenc.associations["concrete_RuntimeProvider::networks"], net), + smtenc.association_rel( + net, smtenc.associations["concrete_Network::subnets"], celem), + smtenc.association_rel( + celem, smtenc.associations["concrete_Network::maps"], ielem) + ) + )) + ) + ) + ) + +def ed_all_infrastructure_elements_deployed(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + ielem = Const("ielem", smtsorts.element_sort) + ielem_name = get_user_friendly_name( + intermediate_model, solver.model(), ielem) + if ielem_name: + return f"Abstract infrastructure element '{ielem_name}' is not mapped to any element in the active concretization." + except: + return "An abstract infrastructure element has is not mapped to any element in the active concretization." + +MSG = "All abstract infrastructure elements are mapped to an element in the active concretization." + +ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED = ( + all_infrastructure_elements_deployed, + "all_infrastructure_elements_deployed", + MSG, + ed_all_infrastructure_elements_deployed +) + +ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1 = ( + all_infrastructure_elements_deployed_v3_1, + "all_infrastructure_elements_deployed", + MSG, + ed_all_infrastructure_elements_deployed +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py b/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py new file mode 100644 index 0000000000000000000000000000000000000000..a10d5025a6df3aa63107bf6393f107e8670b4813 --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py @@ -0,0 +1,43 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + +# All software components have been deployed to some node. + +def all_software_components_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + sc, deployment, ielem = Consts("sc deployment ielem", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + sc) == smtenc.classes["application_SoftwareComponent"], + Not( + Exists( + [deployment, ielem], + And( + smtenc.association_rel( + deployment, smtenc.associations["commons_Deployment::component"], sc), + smtenc.association_rel( + deployment, smtenc.associations["commons_Deployment::node"], ielem), + ) + ) + ) + ) + +def ed_all_software_components_deployed(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + sc = Const("sc", smtsorts.element_sort) + sc_name = get_user_friendly_name( + intermediate_model, solver.model(), sc) + if sc_name: + return f"Software component '{sc_name}' is not deployed to any abstract infrastructure node." + except: + return "A software component is not deployed to any abstract infrastructure node." + +MSG = "All software components have been deployed to some node." + +ALL_SOFTWARE_COMPONENTS_DEPLOYED = ( + all_software_components_deployed, + "all_software_components_deployed", + MSG, + ed_all_software_components_deployed +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py b/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py new file mode 100644 index 0000000000000000000000000000000000000000..445e8e9d13c3fb98fc73bf54acf022f763f6c16e --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py @@ -0,0 +1,43 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + +def concrete_asg_no_vm(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + ielem, concr, provider, celem, asg = Consts("ielem concr provider celem asg", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + concr) == smtenc.classes["concrete_ConcreteInfrastructure"], + # We don't want the following to happen: + # If exists ASG(infr) -> VM(infr), then exists a VM(concr) -> VM(infr) + And( + smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"], + smtenc.association_rel( + asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem), + (Exists( + [celem], + smtenc.association_rel(celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem) + )) + ) + ) + + +def ed_concrete_asg_no_vm(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + ielem = Const("ielem", smtsorts.element_sort) + asg = Const("asg", smtsorts.element_sort) + ielem_name = get_user_friendly_name( + intermediate_model, solver.model(), ielem) + if ielem_name: + return f"Virtual machine '{ielem_name}' in AutoScale Group '{asg}' should not be present in the concretization layer." + except: + return "Any virtual machine in an AutoScale Group should not be present in the concretization layer." + +MSG = "All virtual machines in an autoscale group in the infrastructure layer should not be mapped in the concretization layer." + +CONCRETE_ASG_NO_VM = ( + concrete_asg_no_vm, + "concrete_asg_no_vm", + MSG, + ed_concrete_asg_no_vm +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py b/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py new file mode 100644 index 0000000000000000000000000000000000000000..669c8d0dedaa09b8673db74cd7d21d16bdb7cd62 --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py @@ -0,0 +1,35 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + +# There are no duplicated interfaces. +def iface_uniq(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + endPointAttr = smtenc.attributes["infrastructure_NetworkInterface::endPoint"] + ni1, ni2 = Consts("ni1 ni2", smtsorts.element_sort) + value = Const("value", smtsorts.attr_data_sort) + return And( + smtenc.attribute_rel(ni1, endPointAttr, value), + smtenc.attribute_rel(ni2, endPointAttr, value), + ni1 != ni2, + ) + +def ed_iface_uniq(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + ni1, ni2 = Consts("ni1 ni2", smtsorts.element_sort) + model = solver.model() + ni1_name = get_user_friendly_name(intermediate_model, model, ni1) + ni2_name = get_user_friendly_name(intermediate_model, model, ni2) + if ni1_name and ni2_name: + return f"Network interfaces '{ni1_name}' and '{ni2_name}' share the same IP address." + except: + return "Two network interfaces share the same IP address." + +MSG = "There are no duplicated interfaces." + +IFACE_UNIQ = ( + iface_uniq, + "iface_uniq", + MSG, + ed_iface_uniq +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py b/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py new file mode 100644 index 0000000000000000000000000000000000000000..6e9cbabf07ee335e565146c45d66e5145239f61c --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py @@ -0,0 +1,61 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + +# From DOML V2.3+: +# The association between security groups and network interfaces can now be done only +# in the security groups definition through the “ifaces” keyword (removed the "security" +# keyword in the network interface definition) +def security_group_must_have_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + sg, iface = Consts("sg iface", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + sg) == smtenc.classes["infrastructure_SecurityGroup"], + Not(Exists([iface], + smtenc.association_rel( + iface, smtenc.associations["infrastructure_NetworkInterface::associated"], sg) + )) + ) + +def security_group_must_have_iface_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + sg, elem = Consts("sg elem", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + sg) == smtenc.classes["infrastructure_SecurityGroup"], + Not(Exists([elem], + Or( + smtenc.association_rel( + elem, smtenc.associations["infrastructure_NetworkInterface::associated"], sg), + smtenc.association_rel( + elem, smtenc.associations["infrastructure_ExecutionEnvironment::securityGroups"], sg) + ) + )) + ) + + +def ed_security_group_must_have_iface(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + sg = Const("sg", smtsorts.element_sort) + sg_name = get_user_friendly_name( + intermediate_model, solver.model(), sg) + if sg_name: + return f"Security group '{sg_name}' is not associated with any network interface. You should probably remove it." + except: + return "A security group is not associated with any element. You should probably remove it." + +MSG = "All security group should be a associated to an element." + +SECURITY_GROUP_MUST_HAVE_IFACE = ( + security_group_must_have_iface, + "security_group_must_have_iface", + MSG, + ed_security_group_must_have_iface +) + +SECURITY_GROUP_MUST_HAVE_IFACE_V3_1 = ( + security_group_must_have_iface_v3_1, + "security_group_must_have_iface", + MSG, + ed_security_group_must_have_iface +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py b/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py new file mode 100644 index 0000000000000000000000000000000000000000..e570717bb4833641014f7076d0ae94f2c625ad3b --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py @@ -0,0 +1,710 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + +# All software packages can see the interfaces they need through a common network. + +def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, csubnet, esubnet = Consts( + "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm csubnet esubnet", smtsorts.element_sort + ) + return And( + smtenc.association_rel( + asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface), + smtenc.association_rel( + asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface), + Not( + Or( + Exists( + [cdeployment, cnode, edeployment, enode, net], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Exists( + [vm, net_iface], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::hosts"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + # ASC_EXPLORER > CN > IFACE > NET + smtenc.association_rel( + enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + # ASC_EXPOSER > CONTAINER > CN > IFACE > NET + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::hosts"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + # ASC_EXPLORER > ASG > CN > IFACE > NET + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ) + ) + ), # OR + Exists( + [cdeployment, cnode, edeployment, enode, csubnet, esubnet], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Or( + smtenc.association_rel( + csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet), + smtenc.association_rel( + esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet), + ), + Exists( + [vm, net_iface], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + # ASC_CONSUMER > CN > IFACE > csubnet + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + # ASC_CONSUMER > CONTAINER > CN > IFACE > csubnet + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::hosts"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + # ASC_CONSUMER > ASG > CN > IFACE > csubnet + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + # ASC_EXPOSER > CN > IFACE > esubnet + smtenc.association_rel( + enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + # ASC_EXPOSER > CONTAINER > CN > IFACE > esubnet + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::hosts"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + # ASC_EXPLORER > ASG > CN > IFACE > esubnet + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ) + ) + ) + ) + ) + ) + ) + ) + +def software_package_iface_net_v2_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts( + "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort + ) + return And( + smtenc.association_rel( + asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface), + smtenc.association_rel( + asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface), + Not( + Or( + Exists( + [cdeployment, cnode, edeployment, enode, net], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ) + ) + ), # OR + Exists( + [cdeployment, cnode, edeployment, enode, csubnet, esubnet], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Or( + smtenc.association_rel( + csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet), + smtenc.association_rel( + esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet), + ), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ) + ) + ) + ) + ) + ) + ) + ) + +def software_package_iface_net_v2_3(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts( + "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort + ) + return And( + smtenc.association_rel( + asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface), + smtenc.association_rel( + asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface), + Not( + Or( + Exists( + [cdeployment, cnode, edeployment, enode, net], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ) + ) + ), # OR + Exists( + [cdeployment, cnode, edeployment, enode, csubnet, esubnet], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Or( + smtenc.association_rel( + csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet), + smtenc.association_rel( + esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet), + ), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::configs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ) + ) + ) + ) + ) + ) + ) + ) + +def software_package_iface_net_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts( + "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort + ) + return And( + smtenc.association_rel( + asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface), + smtenc.association_rel( + asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface), + Not( + Or( + Exists( + [cdeployment, cnode, edeployment, enode, net], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), + ), + ) + ) + ) + ), # OR + Exists( + [cdeployment, cnode, edeployment, enode, csubnet, esubnet], + And( + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), + smtenc.association_rel( + cdeployment, smtenc.associations["commons_Deployment::node"], cnode), + Or( + smtenc.association_rel( + csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet), + smtenc.association_rel( + esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet), + ), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_consumer is deployed on a component with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet), + ), + ) + ), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), + smtenc.association_rel( + edeployment, smtenc.associations["commons_Deployment::node"], enode), + Exists( + [vm, net_iface, cconf], + Or( + And( # asc_exposer is deployed on a component with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf), + smtenc.association_rel( + cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ), + And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n + smtenc.association_rel( + enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface), + smtenc.association_rel( + net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet), + ) + ) + ) + ) + ) + ) + ) + ) + + +def ed_software_package_iface_net(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + asc_consumer, asc_exposer, siface = Consts( + "asc_consumer asc_exposer siface", smtsorts.element_sort + ) + model = solver.model() + asc_consumer_name = get_user_friendly_name( + intermediate_model, model, asc_consumer) + asc_exposer_name = get_user_friendly_name( + intermediate_model, model, asc_exposer) + siface_name = get_user_friendly_name(intermediate_model, model, siface) + if asc_consumer_name and asc_exposer_name and siface_name: + return ( + f"Software components '{asc_consumer_name}' and '{asc_exposer_name}' " + f"are supposed to communicate through interface '{siface_name}', " + "but they are deployed to nodes that cannot communicate through a common network." + ) + except: + return "A software package is deployed on a node that has no access to an interface it consumes." + +MSG = "All software packages can see the interfaces they need through a common network." + +SOFTWARE_PACKAGE_IFACE_NET = ( + software_package_iface_net, + "software_package_iface_net", + MSG, + ed_software_package_iface_net +) + +SOFTWARE_PACKAGE_IFACE_NET_V2_1 = ( + software_package_iface_net_v2_1, + "software_package_iface_net", + MSG, + ed_software_package_iface_net +) + +SOFTWARE_PACKAGE_IFACE_NET_V2_3 = ( + software_package_iface_net_v2_3, + "software_package_iface_net", + MSG, + ed_software_package_iface_net +) + +SOFTWARE_PACKAGE_IFACE_NET_V3_1 = ( + software_package_iface_net_v3_1, + "software_package_iface_net", + MSG, + ed_software_package_iface_net +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py b/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py new file mode 100644 index 0000000000000000000000000000000000000000..bfb43d5d1051dd1d28f9f9b7d326f810d9273747 --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py @@ -0,0 +1,59 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + + +def vm_has_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + vm, iface = Consts("vm iface", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + vm) == smtenc.classes["infrastructure_VirtualMachine"], + Not( + Exists( + [iface], + smtenc.association_rel( + vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) + ) + ) + ) + +def vm_has_iface_v2_3(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + vm, iface = Consts("vm iface", smtsorts.element_sort) + return And( + smtenc.element_class_fun( + vm) == smtenc.classes["infrastructure_VirtualMachine"], + Not( + Exists( + [iface], + smtenc.association_rel( + vm, smtenc.associations["infrastructure_Node::ifaces"], iface) + ) + ) + ) + +def ed_vm_has_iface(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + vm = Const("vm", smtsorts.element_sort) + vm_name = get_user_friendly_name( + intermediate_model, solver.model(), vm) + if vm_name: + return f"Virtual machine {vm_name} is not connected to any network interface." + except: + return "A virtual machine is not connected to any network interface." + +MSG = "All virtual machines must be connected to at least one network interface." + +VM_HAS_IFACE = ( + vm_has_iface, + "vm_has_iface", + MSG, + ed_vm_has_iface +) + +VM_HAS_IFACE_V2_3 = ( + vm_has_iface_v2_3, + "vm_has_iface", + MSG, + ed_vm_has_iface +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py b/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py new file mode 100644 index 0000000000000000000000000000000000000000..73a6ce4d5ade7a56c48c4319720989ef4b7a4e20 --- /dev/null +++ b/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py @@ -0,0 +1,81 @@ +from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name + + +def vm_os_required(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + vm, cont, ccfg = Consts("vm cont ccfg", smtsorts.element_sort) + os = Const("os", smtsorts.attr_data_sort) + return And( + smtenc.element_class_fun( + vm) == smtenc.classes["infrastructure_VirtualMachine"], + smtenc.element_class_fun( + cont) == smtenc.classes["infrastructure_Container"], + Not( + Exists( + [vm, os, ccfg], + And( + smtenc.association_rel( + cont, smtenc.associations["infrastructure_Container::configs"], ccfg), + smtenc.association_rel( + ccfg, smtenc.associations["infrastructure_ContainerConfig::host"], vm), + smtenc.attribute_rel( + vm, smtenc.attributes["infrastructure_ComputingNode::os"], os) + ) + ) + ) + ) + +def vm_os_required_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: + vm, cont, ccfg = Consts("vm cont ccfg", smtsorts.element_sort) + os = Const("os", smtsorts.attr_data_sort) + return And( + smtenc.element_class_fun( + vm) == smtenc.classes["infrastructure_VirtualMachine"], + smtenc.element_class_fun( + cont) == smtenc.classes["infrastructure_Container"], + Not( + Exists( + [vm, os, ccfg], + And( + smtenc.association_rel( + cont, smtenc.associations["infrastructure_Container::hostConfigs"], ccfg), + smtenc.association_rel( + ccfg, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm), + smtenc.attribute_rel( + vm, smtenc.attributes["infrastructure_ComputingNode::os"], os) + ) + ) + ) + ) + +def ed_vm_os_required(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str: + try: + cont = Const("cont", smtsorts.element_sort) + vm = Const("vm", smtsorts.element_sort) + cont_name = get_user_friendly_name( + intermediate_model, solver.model(), cont) + vm_name = get_user_friendly_name( + intermediate_model, solver.model(), vm) + if cont_name and vm_name: + return f"The virtual machine '{vm_name}' hosting container '{cont_name}' needs an OS." + except: + return "A Virtual machine hosting a container needs an OS." + + +MSG = "When something is hosted on a virtual machine (e.g.: containers), the VM must have the 'os' specified." + +VM_OS_REQUIRED = ( + vm_os_required, + "vm_os_required", + MSG, + ed_vm_os_required +) + +VM_OS_REQUIRED_V3_1 = ( + vm_os_required_v3_1, + "vm_os_required", + MSG, + ed_vm_os_required +) \ No newline at end of file diff --git a/mc_openapi/doml_mc/common_reqs.py b/mc_openapi/doml_mc/common_reqs.py index d45c369da44045f7dcdb86834743a786a7706aa0..74edd900f6dea5d2695f8be48488e851b3b27d56 100644 --- a/mc_openapi/doml_mc/common_reqs.py +++ b/mc_openapi/doml_mc/common_reqs.py @@ -1,197 +1,78 @@ -from z3 import ( - Consts, ExprRef, - Exists, And, Or, Not -) - -from .imc import ( - SMTEncoding, SMTSorts, Requirement, RequirementStore -) - - -def get_consts(smtsorts: SMTSorts, consts: list[str]) -> list[ExprRef]: - return Consts(" ".join(consts), smtsorts.element_sort) - - -def vm_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: - vm, iface = get_consts(smtsorts, ["vm", "iface"]) - return Exists( - [vm], - And( - smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], - Not( - Exists( - [iface], - smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) - ) - ) - ) - ) - - -def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: - asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, dc = get_consts( - smtsorts, - ["asc_consumer", "asc_exposer", "siface", "net", "net_iface", "cnode", "cdeployment", "enode", "edeployment", "vm", "dc"] - ) - return Exists( - [asc_consumer, asc_exposer, siface], - And( - smtenc.association_rel(asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface), - smtenc.association_rel(asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface), - Not( - Exists( - [cdeployment, cnode, edeployment, enode, net], - And( - smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer), - smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::node"], cnode), - Exists( - [vm, net_iface], - Or( - And( # asc_consumer is deployed on a component with an interface in network n - smtenc.association_rel(cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n - smtenc.association_rel(cnode, smtenc.associations["infrastructure_Container::hosts"], vm), - smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n - smtenc.association_rel(cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), - smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - ) - ), - smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer), - smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::node"], enode), - Exists( - [vm, net_iface], - Or( - And( # asc_exposer is deployed on a component with an interface in network n - smtenc.association_rel(enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n - smtenc.association_rel(enode, smtenc.associations["infrastructure_Container::hosts"], vm), - smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n - smtenc.association_rel(enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm), - smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface), - smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net), - ), - ) - ) - ) - ) - ) - ) - ) - - -def iface_uniq(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: - def any_iface(elem, iface): - ifaces_assocs = [ - "infrastructure_ComputingNode::ifaces", - "infrastructure_Storage::ifaces", - "infrastructure_FunctionAsAService::ifaces" - ] - return Or(*(smtenc.association_rel(elem, smtenc.associations[assoc_name], iface) for assoc_name in ifaces_assocs)) - - e1, e2, ni = get_consts(smtsorts, ["e1", "e2", "i"]) - return Exists( - [e1, e2, ni], - And( - any_iface(e1, ni), - any_iface(e2, ni), - e1 != e2 - ) - ) - - -def all_SoftwareComponents_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: - sc, deployment, ielem = get_consts(smtsorts, ["sc", "deployment", "ielem"]) - return Exists( - [sc], - And( - smtenc.element_class_fun(sc) == smtenc.classes["application_SoftwareComponent"], - Not( - Exists( - [deployment, ielem], - And( - smtenc.association_rel(deployment, smtenc.associations["commons_Deployment::component"], sc), - smtenc.association_rel(deployment, smtenc.associations["commons_Deployment::node"], ielem), - ) - ) - ) - ) - ) - - -def all_infrastructure_elements_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef: - def checkOneClass(ielem, concr, provider, celem, ielemClass, providerAssoc, celemAssoc): - return And( - smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass], - Not( - Exists( - [provider, celem], - And( - smtenc.association_rel(concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider), - smtenc.association_rel(provider, smtenc.associations[providerAssoc], celem), - smtenc.association_rel(celem, smtenc.associations[celemAssoc], ielem) - ) - ) - ) - ) - - ielem, concr, provider, celem = get_consts(smtsorts, ["ielem", "concr", "provider", "celem"]) - return Exists( - [concr], - And( - smtenc.element_class_fun(concr) == smtenc.classes["concrete_ConcreteInfrastructure"], - Exists( - [ielem], - Or( - checkOneClass( - ielem, concr, provider, celem, - "infrastructure_VirtualMachine", - "concrete_RuntimeProvider::vms", - "concrete_VirtualMachine::maps" - ), - checkOneClass( - ielem, concr, provider, celem, - "infrastructure_Network", - "concrete_RuntimeProvider::networks", - "concrete_Network::maps" - ), - checkOneClass( - ielem, concr, provider, celem, - "infrastructure_Storage", - "concrete_RuntimeProvider::storages", - "concrete_Storage::maps" - ), - checkOneClass( - ielem, concr, provider, celem, - "infrastructure_FunctionAsAService", - "concrete_RuntimeProvider::faas", - "concrete_FunctionAsAService::maps" - ), - ) - ) - ) - ) +from .imc import Requirement, RequirementStore +from .intermediate_model import DOMLVersion +from .builtin_requirements import * + +REQUIREMENTS = { + DOMLVersion.V2_0: [ + VM_HAS_IFACE, + SOFTWARE_PACKAGE_IFACE_NET, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_CONCRETE_MAP_SOMETHING, + SECURITY_GROUP_MUST_HAVE_IFACE + ], + DOMLVersion.V2_1: [ + VM_HAS_IFACE, + SOFTWARE_PACKAGE_IFACE_NET_V2_1, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_CONCRETE_MAP_SOMETHING, + SECURITY_GROUP_MUST_HAVE_IFACE + ], + DOMLVersion.V2_2: [ + VM_HAS_IFACE, + SOFTWARE_PACKAGE_IFACE_NET_V2_1, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_CONCRETE_MAP_SOMETHING, + SECURITY_GROUP_MUST_HAVE_IFACE, + CONCRETE_ASG_NO_VM, + VM_OS_REQUIRED + ], + DOMLVersion.V2_3: [ + VM_HAS_IFACE_V2_3, + SOFTWARE_PACKAGE_IFACE_NET_V2_3, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_CONCRETE_MAP_SOMETHING, + SECURITY_GROUP_MUST_HAVE_IFACE, + CONCRETE_ASG_NO_VM, + VM_OS_REQUIRED + ], + DOMLVersion.V3_0: [ + VM_HAS_IFACE_V2_3, + SOFTWARE_PACKAGE_IFACE_NET_V2_3, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, + ALL_CONCRETE_MAP_SOMETHING, + SECURITY_GROUP_MUST_HAVE_IFACE, + CONCRETE_ASG_NO_VM, + VM_OS_REQUIRED + ], + DOMLVersion.V3_1: [ + VM_HAS_IFACE_V2_3, + SOFTWARE_PACKAGE_IFACE_NET_V3_1, + IFACE_UNIQ, + ALL_SOFTWARE_COMPONENTS_DEPLOYED, + ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1, + ALL_CONCRETE_MAP_SOMETHING_V3_1, + SECURITY_GROUP_MUST_HAVE_IFACE_V3_1, + CONCRETE_ASG_NO_VM, + VM_OS_REQUIRED_V3_1 + ] +} -CommonRequirements = RequirementStore( +CommonRequirements = {ver: RequirementStore( [ - Requirement(*rt) for rt in [ - (vm_iface, "vm_iface", "All virtual machines must be connected to at least one network interface.", "A virtual machine is connected to no network interface."), - (software_package_iface_net, "software_package_iface_net", "All software packages can see the interfaces they need through a common network.", "A software package is deployed on a node that has no access to an interface it consumes."), - (iface_uniq, "iface_uniq", "There are no duplicated interfaces.", "There is a duplicated interface."), - (all_SoftwareComponents_deployed, "all_SoftwareComponents_deployed", "All software components have been deployed to some node.", "A software component has not been deployed to any node."), - (all_infrastructure_elements_deployed, "all_infrastructure_elements_deployed", "All abstract infrastructure elements are mapped to an element in the active concretization.", "An abstract infrastructure element has not been mapped to any element in the active concretization."), - ] - ] -) + Requirement( + *rt[:-1], error_description=("BUILTIN", rt[-1]), flipped=True + ) for rt in reqs + ]) + for ver, reqs in REQUIREMENTS.items() +} diff --git a/mc_openapi/doml_mc/consistency_reqs.py b/mc_openapi/doml_mc/consistency_reqs.py index e9324b951631002577c2ffe490607810db845d33..64d98422848ddfc2821852a44085dda75280a090 100644 --- a/mc_openapi/doml_mc/consistency_reqs.py +++ b/mc_openapi/doml_mc/consistency_reqs.py @@ -8,7 +8,7 @@ from .intermediate_model.metamodel import get_subclasses_dict from .imc import ( SMTEncoding, SMTSorts, Requirement, RequirementStore ) -from .z3encoding.utils import Iff +from .utils import Iff def subclass_cond(smtenc: SMTEncoding, subclasses: set[str], elem: ExprRef) -> ExprRef: @@ -19,7 +19,7 @@ def subclass_cond(smtenc: SMTEncoding, subclasses: set[str], elem: ExprRef) -> E ) ) - +# TODO: CHECK WHAT IS WRONG ELSE SKIP IT def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore: subclasses_dict = get_subclasses_dict(mm) # A type validity constraint is added for every attribute: @@ -41,17 +41,14 @@ def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore: tgt_type_cond = smtsorts.attr_data_sort.is_ss(attr_val) # type: ignore else: # mm_attr.type == "GeneratorKind" tgt_type_cond = Or( - attr_val == smtsorts.attr_data_sort.ss(smtenc.str_symbols["IMAGE"]), # type: ignore - attr_val == smtsorts.attr_data_sort.ss(smtenc.str_symbols["SCRIPT"]), # type: ignore + attr_val == smtsorts.attr_data_sort.str(smtenc.str_symbols["IMAGE"]), # type: ignore + attr_val == smtsorts.attr_data_sort.str(smtenc.str_symbols["SCRIPT"]), # type: ignore ) - return Exists( - [elem, attr_val], - And( - smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val), - Or( - Not(src_subclass_cond), - Not(tgt_type_cond), - ), + return And( + smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val), + Or( + Not(src_subclass_cond), + Not(tgt_type_cond), ), ) @@ -60,7 +57,8 @@ def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore: req_assertion, f"attribute_st_types {cname}::{mm_attr.name}", f"Attribute {mm_attr.name} from class {cname} must have type {mm_attr.type}.", - f"Attribute {mm_attr.name} from class {cname} has a type different from {mm_attr.type}.", + lambda _s, _m, _i: f"Attribute {mm_attr.name} from class {cname} has a type different from {mm_attr.type}.", + flipped=True ) ) return RequirementStore(reqs) @@ -76,29 +74,23 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore: elem = Const("elem", smtsorts.element_sort) attr_val = Const("attr_val", smtsorts.attr_data_sort) src_subclass_cond = subclass_cond(smtenc, subclasses_dict[cname], elem) # Source subclass condition - return Exists( - [elem], - And( - src_subclass_cond, - Not( - Exists( - [attr_val], - smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val), - ), - ) - ), + return And( + src_subclass_cond, + Not( + Exists( + [attr_val], + smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val), + ), + ) ) def req_assertion_ub(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_attr=mm_attr) -> ExprRef: elem = Const("elem", smtsorts.element_sort) attr_val1, attr_val2 = Consts("attr_val1 attr_val2", smtsorts.attr_data_sort) - return Exists( - [elem, attr_val1, attr_val2], - And( - smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val1), - smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val2), - attr_val1 != attr_val2, - ), + return And( + smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val1), + smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val2), + attr_val1 != attr_val2, ) lb, ub = mm_attr.multiplicity @@ -108,7 +100,8 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore: req_assertion_lb, f"attribute_mult_lb {cname}::{mm_attr.name}", f"Attribute {mm_attr.name} from class {cname} must have at least one value.", - f"Mandatory attribute {mm_attr.name} from class {cname} has no value.", + lambda _s, _m, _i: f"Mandatory attribute {mm_attr.name} from class {cname} has no value.", + flipped=True ) ) if ub == "1": @@ -117,7 +110,8 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore: req_assertion_ub, f"attribute_mult_ub {cname}::{mm_attr.name}", f"Attribute {mm_attr.name} from class {cname} must have at most one value.", - f"Attribute {mm_attr.name} from class {cname} has more than one value.", + lambda _s, _m, _i: f"Attribute {mm_attr.name} from class {cname} has more than one value.", + flipped=True ) ) return RequirementStore(reqs) @@ -134,15 +128,12 @@ def get_association_type_reqs(mm: MetaModel) -> RequirementStore: # of the association. def req_assertion(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef: es, et = Consts("es et", smtsorts.element_sort) - return Exists( - [es, et], - And( - smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et), - Not( - And( - subclass_cond(smtenc, subclasses_dict[cname], es), # Source subclass condition - subclass_cond(smtenc, subclasses_dict[mm_assoc.class_], et) # Target subclass condition - ), + return And( + smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et), + Not( + And( + subclass_cond(smtenc, subclasses_dict[cname], es), # Source subclass condition + subclass_cond(smtenc, subclasses_dict[mm_assoc.class_], et) # Target subclass condition ), ), ) @@ -152,7 +143,8 @@ def get_association_type_reqs(mm: MetaModel) -> RequirementStore: req_assertion, f"association_st_classes {cname}::{mm_assoc.name}", f"Association {mm_assoc.name} from class {cname} must target class {mm_assoc.class_}.", - f"Association {mm_assoc.name} from class {cname} has a class different from {mm_assoc.class_}.", + lambda _s, _m, _i: f"Association {mm_assoc.name} from class {cname} has a class different from {mm_assoc.class_}.", + flipped=True ) ) return RequirementStore(reqs) @@ -166,28 +158,22 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore: for mm_assoc in c.associations.values(): def req_assertion_lb(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef: es, et = Consts("es et", smtsorts.element_sort) - return Exists( - [es], - And( - subclass_cond(smtenc, subclasses_dict[cname], es), # Source subclass condition - Not( - Exists( - [et], - smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et), - ), - ) - ), + return And( + subclass_cond(smtenc, subclasses_dict[cname], es), # Source subclass condition + Not( + Exists( + [et], + smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et), + ), + ) ) def req_assertion_ub(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef: es, et1, et2 = Consts("es et1 et2", smtsorts.element_sort) - return Exists( - [es, et1, et2], - And( - smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et1), - smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et2), - et1 != et2, - ), + return And( + smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et1), + smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et2), + et1 != et2, ) lb, ub = mm_assoc.multiplicity @@ -197,7 +183,8 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore: req_assertion_lb, f"association_mult_lb {cname}::{mm_assoc.name}", f"Association {mm_assoc.name} from class {cname} must have at least one target.", - f"Mandatory association {mm_assoc.name} is missing from an element of class {cname}.", + lambda _s, _m, _i: f"Mandatory association {mm_assoc.name} is missing from an element of class {cname}.", + flipped=True ) ) if ub == "1": @@ -206,7 +193,8 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore: req_assertion_ub, f"association_mult_ub {cname}::{mm_assoc.name}", f"Association {mm_assoc.name} from class {cname} must have at most one target.", - f"Association {mm_assoc.name} has more than one target in an element of class {cname}.", + lambda _s, _m, _i: f"Association {mm_assoc.name} has more than one target in an element of class {cname}.", + flipped=True ) ) return RequirementStore(reqs) @@ -218,14 +206,11 @@ def get_inverse_association_reqs(inv_assoc: list[tuple[str, str]]) -> Requiremen for an1, an2 in inv_assoc: def req_assertion(smtenc: SMTEncoding, smtsorts: SMTSorts, an1=an1, an2=an2) -> ExprRef: es, et = Consts("es et", smtsorts.element_sort) - return Exists( - [es, et], - Not( - Iff( - smtenc.association_rel(es, smtenc.associations[an1], et), - smtenc.association_rel(et, smtenc.associations[an2], es) - ), - ) + return Not( + Iff( + smtenc.association_rel(es, smtenc.associations[an1], et), + smtenc.association_rel(et, smtenc.associations[an2], es) + ), ) reqs.append( @@ -233,7 +218,8 @@ def get_inverse_association_reqs(inv_assoc: list[tuple[str, str]]) -> Requiremen req_assertion, f"association_inverse {an1} {an2}", f"Association {an1} must be the inverse of {an2}.", - f"Association {an1} is not the inverse of {an2}.", + lambda _s, _m, _i: f"Association {an1} is not the inverse of {an2}.", + flipped=True ) ) return RequirementStore(reqs) @@ -268,8 +254,8 @@ def assert_attribute_rel_constraints( tgt_type_cond = smtsorts.attr_data_sort.is_ss(ad) # type: ignore else: # mm_attr.type == "GeneratorKind" tgt_type_cond = Or( - ad == smtsorts.attr_data_sort.ss(smtenc.str_symbols["IMAGE"]), # type: ignore - ad == smtsorts.attr_data_sort.ss(smtenc.str_symbols["SCRIPT"]), # type: ignore + ad == smtsorts.attr_data_sort.str(smtenc.str_symbols["IMAGE"]), # type: ignore + ad == smtsorts.attr_data_sort.str(smtenc.str_symbols["SCRIPT"]), # type: ignore ) assn = ForAll( [es, ad], diff --git a/mc_openapi/doml_mc/csp_compatibility/__init__.py b/mc_openapi/doml_mc/csp_compatibility/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..27620127f693445ba8ab6f9846b1f25d7a511d14 --- /dev/null +++ b/mc_openapi/doml_mc/csp_compatibility/__init__.py @@ -0,0 +1,22 @@ +from .allowlist_check_v1 import CSPCompatibilityValidator +import importlib.resources as ilres +from ... import assets +import yaml + +FILE = lambda filename: ilres.files(assets).joinpath(f"csp/{filename}") + +SOURCES = [ + 'keypair', + 'arch', + 'os', + 'minimum_setup' +] + +DATA = {} + +for src in SOURCES: + with open(FILE(f'{src}.yml')) as data: + DATA[src] = yaml.safe_load(data) + +CSPCompatibilityValidator = CSPCompatibilityValidator(DATA) + diff --git a/mc_openapi/doml_mc/csp_compatibility/_iec_check.py b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py new file mode 100644 index 0000000000000000000000000000000000000000..809c26b31ba10e39e0d125c62b817bf8068ae343 --- /dev/null +++ b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py @@ -0,0 +1,110 @@ +from itertools import groupby +import re +import requests +from mc_openapi.doml_mc.imc import IntermediateModelChecker +from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion + +# DEPRECATED +# Doing this would overlap with IOP tool, therefore checks will be performed using the other tool + + +IEC_API = 'https://iec.ci.piacere.digital.tecnalia.dev/services/iecbackend/api/root-services/catalogue' + +def check_csp_compatibility(model: IntermediateModelChecker, doml_version: DOMLVersion): + if doml_version != DOMLVersion.V2_2 and doml_version != DOMLVersion.V2_2_1: + print("Unsupported DOML version!") + + all_json = requests.get(IEC_API).json() + + all_json = [ + { + 'name': x['serviceName'], + 'class': x['serviceClass']['serviceClassName'], + 'props': x['serviceAttributeValues'] + } + for x in all_json + ] + + def filterByClass(name: str): + return [vm for vm in all_json if vm['class'] == name] + + def groupByProvider(elems: list): + def flatten_properties(el): + for p in el['props']: + el[p['serviceAttributeType']['name'].lower()] = p['serviceAttributeValue'] or None + el.pop('props', None) + return el + + elems = [flatten_properties(elem) for elem in elems] + + return { k: list(v) for k, v in groupby(sorted(elems, key=lambda elem: elem['provider']), lambda elem: elem['provider'])} + + + # Catalog IEC Elements + iec_vms = groupByProvider(filterByClass('Virtual Machine')) + iec_stos = groupByProvider(filterByClass('Storage')) + iec_dbs = groupByProvider(filterByClass('Database')) + + # DOML IM Elements + im_elems = model.values() + + compnodes = [cn for cn in im_elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)] + locations = [lc for lc in im_elems if lc.class_ == 'infrastructure_Location'] + + # print(compnodes) + # print(locations) + + # for each provider + # check if the available elements have all the properties of doml elements + # if not, mark provider as unsupported and report the unsupported element and its value + + for provider, avail_vms in iec_vms.items(): + print(f'==={provider}===') + for cn in compnodes: + # attributes are list|None! + name = cn.attributes.get('commons_DOMLElement::name') + cpu_count = cn.attributes.get('infrastructure_ComputingNode::cpu_count') + memory_mb = cn.attributes.get('infrastructure_ComputingNode::memory_mb') + location = cn.associations.get('infrastructure_ComputingNode::location') + region = None + zone = None + if location: + location = model[list(location)[0]] + region = location.attributes.get('infrastructure_Location::region') + zone = location.attributes.get('infrastructure_Location::zone') + # not in IEC + # arch = cn.attributes.get('infrastructure_ComputingNode::architecture') + # os = cn.attributes.get('infrastructure_ComputingNode::os') + + print(f'---{name[0]}---') + + valid_configs = avail_vms + + if cpu_count: + valid_configs = [ + avm for avm in valid_configs + if (int(avm['virtual cpu cores']) == cpu_count[0] if cpu_count else False) + ] + + if memory_mb: + valid_configs = [ + avm for avm in valid_configs + if (float(avm['memory']) * 1000 == float(memory_mb[0]) if memory_mb else False) + ] + + if region: + valid_configs = [ + avm for avm in valid_configs + if (avm['region'] == region[0] if region else False) + ] + + if zone: + valid_configs = [ + avm for avm in valid_configs + if (avm['zone'] == zone[0] if zone else False) + ] + + # print(valid_configs) + + + diff --git a/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py new file mode 100644 index 0000000000000000000000000000000000000000..3c8b0c4aadfd7f7ad42b2daba1160d18ab849fe1 --- /dev/null +++ b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py @@ -0,0 +1,131 @@ + + +from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement, IntermediateModel +from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion +from difflib import SequenceMatcher + +import re + +class CSPCompatibilityValidator: + def __init__(self, data: dict) -> None: + self.data = data + + def check(self, model: IntermediateModel, doml_version: DOMLVersion) -> dict[str, list]: + """Returns a list of CSP supported by the model""" + + ret = {} + + # Check KeyPair + keypairs = self.check_keypair(model) + if len(keypairs) > 1: + ret['keypairs'] = keypairs + # ComputingNode and inheritors + arch, os, minreq = self.check_computing_nodes(model) + if len(arch) > 1: + ret['arch'] = arch + if len(os) > 1: + ret['os'] = os + if len(minreq) > 1: + ret['minreq'] = minreq + + return ret + + def check_keypair(self, model: IntermediateModel): + elems = model.values() + keypairs = [kp for kp in elems if kp.class_ == 'commons_KeyPair'] + TABLE = [['KeyPair', 'Algorithm', *self.data['keypair'].keys()]] + for kp in keypairs: + name = kp.user_friendly_name + algorithm = kp.attributes.get('commons_KeyPair::algorithm') + bits = kp.attributes.get('commons_KeyPair::bits') + # For each vendor, check if there's at least one supported configuration + if algorithm is not None and len(algorithm) > 0: + algorithm = algorithm[0].upper() + ROW = [name, algorithm] + for _, valid_algos in self.data['keypair'].items(): + value = '✅' if algorithm in valid_algos else '❌' + ROW.append(value) + TABLE.append(ROW) + return TABLE + + def check_computing_nodes(self, model: IntermediateModel): + elems = model.values() + compnodes = [cn for cn in elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)] + ARCH_TABLE = [['Node', 'Arch', *self.data['arch'].keys()]] + OS_TABLE = [['Node', 'OS', *self.data['os'].keys()]] + MINREQ_TABLE = [['Node', *self.data['minimum_setup'].keys()]] + + VALID_OS_MATCH_PERCENT = 0.33 + + for el in compnodes: + name = el.user_friendly_name or el.attributes.get('commons_DOMLElement::name') or f'[{el.class_}]' + arch = el.attributes.get('infrastructure_ComputingNode::architecture') + os = el.attributes.get('infrastructure_ComputingNode::os') + # cpu_count = el.attributes.get('infrastructure_ComputingNode::cpu_count') + # memory_mb = el.attributes.get('infrastructure_ComputingNode::memory_mb') + + # CHECK ARCH + if arch and len(arch) > 0: + arch = arch[0].upper() + ROW = [name, arch] + for _, valid_archs in self.data['arch'].items(): + valid_archs = [v.upper() for v in valid_archs] + value = '✅' if arch in valid_archs else '❌' + ROW.append(value) + ARCH_TABLE.append(ROW) + + # CHECK OS + if os and len(os) > 0: + os = os[0].upper() + ROW = [name, os] + for _, valid_os in self.data['os'].items(): + valid_os = [distro.upper() for os_family in valid_os for distro in valid_os[os_family]] + compatible_os = [v for v in valid_os if v in os or os in v] + alt_compatible_os = [(v, SequenceMatcher(None, v, os).ratio()) for v in valid_os if SequenceMatcher(None, v, os).ratio() > VALID_OS_MATCH_PERCENT] + alt_compatible_os = sorted(alt_compatible_os, key=lambda x: x[1]) + value = any(compatible_os) + value = '✅' if value else '❌' if len(alt_compatible_os) == 0 else '❓' + if len(compatible_os) > 0: + value += f' ({compatible_os[0].lower()})' + if value == '❓': + alt_os_name, alt_os_ratio = alt_compatible_os[0] + value += f' ({alt_os_name.lower()}, {alt_os_ratio*100:.{1}f}%)' + ROW.append(value) + OS_TABLE.append(ROW) + + # CHECK MINIMUM REQUIREMENTS FOR CSP + ROW = [name] + for vendor, reqs in self.data['minimum_setup'].items(): + CHECKS = {} + for req in reqs: + if isinstance(req, list): + try: + dep = list(el.associations.get(req[0]))[0] + dep = model[dep] + CHECKS[str(req)] = dep.associations.get(req[1]) is not None or el.attributes.get(req[1]) is not None + except: + CHECKS[str(req)] = False + if isinstance(req, str): + CHECKS[req] = el.associations.get(req) is not None or el.attributes.get(req) is not None + + all_req_valid = all([v for v in CHECKS.values()]) + value = ['✅' if all_req_valid else '❌'] + if not all_req_valid: + value += [ + re.sub(r"\s*,\s*", " -> ", k) + .replace("_", ".", 1) + .replace("::", ".") + .replace("[", "") + .replace("]", "") + .replace("'", "") + for k, v in CHECKS.items() + if v is False + ] + ROW.append(value) + MINREQ_TABLE.append(ROW) + + return ARCH_TABLE, OS_TABLE, MINREQ_TABLE + + + + diff --git a/mc_openapi/doml_mc/domlr_parser/__init__.py b/mc_openapi/doml_mc/domlr_parser/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7e7d69b9817656cb7984292858fb371e41694891 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/__init__.py @@ -0,0 +1,3 @@ +from .transformer import DOMLRTransformer +from .synthesis_transformer import SynthesisDOMLRTransformer +from .parser import Parser \ No newline at end of file diff --git a/mc_openapi/doml_mc/domlr_parser/exceptions.py b/mc_openapi/doml_mc/domlr_parser/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..44ba418127398291a5449923bc729fe06596be0d --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/exceptions.py @@ -0,0 +1,25 @@ +class RequirementException(Exception): + message: str + def __repr__(self) -> str: + return self.message + +class RequirementMissingKeyException(RequirementException): + def __init__(self, key_type: str, key: str, close_matches: list[str], *args: object) -> None: + super().__init__(*args) + fix_syntax = lambda x: x.replace("_", ".", 1).replace("::", ".") + key = fix_syntax(key) + close_matches = list(map(fix_syntax, close_matches)) + self.message = f"Error: no {key_type} found named '{key}'.\n" + if close_matches: + self.message += "Perhaps you meant...\n" + self.message += "".join([f"- '{match}'\n" for match in close_matches]) + +class RequirementBadSyntaxException(RequirementException): + def __init__(self, line: int, col: int, message: str, *args: object) -> None: + super().__init__(*args) + self.message = f"Syntax Error at Ln {line}, Col {col}:\n{message}" + +class ParserException(Exception): + def __init__(self, *args: object) -> None: + super().__init__(*args) + self.errors = "Failed to parse DOMLR." \ No newline at end of file diff --git a/mc_openapi/doml_mc/domlr_parser/exceptions.yaml b/mc_openapi/doml_mc/domlr_parser/exceptions.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f04cf3429d4ab3fcd5c414ac9d8661a63c4a8454 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/exceptions.yaml @@ -0,0 +1,43 @@ +TOKENS: + FLIP_EXPR: | + a declaration of a requirement. + To declare a requirement use: + • '+' to declare a requirement + • '-' to declare a requirement in negation form, which means + that if it's satisfied, then the DOML does not respect the + requirements. + + ESCAPED_STRING: a string. Strings are enclosed by double quotes '"'. + BOOL: a boolean value. It can be 'true' or 'false'. + NUMBER: a number. It must be an integer. + VALUE: a value constant. Values must start with an uppercase letter. + CONST: a logic variable. Variables must start with a lowercase letter. + + IS: | + a statement such as: + • 'is', 'is not' followed by a class or a variable + • 'has' followed by an relationship name and then a variable or value + + NOT: a 'not' before an expression or a quantifier. + OR: a logical connective such as 'or' between expressions. + AND: a logical connective such as 'and' between expressions. + IFF: a logical connective such as 'iff' between expressions. + IMPLIES: a logical connective such as 'implies' between expressions. + + COMMA: a ',' separating bounded variables after an 'exists'/'forall' + + LPAR: a '(' after which an expression begins. + RPAR: a ')' closing a previous '('. + + RELATIONSHIP: | + a valid relationship name. + Relationships consists of 'package.class->relationship', with no spaces around '.' and '->'. + + + EXISTS: a 'exists' quantifier. + FORALL: a 'forall' quantifier. + + CLASS_PREFIX: a 'class' followed by a class name + ERR_DESC_SYMBOL: a 'error:' to separate the logic expression from the error message. +HINTS: + DOT: If you're trying to use a class, did you put 'class' before the class name? \ No newline at end of file diff --git a/mc_openapi/doml_mc/domlr_parser/grammar.lark b/mc_openapi/doml_mc/domlr_parser/grammar.lark new file mode 100644 index 0000000000000000000000000000000000000000..896cf3a64f41f0743b44246c05acdbd7393e07b9 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/grammar.lark @@ -0,0 +1,82 @@ +start : (flags)? (requirements)? + +flags : flag (flag)* + +flag : "%IGNORE" CONST -> flag_requirement_ignore + | "%IGNORE_BUILTIN" -> flag_requirement_ignore_builtin + | "%CHECK" CONST -> flag_requirement_check + | "%CHECK_CONSISTENCY" -> flag_requirement_check_consistency + | "%CSP" -> flag_csp + +requirements : requirement (requirement)* + +requirement : FLIP_EXPR req_name expression "error:" error_desc + +req_name : ESCAPED_STRING +error_desc : ESCAPED_STRING + +?expression : iff_expr + +?iff_expr : (implies_expr "iff")? implies_expr + +?implies_expr : (and_expr "implies")? and_expr + +?and_expr : (or_expr "and")* or_expr + +?or_expr : (not_expr "or")* not_expr + +?not_expr : "not" not_expr -> negation + | quantification + +?quantification : "exists" bound_consts "(" expression ")" -> exists + | "forall" bound_consts "(" expression ")" -> forall + | "(" expression ")" + | property + +?property : CONST "has" RELATIONSHIP CONST -> rel_assoc_expr + | CONST "has" RELATIONSHIP COMPARISON_OP value -> rel_attr_value_expr + | CONST "has" RELATIONSHIP COMPARISON_OP CONST RELATIONSHIP -> rel_attr_elem_expr + | const_or_class "is" const_or_class -> equality + | const_or_class "is not" const_or_class -> inequality + + +bound_consts : [CONST ("," CONST)*] + +const_or_class : "class" CLASS + | CONST + +value : ESCAPED_STRING + | NUMBER + | BOOL + +FLIP_EXPR : "+" + | "-" + +COMPARISON_OP : ">" | ">=" + | "<" | "<=" + | "==" | "!=" + +BOOL : ":true" + | ":false" + +// regex: /[a-zA-Z]+_[a-zA-Z]+::[a-zA-Z]+/ +RELATIONSHIP: /[^\W\d_]+\.[^\W\d_]+\.([^\W\d]|_)+/ + +CLASS: /[^\W\d_]+\.[^\W\d_]+/ + +// Const must start with lowercase letter +CONST: (LCASE_LETTER) ("_"|LETTER|DIGIT)* + +// Comment: python/sh style +COMMENT: /#[^\n]*/ + +%import common.ESCAPED_STRING +%import common.NEWLINE +%import common.LETTER +%import common.DIGIT +%import common.NUMBER +%import common.LCASE_LETTER +%import common.UCASE_LETTER +%import common.WS +%ignore WS +%ignore COMMENT diff --git a/mc_openapi/doml_mc/domlr_parser/parser.py b/mc_openapi/doml_mc/domlr_parser/parser.py new file mode 100644 index 0000000000000000000000000000000000000000..00fdc260421d328c5149200e8865e1cb4f839fa2 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/parser.py @@ -0,0 +1,90 @@ +import os + +import yaml +from doml_synthesis import State +from lark import Lark, UnexpectedCharacters, UnexpectedEOF +from z3 import Not + +from mc_openapi.doml_mc.domlr_parser.exceptions import ParserException, RequirementBadSyntaxException, RequirementMissingKeyException +from mc_openapi.doml_mc.domlr_parser.utils import StringValuesCache, VarStore +from mc_openapi.doml_mc.imc import RequirementStore + +class ParserData: + def __init__(self) -> None: + grammar_path = os.path.join(os.path.dirname(__file__), "grammar.lark") + exceptions_path = os.path.join( + os.path.dirname(__file__), "exceptions.yaml") + with open(grammar_path, "r") as grammar: + self.grammar = grammar.read() + with open(exceptions_path, "r") as exceptions: + self.exceptions = yaml.safe_load(exceptions) + + +PARSER_DATA = ParserData() + + +class Parser: + def __init__(self, transformer, grammar: str = PARSER_DATA.grammar): + self.parser = Lark(grammar, start="start", parser="lalr") + self.transformer = transformer + + def parse(self, input: str, for_synthesis: bool = False) -> tuple[RequirementStore, list[str], dict[str, bool]]: + """Parse the input string containing the DOMLR requirements and + returns a tuple with: + - RequirementStore with the parsed requirements inside + - A list of strings to be added to the string constant EnumSort + - A dictionary of all the flags + """ + try: + self.tree = self.parser.parse(input) + + const_store = VarStore() + user_values_cache = StringValuesCache() + + transformer = self.transformer(const_store, user_values_cache) + + if not for_synthesis: + reqs, flags = transformer.transform(self.tree) + return ( + RequirementStore(reqs), + user_values_cache.get_list(), + flags + ) + else: + reqs = transformer.transform(self.tree) + + # This function has to return state or it will break the + # synthesis solver + def user_reqs(state: State): + for (req, id, negated) in reqs: + state.solver.assert_and_track( + req(state) if not negated else Not(req(state)), f'Requirement {id}') + return state + + return user_reqs, user_values_cache.get_list() + + except UnexpectedEOF as e: + msg = "Unexpected End of File:\n" + msg += "Did you forget the `error:` keyword at the end of a requirement?" + raise Exception(msg) + + except UnexpectedCharacters as e: + msg = _get_error_desc_for_unexpected_characters(e, input) + raise RequirementBadSyntaxException(e.line, e.column, msg) + + +def _get_error_desc_for_unexpected_characters(e: UnexpectedCharacters, input: str): + # Error description + msg = "Syntax Error:\n\n" + msg += e.get_context(input) + msg += "Expected one of the following:\n" + for val in e.allowed: + val = PARSER_DATA.exceptions["TOKENS"].get(val, "") + msg += (f"• {val}\n") + # Suggestion that might be useful + if e.char == ".": + msg += "HINTS:\n" + msg += PARSER_DATA.exceptions["HINTS"]["DOT"] + # Print line highlighting the error + + return msg diff --git a/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py b/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..46de50cf0803ad26a82b2d4ff676141add729581 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py @@ -0,0 +1,248 @@ +from typing import Callable + +from doml_synthesis import State +from lark import Transformer +from z3 import And, Exists, ExprRef, ForAll, Implies, Not, Or + +from mc_openapi.doml_mc.domlr_parser.utils import (StringValuesCache, + SynthesisRefHandler, + VarStore) + + +class SynthesisDOMLRTransformer(Transformer): + # These callbacks will be called when a rule with the same name + # is matched. It starts from the leaves. + def __init__(self, + const_store: VarStore, + user_values_cache: StringValuesCache, + visit_tokens: bool = True + ) -> None: + super().__init__(visit_tokens) + self.const_store = const_store + self.user_values_cache = user_values_cache + + def __default__(self, data, children, meta): + return children + + # start + def requirements(self, args) -> list[tuple]: + return args + + def requirement(self, args) -> tuple: + flip_expr: bool = args[0].value == "-" + name: str = args[1] + expr: Callable[[State], ExprRef] = args[2] + return ( + expr, + name.lower().replace(" ", "_"), # id + flip_expr + ) + + def req_name(self, args) -> str: + return str(args[0].value.replace('"', '')) + + # Requirement requirement expression + + def bound_consts(self, args): + const_names = list(map(lambda arg: arg.value, args)) + for name in const_names: + self.const_store.use(name) + self.const_store.quantify(name) + return lambda state: SynthesisRefHandler.get_consts(const_names, state) + + def negation(self, args): + return lambda state: Not(args[0](state)) + + def iff_expr(self, args): + return lambda state: args[0](state) == args[1](state) + + def implies_expr(self, args): + return lambda state: Implies(args[0](state), args[1](state)) + + def and_expr(self, args): + return lambda state: And([arg(state) for arg in args]) + + def or_expr(self, args): + return lambda state: Or([arg(state) for arg in args]) + + def exists(self, args): + return lambda state: Exists(args[0](state), args[1](state)) + + def forall(self, args): + return lambda state: ForAll(args[0](state), args[1](state)) + + def rel_assoc_expr(self, args): + """An ASSOCIATION relationship""" + rel_name = args[1].value + self.const_store.use(args[0].value) + self.const_store.use(args[2].value) + + def _gen_rel_elem_expr(state: State): + rel = SynthesisRefHandler.get_assoc(state, rel_name) + + return state.rels.AssocRel( + SynthesisRefHandler.get_const(args[0].value, state), + rel.ref, + SynthesisRefHandler.get_const(args[2].value, state) + ) + return _gen_rel_elem_expr + + def rel_attr_value_expr(self, args): + """An ATTRIBUTE relationship with a rhs that is a value + + CONST "has" RELATIONSHIP COMPARISON_OP value + 0 1 2 3 + """ + + rel_name = args[1].value + + def _gen_rel_attr_value_expr(state: State): + elem = SynthesisRefHandler.get_const(args[0].value, state) + rel = SynthesisRefHandler.get_attr(state, rel_name) + + rhs_value, rhs_value_type = args[3] + rhs_value = rhs_value(state) + op = args[2].value + + if rhs_value_type == SynthesisRefHandler.INTEGER and rel.type == 'Integer': + lhs_value = state.rels.int.AttrValueRel(elem, rel.ref) + return And( + self.compare(op, lhs_value, rhs_value), + state.rels.int.AttrSynthRel(elem, rel.ref) + ) + elif op != "==" and op != "!=": + raise "You can only use == and != to compare Strings and Booleans!" + elif rhs_value_type == SynthesisRefHandler.STRING: + lhs_value = state.rels.str.AttrValueRel(elem, rel.ref) + + return And( + lhs_value == rhs_value if op == "==" else lhs_value != rhs_value, + state.rels.str.AttrSynthRel(elem, rel.ref) + ) + elif rhs_value_type == SynthesisRefHandler.BOOLEAN: + lhs_value = state.rels.bool.AttrValueRel(elem, rel.ref) + return And( + lhs_value == rhs_value if op == "==" else lhs_value != rhs_value, + state.rels.bool.AttrSynthRel(elem, rel.ref) + ) + else: + raise f'Invalid value {rhs_value} during parsing for synthesis.' + + return _gen_rel_attr_value_expr + + def rel_attr_elem_expr(self, args): + """An ATTRIBUTE relationship with a rhs that is another element + CONST "has" RELATIONSHIP COMPARISON_OP CONST RELATIONSHIP + 0 1 2 3 4 + """ + + rel1_name = args[1].value + rel2_name = args[4].value + op = args[2].value + + def _gen_rel_attr_elem_expr(state: State): + elem1 = SynthesisRefHandler.get_const(args[0].value, state) + elem2 = SynthesisRefHandler.get_const(args[3].value, state) + rel1 = SynthesisRefHandler.get_attr(state, rel1_name) + rel2 = SynthesisRefHandler.get_attr(state, rel2_name) + + if rel1.type == rel2.type == 'Integer': + return And( + state.rels.int.AttrSynthRel(elem1, rel1.ref), + state.rels.int.AttrSynthRel(elem2, rel2.ref), + self.compare( + op, + state.rels.int.AttrValueRel(elem1, rel1.ref), + state.rels.int.AttrValueRel(elem2, rel2.ref) + ) + ) + if rel1.type == rel2.type == 'Boolean': + return And( + state.rels.bool.AttrSynthRel(elem1, rel1.ref), + state.rels.bool.AttrSynthRel(elem2, rel2.ref), + self.compare( + op, + state.rels.bool.AttrValueRel(elem1, rel1.ref), + state.rels.bool.AttrValueRel(elem2, rel2.ref) + ) + ) + if rel1.type == rel2.type == 'String': + return And( + state.rels.str.AttrSynthRel(elem1, rel1.ref), + state.rels.str.AttrSynthRel(elem2, rel2.ref), + self.compare( + op, + state.rels.str.AttrValueRel(elem1, rel1.ref), + state.rels.str.AttrValueRel(elem2, rel2.ref) + ) + ) + raise f'Attribute relationships {rel1_name} ({rel1.type}) and {rel2_name} ({rel2.type}) have mismatch type.' + + return _gen_rel_attr_elem_expr + + def _get_equality_sides(self, arg1, arg2): + # We track use of const in const_or_class + if arg1.type == "CONST" and arg2.type == "CONST": + return ( + lambda state: SynthesisRefHandler.get_const(arg1.value, state), + lambda state: SynthesisRefHandler.get_const(arg2.value, state) + ) + + if arg1.type == "CLASS": + def arg1_ret(state): return SynthesisRefHandler.get_class( + state, arg1.value) + else: + def arg1_ret(state): return SynthesisRefHandler.get_element_class( + state, SynthesisRefHandler.get_const(arg1.value, state)) + + if arg2.type == "CLASS": + def arg2_ret(state): return SynthesisRefHandler.get_class( + state, arg2.value) + else: + def arg2_ret(state): return SynthesisRefHandler.get_element_class( + state, SynthesisRefHandler.get_const(arg2.value, state)) + + return (arg1_ret, arg2_ret) + + def equality(self, args): + a, b = self._get_equality_sides(args[0], args[1]) + return lambda state: a(state) == b(state) + + def inequality(self, args): + a, b = self._get_equality_sides(args[0], args[1]) + return lambda state: a(state) != b(state) + + def const_or_class(self, args): + if args[0].type == "CONST": + self.const_store.use(args[0].value) + return args[0] + + def compare(self, op: str, a, b): + + if op == ">": + return a > b + if op == ">=": + return a >= b + if op == "<": + return a < b + if op == "<=": + return a <= b + if op == "==": + return a == b + if op == "!=": + return a != b + raise f"Invalid Compare Operator Symbol: {op}" + + def value(self, args): + type = args[0].type + value = args[0].value + + if type == "ESCAPED_STRING": + value = value.replace('"', '') + self.user_values_cache.add(value) + return lambda state: SynthesisRefHandler.get_str(value, state), SynthesisRefHandler.STRING + elif type == "NUMBER": + return lambda _: value, SynthesisRefHandler.INTEGER + elif type == "BOOL": + return lambda _: SynthesisRefHandler.get_bool(value), SynthesisRefHandler.BOOLEAN + diff --git a/mc_openapi/doml_mc/domlr_parser/transformer.py b/mc_openapi/doml_mc/domlr_parser/transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..624d6003a3a675297e91e2b73bec601385b8f851 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/transformer.py @@ -0,0 +1,334 @@ +import logging +import re +from collections import ChainMap +from typing import Callable, Literal + +from lark import Transformer +from z3 import And, Exists, ExprRef, ForAll, Implies, Not, Or, Solver + +from mc_openapi.doml_mc.domlr_parser.utils import (RefHandler, + StringValuesCache, VarStore) +from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name +from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts +from mc_openapi.doml_mc.intermediate_model.doml_element import \ + IntermediateModel + + +class DOMLRTransformer(Transformer): + # These callbacks will be called when a rule with the same name + # is matched. It starts from the leaves. + def __init__(self, + const_store: VarStore, + user_values_cache: StringValuesCache, + visit_tokens: bool = True + ) -> None: + super().__init__(visit_tokens) + self.const_store = const_store + self.user_values_cache = user_values_cache + + def __default__(self, data, children, meta): + return children + + # start + def start(self, args) -> tuple[list[Requirement], dict[str, str]]: + if not isinstance(args[0], dict): # there aren't flags + return args[0], {} + elif len(args) == 1 and isinstance(args[0], dict): # There are just the flags + return [], args[0] + return args[1], args[0] + + def flags(self, args) -> dict: + return dict(ChainMap(*list(args))) + + def flag_requirement_check(self, args) -> dict: + return { args[0].value : True } + + def flag_requirement_check_consistency(self, args) -> dict: + return { '_check_consistency' : True } + + def flag_requirement_ignore(self, args) -> dict: + return { args[0].value : False } + + def flag_requirement_ignore_builtin(self, args) -> dict: + return { '_ignore_builtin' : True } + + def flag_csp(self, args) -> dict: + return { '_csp' : True } + + def requirements(self, args) -> list[Requirement]: + return args + + def requirement(self, args) -> Requirement: + flip_expr: bool = args[0].value == "-" + name: str = args[1] + expr: Callable[[SMTEncoding, SMTSorts], ExprRef] = args[2] + errd: tuple[Literal["USER", "BUILTIN"], Callable[[Solver, SMTSorts, + IntermediateModel, int], str]] = args[3] + index = self.const_store.get_index_and_push() + return Requirement( + expr, + name.lower().replace(" ", "_"), + name, + (errd[0], lambda solver, sorts, model: errd[1]( + solver, sorts, model, + index, + name + )), + flipped=flip_expr + ) + + def req_name(self, args) -> str: + return str(args[0].value.replace('"', '')) + + # Requirement requirement expression + + def bound_consts(self, args): + const_names = list(map(lambda arg: arg.value, args)) + for name in const_names: + self.const_store.use(name) + self.const_store.quantify(name) + return lambda _, sorts: RefHandler.get_consts(const_names, sorts) + + def negation(self, args): + return lambda enc, sorts: Not(args[0](enc, sorts)) + + def iff_expr(self, args): + return lambda enc, sorts: args[0](enc, sorts) == args[1](enc, sorts) + + def implies_expr(self, args): + return lambda enc, sorts: Implies(args[0](enc, sorts), args[1](enc, sorts)) + + def and_expr(self, args): + return lambda enc, sorts: And([arg(enc, sorts) for arg in args]) + + def or_expr(self, args): + return lambda enc, sorts: Or([arg(enc, sorts) for arg in args]) + + def exists(self, args): + return lambda enc, sorts: Exists(args[0](enc, sorts), args[1](enc, sorts)) + + def forall(self, args): + return lambda enc, sorts: ForAll(args[0](enc, sorts), args[1](enc, sorts)) + + def rel_assoc_expr(self, args): + """An ASSOCIATION relationship""" + rel_name = args[1].value + self.const_store.use(args[0].value) + self.const_store.use(args[2].value) + + def _gen_rel_elem_expr(enc: SMTEncoding, sorts: SMTSorts): + rel, rel_type = RefHandler.get_relationship(enc, rel_name) + + assert rel_type == RefHandler.ASSOCIATION + + return RefHandler.get_association_rel( + enc, + RefHandler.get_const(args[0].value, sorts), + rel, + RefHandler.get_const(args[2].value, sorts) + ) + return _gen_rel_elem_expr + + def rel_attr_value_expr(self, args): + """An ATTRIBUTE relationship with a rhs that is a value""" + + rel_name = args[1].value + + def _gen_rel_attr_value_expr(enc: SMTEncoding, sorts: SMTSorts): + elem = RefHandler.get_const(args[0].value, sorts) + rel, rel_type = RefHandler.get_relationship(enc, rel_name) + assert rel_type == RefHandler.ATTRIBUTE + + rhs_value, rhs_value_type = args[3] + rhs_value = rhs_value(enc, sorts) + op = args[2].value + + if rhs_value_type == RefHandler.INTEGER: + + lhs_value = RefHandler.get_value("x", sorts) + + return And( + RefHandler.get_attribute_rel(enc, + elem, + rel, + lhs_value + ), + self.compare_int(sorts, op, lhs_value, rhs_value) + ) + elif rhs_value_type == RefHandler.STRING or rhs_value_type == RefHandler.BOOLEAN: + expr = RefHandler.get_attribute_rel(enc, + elem, + rel, + rhs_value + ) + if op == "==": + return expr + elif op == "!=": + return Not(expr) + else: + raise f'Invalid compare operator "{op}". It must be "==" or "!=".' + + return _gen_rel_attr_value_expr + + def rel_attr_elem_expr(self, args): + """An ATTRIBUTE relationship with a rhs that is another element""" + + rel1_name = args[1].value + rel2_name = args[4].value + op = args[2].value + + def _gen_rel_attr_elem_expr(enc: SMTEncoding, sorts: SMTSorts): + elem1 = RefHandler.get_const(args[0].value, sorts) + elem2 = RefHandler.get_const(args[3].value, sorts) + rel1, rel1_type = RefHandler.get_relationship(enc, rel1_name) + rel2, rel2_type = RefHandler.get_relationship(enc, rel2_name) + + assert rel1_type == RefHandler.ATTRIBUTE + assert rel2_type == RefHandler.ATTRIBUTE + + rhs_value = RefHandler.get_value("x", sorts) + + expr = And( + RefHandler.get_attribute_rel(enc, + elem1, + rel1, + rhs_value + ), + RefHandler.get_attribute_rel(enc, + elem2, + rel2, + rhs_value + ) + ) + if op == "==": + return expr + elif op == "!=": + return Not(expr) + else: + rhs1_value = RefHandler.get_value("rhs1", sorts) + rhs2_value = RefHandler.get_value("rhs2", sorts) + expr = And( + RefHandler.get_attribute_rel(enc, + elem1, + rel1, + rhs1_value + ), + RefHandler.get_attribute_rel(enc, + elem2, + rel2, + rhs2_value + ), + self.compare_int(sorts, op, rhs1_value, rhs2_value) + ) + logging.warning( + "Warning: Comparing attributes of two elements with {op} is experimental!\n", + "Assumption: the attribute is an Integer." + ) + return expr + + return _gen_rel_attr_elem_expr + + def _get_equality_sides(self, arg1, arg2): + # We track use of const in const_or_class + if arg1.type == "CONST" and arg2.type == "CONST": + return ( + lambda _, sorts: RefHandler.get_const(arg1.value, sorts), + lambda _, sorts: RefHandler.get_const(arg2.value, sorts) + ) + + if arg1.type == "CLASS": + def arg1_ret(enc, _): return RefHandler.get_class(enc, arg1.value) + else: + def arg1_ret(enc, sorts): return RefHandler.get_element_class( + enc, RefHandler.get_const(arg1.value, sorts)) + + if arg2.type == "CLASS": + def arg2_ret(enc, _): return RefHandler.get_class(enc, arg2.value) + else: + def arg2_ret(enc, sorts): return RefHandler.get_element_class( + enc, RefHandler.get_const(arg2.value, sorts)) + + return (arg1_ret, arg2_ret) + + def equality(self, args): + a, b = self._get_equality_sides(args[0], args[1]) + return lambda enc, sorts: a(enc, sorts) == b(enc, sorts) + + def inequality(self, args): + a, b = self._get_equality_sides(args[0], args[1]) + return lambda enc, sorts: a(enc, sorts) != b(enc, sorts) + + def const_or_class(self, args): + if args[0].type == "CONST": + self.const_store.use(args[0].value) + return args[0] + + def compare_int(self, sorts: SMTSorts, op: str, a, b): + # To extract the `int` contained in the attr_data_sort, + # we need to call its `get_int` method on the `DatatypeRef` + get_int = sorts.attr_data_sort.get_int + + a = get_int(a) + b = get_int(b) + + if op == ">": + return a > b + if op == ">=": + return a >= b + if op == "<": + return a < b + if op == "<=": + return a <= b + if op == "==": + return a == b + if op == "!=": + return a != b + raise f"Invalid Compare Operator Symbol: {op}" + + def value(self, args): + type = args[0].type + value = args[0].value + + if type == "ESCAPED_STRING": + value = value.replace('"', '') + self.user_values_cache.add(value) + return lambda enc, sorts: RefHandler.get_str(value, enc, sorts), RefHandler.STRING + elif type == "NUMBER": + return lambda _, sorts: RefHandler.get_int(value, sorts), RefHandler.INTEGER + elif type == "BOOL": + return lambda _, sorts: RefHandler.get_bool(value, sorts), RefHandler.BOOLEAN + # elif type == "VALUE": + # return lambda _, sorts: RefHandler.get_value(value, sorts), RefHandler.VALUE_REF + + def error_desc(self, args): + def err_callback( + solver: Solver, + sorts: SMTSorts, + intermediate_model: IntermediateModel, + index: int, + requirement_desc: str + ) -> str: + err_msg = args[0].value.replace('"', '') + # Get list of free variables + consts_name = self.const_store.get_free_vars(index) + consts = RefHandler.get_consts(consts_name, sorts) + notes = [] + try: + model = solver.model() + for const in consts: + name = get_user_friendly_name( + intermediate_model, model, const) + err_msg = err_msg.replace( + "{" + str(const) + "}", f"'{name}'") + except: + notes.append( + "Model not found: it's not possible to show which element is causing the issue") + + # tell the user which variables are not free + unused_free_vars = re.findall(r"{[^{}]*}", err_msg) + if unused_free_vars: + notes.append( + "The following variables are not free and should be removed from the error description: " + " ".join(unused_free_vars)) + + return (requirement_desc, err_msg, notes) + return ("USER", err_callback) diff --git a/mc_openapi/doml_mc/domlr_parser/utils.py b/mc_openapi/doml_mc/domlr_parser/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b52a2ae01a01ce7472fb18276a0f4fb0b0c6ab57 --- /dev/null +++ b/mc_openapi/doml_mc/domlr_parser/utils.py @@ -0,0 +1,166 @@ +from difflib import get_close_matches + +from mc_openapi.doml_mc.domlr_parser.exceptions import \ + RequirementMissingKeyException +from mc_openapi.doml_mc.imc import SMTEncoding, SMTSorts +from z3 import Const, DatatypeRef, ExprRef, FuncDeclRef, SortRef, Ints, And +from doml_synthesis import State, AssocRel, AttrRel + +class StringValuesCache: + def __init__(self) -> None: + self.values: set[str] = set() + + def add(self, value: str): + self.values.add(value) + + def get_list(self): + return list(self.values) + +class VarStore: + """This class provides a way to instance a Z3 variable only the first time + it's called, and subsequent uses of that variable simply retrieve it + from the store. + """ + + def __init__(self): + self.expressions: list[dict[str, bool]] = [] + self.curr_vars: dict[str, bool] = dict() + self.curr_index: int = 0 + + def use(self, name: str): + self.curr_vars[name] = self.curr_vars.get(name, False) + + def quantify(self, name: str): + self.curr_vars[name] = True + + def get_index_and_push(self): + self.expressions.append(self.curr_vars) + self.curr_vars = dict() + + self.curr_index += 1 + return self.curr_index - 1 + + def get_free_vars(self, index: int) -> list[ExprRef]: + vars = self.expressions[index] + if not vars: + return [] + free_vars = [key for key, val in vars.items() if not val] + return free_vars + + +class RefHandler: + """A utility class that provides simplified ways to create Z3 Refs. + """ + + def get_consts(names: list[str], sorts: SMTSorts): + return [Const(name, sorts.element_sort) for name in names] + + def get_const(name: str, sorts: SMTSorts): + return Const(name, sorts.element_sort) + + def get_value(name: str, sorts: SMTSorts): + return Const(name, sorts.attr_data_sort) + + def get_int(value: str, sorts: SMTSorts): + return sorts.attr_data_sort.int(int(value)) + + def get_bool(value: str, sorts: SMTSorts): + return sorts.attr_data_sort.bool(value == "!True") + + def get_str(value: str, enc: SMTEncoding, sorts: SMTSorts): + return sorts.attr_data_sort.str(enc.str_symbols[value]) + + def get_element_class(enc: SMTEncoding, const: ExprRef) -> FuncDeclRef: + return enc.element_class_fun(const) + + def get_class(enc: SMTEncoding, class_name: str) -> DatatypeRef: + class_name = _convert_rel_str(class_name) + _class = enc.classes.get(class_name, None) + if _class is not None: + return _class + else: + close_matches = get_close_matches(class_name, enc.classes.keys()) + raise RequirementMissingKeyException("class", class_name, close_matches) + + ASSOCIATION = 0 + ATTRIBUTE = 1 + + INTEGER = 2 + BOOLEAN = 3 + STRING = 4 + + def get_relationship(enc: SMTEncoding, rel_name: str) -> tuple[DatatypeRef, int]: + rel_name = _convert_rel_str(rel_name) + rel = enc.associations.get(rel_name, None) + if rel is not None: + return rel, RefHandler.ASSOCIATION + else: + rel = enc.attributes.get(rel_name, None) + if rel is not None: + return rel, RefHandler.ATTRIBUTE + else: + close_matches = get_close_matches(rel_name, list(enc.associations.keys()) + list(enc.attributes.keys())) + raise RequirementMissingKeyException("relationship", rel_name, close_matches) + + def get_association_rel(enc: SMTEncoding, a: ExprRef, rel: DatatypeRef, b: ExprRef) -> DatatypeRef: + return enc.association_rel(a, rel, b) + + def get_attribute_rel(enc: SMTEncoding, a: ExprRef, rel: DatatypeRef, b: ExprRef) -> DatatypeRef: + return enc.attribute_rel(a, rel, b) + +class SynthesisRefHandler: + """A utility class that provides simplified ways to create Z3 Refs. + To be used when parsing requirements for synthesis + """ + + INTEGER = 2 + BOOLEAN = 3 + STRING = 4 + + def get_consts(names: list[str], state: State): + return [Const(name, state.sorts.Elem) for name in names] + + def get_const(name: str, state: State): + return Const(name, state.sorts.Elem) + + def get_bool(value: str): + return value == "!True" + + def get_str(value: str, state: State): + return state.data.Strings[value] + + def get_element_class(state: State, const: ExprRef) -> FuncDeclRef: + return state.rels.ElemClass(const) + + def get_class(state: State, class_name: str) -> DatatypeRef: + class_name = _convert_rel_str(class_name) + _class = state.data.Classes.get(class_name, None) + if _class is not None: + return _class.ref + else: + close_matches = get_close_matches(class_name, state.data.Classes.keys()) + raise RequirementMissingKeyException("class", class_name, close_matches) + + def get_assoc(state: State, rel_name: str) -> AssocRel: + rel_name = _convert_rel_str(rel_name) + rel = state.data.Assocs.get(rel_name, None) + if rel is not None: + return rel + else: + raise f"Association {rel_name} not present in the metamodel!" + + def get_attr(state: State, rel_name: str) -> AttrRel: + rel_name = _convert_rel_str(rel_name) + rel = state.data.Attrs.get(rel_name, None) + if rel is not None: + return rel + else: + raise f"Attribute {rel_name} not present in the metamodel!" + +def _convert_rel_str(rel: str) -> str: + tokens = rel.replace("abstract", "infrastructure").split(".") + if len(tokens) == 2: + return tokens[0] + "_" + tokens[1] + if len(tokens) == 3: + return tokens[0] + "_" + tokens[1] + "::" + tokens[2] + raise f"Bad relationship name: {rel}" diff --git a/mc_openapi/doml_mc/error_desc_helper.py b/mc_openapi/doml_mc/error_desc_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..abf13dd44346a26b4469b2840480ea8f603affa7 --- /dev/null +++ b/mc_openapi/doml_mc/error_desc_helper.py @@ -0,0 +1,15 @@ +from z3 import ExprRef, ModelRef +from typing import Optional +from mc_openapi.doml_mc.intermediate_model import IntermediateModel + +def get_user_friendly_name( + intermediate_model: IntermediateModel, + model: ModelRef, + const: ExprRef +) -> Optional[str]: + z3_elem = model[const] + if z3_elem is not None: + im_elem = intermediate_model.get(str(z3_elem)) + if im_elem is not None: + return im_elem.user_friendly_name + return None diff --git a/mc_openapi/doml_mc/example.ipynb b/mc_openapi/doml_mc/example.ipynb deleted file mode 100644 index adef80b5a80d287751bc399eea1f718386d55660..0000000000000000000000000000000000000000 --- a/mc_openapi/doml_mc/example.ipynb +++ /dev/null @@ -1,995 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n", - "import yaml\n", - "with open(\"../assets/doml_meta.yaml\") as mmf:\n", - " mmdoc = yaml.load(mmf, yaml.Loader)\n", - "mm = parse_metamodel(mmdoc)\n", - "inv_assoc = parse_inverse_associations(mmdoc)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import prettyprinter as pp\n", - "from prettyprinter.prettyprinter import IMPLICIT_MODULES\n", - "pp.install_extras(include=['dataclasses'])" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "mc_openapi.doml_mc.intermediate_model.metamodel.DOMLClass(\n", - " name='application_SoftwareComponent',\n", - " superclass='application_ApplicationComponent',\n", - " attributes={\n", - " 'isPersistent': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n", - " name='isPersistent',\n", - " type='Boolean',\n", - " multiplicity=('1', '1'),\n", - " default=False\n", - " ),\n", - " 'licenseCost': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n", - " name='licenseCost',\n", - " type='String',\n", - " multiplicity=('0', '1'),\n", - " default=None\n", - " ),\n", - " 'configFile': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n", - " name='configFile',\n", - " type='String',\n", - " multiplicity=('0', '1'),\n", - " default=None\n", - " )\n", - " },\n", - " associations={\n", - " 'exposedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n", - " name='exposedInterfaces',\n", - " class_='application_SoftwareInterface',\n", - " multiplicity=('0', '*')\n", - " ),\n", - " 'consumedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n", - " name='consumedInterfaces',\n", - " class_='application_SoftwareInterface',\n", - " multiplicity=('0', '*')\n", - " )\n", - " }\n", - ")\n" - ] - } - ], - "source": [ - "IMPLICIT_MODULES.add('doml_mc.intermediate_model.metamodel')\n", - "pp.pprint(mm[\"application_SoftwareComponent\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Load the DOML document here:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'source_code': DOMLElement(name='source_code', class_='commons_SProperty', attributes={'commons_Property::key': 'source_code', 'commons_SProperty::value': '/usr/share/nginx/html/index.html'}, associations={}), 'nginx': DOMLElement(name='nginx', class_='application_SoftwareComponent', attributes={'application_SoftwareComponent::isPersistent': False, 'commons_DOMLElement::name': 'nginx'}, associations={'commons_DOMLElement::annotations': {'source_code'}}), 'app': DOMLElement(name='app', class_='application_ApplicationLayer', attributes={'commons_DOMLElement::name': 'app'}, associations={'application_ApplicationLayer::components': {'nginx'}}), 'ssh_key': DOMLElement(name='ssh_key', class_='infrastructure_KeyPair', attributes={'infrastructure_KeyPair::algorithm': 'RSA', 'infrastructure_KeyPair::keyfile': '/home/user1/.ssh/openstack.key', 'infrastructure_KeyPair::bits': 4096, 'infrastructure_KeyPair::user': 'ubuntu', 'commons_DOMLElement::name': 'ssh_key'}, associations={}), 'out_all': DOMLElement(name='out_all', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': '-1', 'infrastructure_Rule::toPort': 0, 'infrastructure_Rule::fromPort': 0, 'commons_DOMLElement::name': 'out_all', 'infrastructure_Rule::kind': 'EGRESS'}, associations={}), 'http': DOMLElement(name='http', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 80, 'infrastructure_Rule::fromPort': 80, 'commons_DOMLElement::name': 'http', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'https': DOMLElement(name='https', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 443, 'infrastructure_Rule::fromPort': 443, 'commons_DOMLElement::name': 'https', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'ssh': DOMLElement(name='ssh', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 22, 'infrastructure_Rule::fromPort': 22, 'commons_DOMLElement::name': 'ssh', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'net1': DOMLElement(name='net1', class_='infrastructure_VPC', attributes={'infrastructure_Network::address_lb': 268435456, 'infrastructure_Network::address_ub': 268435711, 'infrastructure_Network::protocol': 'tcp/ip', 'commons_DOMLElement::name': 'net1'}, associations={'infrastructure_Network::connectedIfaces': {'i1'}}), 'i1': DOMLElement(name='i1', class_='infrastructure_NetworkInterface', attributes={'infrastructure_NetworkInterface::endPoint': 268435457, 'commons_DOMLElement::name': 'i1'}, associations={'infrastructure_NetworkInterface::belongsTo': {'net1'}, 'infrastructure_NetworkInterface::associated': {'sg'}}), 'sg': DOMLElement(name='sg', class_='infrastructure_SecurityGroup', attributes={'commons_DOMLElement::name': 'sg'}, associations={'infrastructure_SecurityGroup::rules': {'https', 'ssh', 'http', 'out_all'}, 'infrastructure_ComputingGroup::groupedNodes': {'vm1'}, 'infrastructure_SecurityGroup::ifaces': {'i1'}}), 'vm1': DOMLElement(name='vm1', class_='infrastructure_VirtualMachine', attributes={'commons_DOMLElement::name': 'vm1'}, associations={'infrastructure_ComputingNode::credentials': {'ssh_key'}, 'infrastructure_ComputingNode::group': {'sg'}, 'infrastructure_VirtualMachine::generatedFrom': {'v_img'}, 'infrastructure_ComputingNode::ifaces': {'i1'}}), 'v_img': DOMLElement(name='v_img', class_='infrastructure_VMImage', attributes={'infrastructure_ComputingNodeGenerator::kind': 'SCRIPT', 'commons_DOMLElement::name': 'v_img'}, associations={'infrastructure_VMImage::generatedVMs': {'vm1'}}), 'ag': DOMLElement(name='ag', class_='infrastructure_AutoScalingGroup', attributes={'infrastructure_AutoScalingGroup::loadBalancer': 'DEFAULT', 'infrastructure_AutoScalingGroup::min': 1, 'commons_DOMLElement::name': 'ag', 'infrastructure_AutoScalingGroup::max': 1}, associations={'infrastructure_AutoScalingGroup::deploymentNetwork': {'net1'}, 'infrastructure_AutoScalingGroup::machineDefinition': {'vm1'}}), 'infra': DOMLElement(name='infra', class_='infrastructure_InfrastructureLayer', attributes={'commons_DOMLElement::name': 'infra'}, associations={'infrastructure_InfrastructureLayer::generators': {'v_img'}, 'infrastructure_InfrastructureLayer::networks': {'net1'}, 'infrastructure_InfrastructureLayer::credentials': {'ssh_key'}, 'infrastructure_InfrastructureLayer::secGroups': {'sg'}, 'infrastructure_InfrastructureLayer::nodes': {'ag'}}), 'vm_name': DOMLElement(name='vm_name', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_name', 'commons_SProperty::value': 'nginx-host'}, associations={}), 'vm_flavor': DOMLElement(name='vm_flavor', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_flavor', 'commons_SProperty::value': 'small'}, associations={}), 'vm_key_name': DOMLElement(name='vm_key_name', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_key_name', 'commons_SProperty::value': 'user1'}, associations={}), 'concrete_vm': DOMLElement(name='concrete_vm', class_='concrete_VirtualMachine', attributes={'commons_DOMLElement::name': 'concrete_vm'}, associations={'commons_DOMLElement::annotations': {'vm_flavor', 'vm_name', 'vm_key_name'}, 'concrete_VirtualMachine::maps': {'vm1'}}), 'name': DOMLElement(name='name', class_='commons_SProperty', attributes={'commons_Property::key': 'name', 'commons_SProperty::value': 'ostack2'}, associations={}), 'concrete_net': DOMLElement(name='concrete_net', class_='concrete_Network', attributes={'commons_DOMLElement::name': 'concrete_net'}, associations={'commons_DOMLElement::annotations': {'name'}, 'concrete_Network::maps': {'net1'}}), 'concrete_vm_image': DOMLElement(name='concrete_vm_image', class_='concrete_VMImage', attributes={'commons_DOMLElement::name': 'concrete_vm_image'}, associations={'commons_DOMLElement::annotations': {'name'}, 'concrete_VMImage::maps': {'v_img'}}), 'openstack': DOMLElement(name='openstack', class_='concrete_RuntimeProvider', attributes={'commons_DOMLElement::name': 'openstack'}, associations={'concrete_RuntimeProvider::vms': {'concrete_vm'}, 'concrete_RuntimeProvider::networks': {'concrete_net'}, 'concrete_RuntimeProvider::vmImages': {'concrete_vm_image'}}), 'con_infra': DOMLElement(name='con_infra', class_='concrete_ConcreteInfrastructure', attributes={'commons_DOMLElement::name': 'con_infra'}, associations={'concrete_ConcreteInfrastructure::providers': {'openstack'}})}\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Attribute addressRanges of multiplicity > 1 not supported yet.\n", - "Attribute addressRanges of multiplicity > 1 not supported yet.\n", - "Attribute addressRanges of multiplicity > 1 not supported yet.\n", - "Attribute addressRanges of multiplicity > 1 not supported yet.\n" - ] - } - ], - "source": [ - "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n", - "doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n", - "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n", - "with open(doml_document_path, \"rb\") as xmif:\n", - " doc = xmif.read()\n", - "\n", - "im = parse_doml_model(doc, mm)\n", - "print(im)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n", - "doml_xmi = parse_xmi_model(doc)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['abstract', 'allInstances', 'defaultValue', 'eAllAttributes', 'eAllOperations', 'eAllReferences', 'eAllStructuralFeatures', 'eAllSuperTypes', 'eAnnotations', 'eAttributes', 'eGenericSuperTypes', 'eOperations', 'ePackage', 'eReferences', 'eStructuralFeatures', 'eSuperTypes', 'eTypeParameters', 'eURIFragment', 'findEOperation', 'findEStructuralFeature', 'getEAnnotation', 'instanceClass', 'instanceClassName', 'instanceTypeName', 'interface', 'name', 'notifyChanged']\n", - "infrastructure\n", - "0\n", - "<EClass name=\"ConcreteInfrastructure\">\n" - ] - } - ], - "source": [ - "print(dir(doml_xmi.eClass))\n", - "print(doml_xmi.infrastructure.eClass.ePackage.name)\n", - "print(doml_xmi.infrastructure.eClass.eAllReferences().pop().lower)\n", - "print(doml_xmi.activeInfrastructure.eClass)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "from mc_openapi.doml_mc.intermediate_model.doml_element import reciprocate_inverse_associations\n", - "reciprocate_inverse_associations(im, inv_assoc)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " 'source_code': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='source_code',\n", - " class_='commons_SProperty',\n", - " attributes={\n", - " 'commons_Property::key': 'source_code',\n", - " 'commons_SProperty::value': '/usr/share/nginx/html/index.html'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'nginx': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='nginx',\n", - " class_='application_SoftwareComponent',\n", - " attributes={\n", - " 'application_SoftwareComponent::isPersistent': False,\n", - " 'commons_DOMLElement::name': 'nginx'\n", - " },\n", - " associations={'commons_DOMLElement::annotations': {'source_code'}}\n", - " ),\n", - " 'app': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='app',\n", - " class_='application_ApplicationLayer',\n", - " attributes={'commons_DOMLElement::name': 'app'},\n", - " associations={'application_ApplicationLayer::components': {'nginx'}}\n", - " ),\n", - " 'ssh_key': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='ssh_key',\n", - " class_='infrastructure_KeyPair',\n", - " attributes={\n", - " 'infrastructure_KeyPair::algorithm': 'RSA',\n", - " 'infrastructure_KeyPair::keyfile': '/home/user1/.ssh/openstack.key',\n", - " 'infrastructure_KeyPair::bits': 4096,\n", - " 'infrastructure_KeyPair::user': 'ubuntu',\n", - " 'commons_DOMLElement::name': 'ssh_key'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'out_all': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='out_all',\n", - " class_='infrastructure_Rule',\n", - " attributes={\n", - " 'infrastructure_Rule::protocol': '-1',\n", - " 'infrastructure_Rule::toPort': 0,\n", - " 'infrastructure_Rule::fromPort': 0,\n", - " 'commons_DOMLElement::name': 'out_all',\n", - " 'infrastructure_Rule::kind': 'EGRESS'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'http': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='http',\n", - " class_='infrastructure_Rule',\n", - " attributes={\n", - " 'infrastructure_Rule::protocol': 'tcp',\n", - " 'infrastructure_Rule::toPort': 80,\n", - " 'infrastructure_Rule::fromPort': 80,\n", - " 'commons_DOMLElement::name': 'http',\n", - " 'infrastructure_Rule::kind': 'INGRESS'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'https': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='https',\n", - " class_='infrastructure_Rule',\n", - " attributes={\n", - " 'infrastructure_Rule::protocol': 'tcp',\n", - " 'infrastructure_Rule::toPort': 443,\n", - " 'infrastructure_Rule::fromPort': 443,\n", - " 'commons_DOMLElement::name': 'https',\n", - " 'infrastructure_Rule::kind': 'INGRESS'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'ssh': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='ssh',\n", - " class_='infrastructure_Rule',\n", - " attributes={\n", - " 'infrastructure_Rule::protocol': 'tcp',\n", - " 'infrastructure_Rule::toPort': 22,\n", - " 'infrastructure_Rule::fromPort': 22,\n", - " 'commons_DOMLElement::name': 'ssh',\n", - " 'infrastructure_Rule::kind': 'INGRESS'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'net1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='net1',\n", - " class_='infrastructure_VPC',\n", - " attributes={\n", - " 'infrastructure_Network::address_lb': 268435456,\n", - " 'infrastructure_Network::address_ub': 268435711,\n", - " 'infrastructure_Network::protocol': 'tcp/ip',\n", - " 'commons_DOMLElement::name': 'net1'\n", - " },\n", - " associations={'infrastructure_Network::connectedIfaces': {'i1'}}\n", - " ),\n", - " 'i1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='i1',\n", - " class_='infrastructure_NetworkInterface',\n", - " attributes={\n", - " 'infrastructure_NetworkInterface::endPoint': 268435457,\n", - " 'commons_DOMLElement::name': 'i1'\n", - " },\n", - " associations={\n", - " 'infrastructure_NetworkInterface::belongsTo': {'net1'},\n", - " 'infrastructure_NetworkInterface::associated': {'sg'}\n", - " }\n", - " ),\n", - " 'sg': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='sg',\n", - " class_='infrastructure_SecurityGroup',\n", - " attributes={'commons_DOMLElement::name': 'sg'},\n", - " associations={\n", - " 'infrastructure_SecurityGroup::rules': {\n", - " 'https',\n", - " 'ssh',\n", - " 'http',\n", - " 'out_all'\n", - " },\n", - " 'infrastructure_ComputingGroup::groupedNodes': {'vm1'},\n", - " 'infrastructure_SecurityGroup::ifaces': {'i1'}\n", - " }\n", - " ),\n", - " 'vm1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='vm1',\n", - " class_='infrastructure_VirtualMachine',\n", - " attributes={'commons_DOMLElement::name': 'vm1'},\n", - " associations={\n", - " 'infrastructure_ComputingNode::credentials': {'ssh_key'},\n", - " 'infrastructure_ComputingNode::group': {'sg'},\n", - " 'infrastructure_VirtualMachine::generatedFrom': {'v_img'},\n", - " 'infrastructure_ComputingNode::ifaces': {'i1'}\n", - " }\n", - " ),\n", - " 'v_img': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='v_img',\n", - " class_='infrastructure_VMImage',\n", - " attributes={\n", - " 'infrastructure_ComputingNodeGenerator::kind': 'SCRIPT',\n", - " 'commons_DOMLElement::name': 'v_img'\n", - " },\n", - " associations={'infrastructure_VMImage::generatedVMs': {'vm1'}}\n", - " ),\n", - " 'ag': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='ag',\n", - " class_='infrastructure_AutoScalingGroup',\n", - " attributes={\n", - " 'infrastructure_AutoScalingGroup::loadBalancer': 'DEFAULT',\n", - " 'infrastructure_AutoScalingGroup::min': 1,\n", - " 'commons_DOMLElement::name': 'ag',\n", - " 'infrastructure_AutoScalingGroup::max': 1\n", - " },\n", - " associations={\n", - " 'infrastructure_AutoScalingGroup::deploymentNetwork': {'net1'},\n", - " 'infrastructure_AutoScalingGroup::machineDefinition': {'vm1'}\n", - " }\n", - " ),\n", - " 'infra': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='infra',\n", - " class_='infrastructure_InfrastructureLayer',\n", - " attributes={'commons_DOMLElement::name': 'infra'},\n", - " associations={\n", - " 'infrastructure_InfrastructureLayer::generators': {'v_img'},\n", - " 'infrastructure_InfrastructureLayer::networks': {'net1'},\n", - " 'infrastructure_InfrastructureLayer::credentials': {'ssh_key'},\n", - " 'infrastructure_InfrastructureLayer::secGroups': {'sg'},\n", - " 'infrastructure_InfrastructureLayer::nodes': {'ag'}\n", - " }\n", - " ),\n", - " 'vm_name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='vm_name',\n", - " class_='commons_SProperty',\n", - " attributes={\n", - " 'commons_Property::key': 'vm_name',\n", - " 'commons_SProperty::value': 'nginx-host'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'vm_flavor': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='vm_flavor',\n", - " class_='commons_SProperty',\n", - " attributes={\n", - " 'commons_Property::key': 'vm_flavor',\n", - " 'commons_SProperty::value': 'small'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'vm_key_name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='vm_key_name',\n", - " class_='commons_SProperty',\n", - " attributes={\n", - " 'commons_Property::key': 'vm_key_name',\n", - " 'commons_SProperty::value': 'user1'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'concrete_vm': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='concrete_vm',\n", - " class_='concrete_VirtualMachine',\n", - " attributes={'commons_DOMLElement::name': 'concrete_vm'},\n", - " associations={\n", - " 'commons_DOMLElement::annotations': {\n", - " 'vm_flavor',\n", - " 'vm_name',\n", - " 'vm_key_name'\n", - " },\n", - " 'concrete_VirtualMachine::maps': {'vm1'}\n", - " }\n", - " ),\n", - " 'name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='name',\n", - " class_='commons_SProperty',\n", - " attributes={\n", - " 'commons_Property::key': 'name',\n", - " 'commons_SProperty::value': 'ostack2'\n", - " },\n", - " associations={}\n", - " ),\n", - " 'concrete_net': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='concrete_net',\n", - " class_='concrete_Network',\n", - " attributes={'commons_DOMLElement::name': 'concrete_net'},\n", - " associations={\n", - " 'commons_DOMLElement::annotations': {'name'},\n", - " 'concrete_Network::maps': {'net1'}\n", - " }\n", - " ),\n", - " 'concrete_vm_image': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='concrete_vm_image',\n", - " class_='concrete_VMImage',\n", - " attributes={'commons_DOMLElement::name': 'concrete_vm_image'},\n", - " associations={\n", - " 'commons_DOMLElement::annotations': {'name'},\n", - " 'concrete_VMImage::maps': {'v_img'}\n", - " }\n", - " ),\n", - " 'openstack': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='openstack',\n", - " class_='concrete_RuntimeProvider',\n", - " attributes={'commons_DOMLElement::name': 'openstack'},\n", - " associations={\n", - " 'concrete_RuntimeProvider::vms': {'concrete_vm'},\n", - " 'concrete_RuntimeProvider::networks': {'concrete_net'},\n", - " 'concrete_RuntimeProvider::vmImages': {'concrete_vm_image'}\n", - " }\n", - " ),\n", - " 'con_infra': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n", - " name='con_infra',\n", - " class_='concrete_ConcreteInfrastructure',\n", - " attributes={'commons_DOMLElement::name': 'con_infra'},\n", - " associations={\n", - " 'concrete_ConcreteInfrastructure::providers': {'openstack'}\n", - " }\n", - " )\n", - "}\n" - ] - } - ], - "source": [ - "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n", - "pp.pprint(im)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "unbound_elems_n = 0\n", - "unbound_elems = [f\"unbound{i}\" for i in range(unbound_elems_n)]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "from z3 import Solver\n", - "\n", - "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n", - " def_association_rel_and_assert_constraints,\n", - " def_attribute_rel_and_assert_constraints,\n", - " mk_association_sort_dict,\n", - " mk_attribute_sort_dict,\n", - " mk_class_sort_dict\n", - ")\n", - "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n", - " assert_im_associations_q,\n", - " assert_im_attributes,\n", - " def_elem_class_f_and_assert_classes,\n", - " mk_elem_sort_dict,\n", - " mk_stringsym_sort_dict\n", - ")\n", - "from mc_openapi.doml_mc.z3encoding.utils import mk_adata_sort\n", - "\n", - "solver = Solver()\n", - "\n", - "class_sort, class_ = mk_class_sort_dict(mm)\n", - "assoc_sort, assoc = mk_association_sort_dict(mm)\n", - "attr_sort, attr = mk_attribute_sort_dict(mm)\n", - "elem_sort, elem = mk_elem_sort_dict(im, unbound_elems)\n", - "ss_sort, ss = mk_stringsym_sort_dict(im, mm)\n", - "AData = mk_adata_sort(ss_sort)\n", - "elem_class_f = def_elem_class_f_and_assert_classes(\n", - " im,\n", - " solver,\n", - " elem_sort,\n", - " elem,\n", - " class_sort,\n", - " class_\n", - ")\n", - "attr_rel = def_attribute_rel_and_assert_constraints(\n", - " mm,\n", - " solver,\n", - " attr_sort,\n", - " attr,\n", - " class_,\n", - " elem_class_f,\n", - " elem_sort,\n", - " AData,\n", - " ss\n", - ")\n", - "assert_im_attributes(\n", - " attr_rel,\n", - " solver,\n", - " im,\n", - " mm,\n", - " elem,\n", - " attr_sort,\n", - " attr,\n", - " AData,\n", - " ss\n", - ")\n", - "assoc_rel = def_association_rel_and_assert_constraints(\n", - " mm,\n", - " solver,\n", - " assoc_sort,\n", - " assoc,\n", - " class_,\n", - " elem_class_f,\n", - " elem_sort,\n", - " inv_assoc\n", - ")\n", - "assert_im_associations_q(\n", - " assoc_rel,\n", - " solver,\n", - " {k: v for k, v in im.items() if k not in unbound_elems},\n", - " elem,\n", - " assoc_sort,\n", - " assoc,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# solver.push()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Metamodel statistics" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of classes: 48\n", - "Number of tuples in the subclass relation: 125\n", - "Number of attributes: 46\n", - "Number of attribute assertions: 138\n", - "Number of associations: 54\n", - "Number of associations assertions: 168\n" - ] - } - ], - "source": [ - "from mc_openapi.doml_mc.intermediate_model.metamodel import get_subclasses_dict\n", - "\n", - "print(\"Number of classes:\", len(mm))\n", - "print(\n", - " \"Number of tuples in the subclass relation:\",\n", - " sum(len(s) for s in get_subclasses_dict(mm).values())\n", - ")\n", - "n_attrs = sum(len(c.attributes) for c in mm.values())\n", - "print(\"Number of attributes:\", n_attrs)\n", - "print(\"Number of attribute assertions:\", 3 * n_attrs)\n", - "n_assocs = sum(len(c.associations) for c in mm.values())\n", - "print(\"Number of associations:\", n_assocs)\n", - "print(\"Number of associations assertions:\", 3 * n_assocs + len(inv_assoc))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### DOML model statistics" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of elements: 24\n", - "Number of attributes (IM): 58\n", - "Number of associations (IM): 35\n", - "Number of string symbols: 40\n", - "Number of IM attribute assertions: 24\n", - "Number of IM association assertions: 576\n" - ] - } - ], - "source": [ - "n_elems = len(im)\n", - "print(\"Number of elements:\", n_elems)\n", - "n_attrs_im = sum(len(e.attributes) for e in im.values())\n", - "print(\"Number of attributes (IM):\", n_attrs_im)\n", - "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n", - "print(\"Number of associations (IM):\", n_assocs_im)\n", - "print(\"Number of string symbols:\", len(ss))\n", - "print(\"Number of IM attribute assertions:\", n_elems)\n", - "print(\"Number of IM association assertions:\", n_elems ** 2)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<b>sat</b>" - ], - "text/plain": [ - "sat" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solver.check()" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "[]" - ], - "text/plain": [ - "[]" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solver.unsat_core()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(:added-eqs 29920\n", - " :arith-make-feasible 8\n", - " :arith-max-columns 11\n", - " :binary-propagations 811\n", - " :conflicts 109\n", - " :datatype-accessor-ax 1114\n", - " :datatype-constructor-ax 11816\n", - " :datatype-splits 1944\n", - " :decisions 86083\n", - " :del-clause 42\n", - " :final-checks 8\n", - " :max-generation 4\n", - " :max-memory 30.88\n", - " :memory 30.88\n", - " :mk-bool-var 4810\n", - " :mk-clause 1138\n", - " :num-allocs 58273624\n", - " :num-checks 1\n", - " :propagations 15765\n", - " :quant-instantiations 1321\n", - " :restarts 3\n", - " :rlimit-count 15307867\n", - " :time 1.88)" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solver.statistics()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "from z3 import Consts, ForAll, Exists, Implies, And, Or" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "# All VMs have a network interface.\n", - "vm, iface = Consts(\n", - " \"vm iface\", elem_sort\n", - ")\n", - "vmIfaceAssertion = ForAll(\n", - " [vm],\n", - " Implies(\n", - " elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n", - " Exists(\n", - " [iface],\n", - " And(\n", - " assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n", - " )\n", - " )\n", - " )\n", - ")\n", - "solver.assert_and_track(vmIfaceAssertion, \"vm_iface\")" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "# nginx has a source code property\n", - "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n", - "nginxSourceCode = ForAll(\n", - " [softwareComponent],\n", - " Implies(\n", - " And(\n", - " elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n", - " attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"nginx\"]))\n", - " ),\n", - " Exists(\n", - " [prop],\n", - " And(\n", - " elem_class_f(prop) == class_[\"commons_SProperty\"],\n", - " attr_rel(prop, attr[\"commons_Property::key\"], AData.ss(ss[\"source_code\"])),\n", - " assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n", - " )\n", - " )\n", - " )\n", - ")\n", - "solver.assert_and_track(nginxSourceCode, \"nginx_source_code\")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<b>sat</b>" - ], - "text/plain": [ - "sat" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solver.check()" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "66.31" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solver.statistics().memory" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[attribute_st_types infrastructure_Rule::toPort = True,\n", - " associations sg out_all = True,\n", - " associations i1 http = True,\n", - " associations ag http = True,\n", - " associations vm_flavor con_infra = True,\n", - " associations openstack concrete_vm_image = True,\n", - " attribute_mult_ub commons_BProperty::value = True,\n", - " associations v_img name = True,\n", - " attribute_mult_lb infrastructure_Rule::kind = True,\n", - " associations vm1 name = True,\n", - " attribute_st_types commons_DOMLElement::name = True,\n", - " association_mult_ub concrete_FunctionAsAService::maps = True,\n", - " associations concrete_vm vm_key_name = True,\n", - " associations app openstack = True,\n", - " association_inverse infrastructure_Container::generatedFrom infrastructure_ContainerImage::generatedContainers = True,\n", - " associations app concrete_vm = True,\n", - " associations out_all v_img = True,\n", - " association_mult_ub infrastructure_Container::generatedFrom = True,\n", - " association_st_classes infrastructure_FunctionAsAService::ifaces = True,\n", - " associations net1 ssh = True,\n", - " associations con_infra con_infra = True,\n", - " associations https concrete_vm = True,\n", - " associations sg ssh = True,\n", - " associations vm_name v_img = True,\n", - " associations ssh_key openstack = True,\n", - " association_st_classes infrastructure_Storage::ifaces = True,\n", - " associations openstack vm_flavor = True,\n", - " associations nginx nginx = True,\n", - " attribute_st_types infrastructure_Rule::addressRanges = True,\n", - " associations vm_flavor v_img = True,\n", - " associations v_img ag = True,\n", - " association_st_classes concrete_ComputingGroup::maps = True,\n", - " attribute_mult_lb infrastructure_Rule::protocol = True,\n", - " associations vm1 ag = True,\n", - " associations ag vm_flavor = True,\n", - " attribute_mult_ub infrastructure_KeyPair::bits = True,\n", - " associations nginx openstack = True,\n", - " associations app sg = True,\n", - " association_mult_ub commons_Property::reference = True,\n", - " associations nginx infra = True,\n", - " associations concrete_net vm_key_name = True,\n", - " associations https concrete_vm_image = True,\n", - " associations v_img vm_name = True,\n", - " associations concrete_net openstack = True,\n", - " attribute_st_types commons_Property::key = True,\n", - " association_mult_ub commons_Deployment::source = True,\n", - " associations concrete_vm_image v_img = True,\n", - " associations source_code https = True,\n", - " associations vm_name vm_flavor = True,\n", - " elem_class concrete_vm concrete_VirtualMachine = True,\n", - " attribute_mult_ub application_SoftwareComponent::isPersistent = True,\n", - " associations https ssh = True,\n", - " associations https vm1 = True,\n", - " associations ag net1 = True,\n", - " associations http source_code = True,\n", - " association_mult_ub concrete_VirtualMachine::maps = True,\n", - " association_st_classes commons_Deployment::target = True,\n", - " associations net1 con_infra = True,\n", - " attribute_st_types concrete_ConcreteElement::configurationScript = True,\n", - " association_mult_ub infrastructure_VirtualMachine::generatedFrom = True,\n", - " associations http vm_key_name = True,\n", - " associations vm_name infra = True,\n", - " associations ag source_code = True,\n", - " associations vm_key_name net1 = True,\n", - " attribute_st_types infrastructure_ComputingNode::cost = True,\n", - " association_mult_ub infrastructure_NetworkInterface::belongsTo = True,\n", - " associations infra ssh = True,\n", - " associations out_all concrete_net = True,\n", - " associations sg source_code = True,\n", - " association_inverse infrastructure_ComputingGroup::groupedNodes infrastructure_ComputingNode::group = True,\n", - " associations concrete_vm_image infra = True,\n", - " associations source_code out_all = True,\n", - " associations ssh sg = True,\n", - " associations ssh name = True,\n", - " associations http ag = True,\n", - " associations out_all concrete_vm_image = True,\n", - " association_st_classes concrete_VMImage::maps = True,\n", - " associations vm1 openstack = True,\n", - " associations v_img source_code = True,\n", - " elem_class ssh_key infrastructure_KeyPair = True,\n", - " associations vm_flavor app = True,\n", - " associations concrete_vm net1 = True,\n", - " associations vm_name http = True,\n", - " associations app out_all = True,\n", - " associations vm_key_name name = True,\n", - " attribute_st_types infrastructure_KeyPair::keyfile = True,\n", - " associations v_img nginx = True,\n", - " associations v_img concrete_net = True,\n", - " attribute_st_types infrastructure_KeyPair::user = True,\n", - " associations http concrete_vm = True,\n", - " association_mult_ub commons_Deployment::target = True,\n", - " associations ssh app = True,\n", - " associations ssh vm_name = True,\n", - " associations source_code ssh_key = True,\n", - " associations vm1 ssh_key = True,\n", - " associations nginx vm_name = True,\n", - " associations http https = True,\n", - " attribute_values vm_key_name = True,\n", - " associations ssh_key concrete_net = True,\n", - " associations infra i1 = True,\n", - " associations https https = True,\n", - " attribute_st_types infrastructure_Rule::fromPort = True,\n", - " associations nginx vm_key_name = True,\n", - " associations app nginx = True,\n", - " associations v_img v_img = True,\n", - " associations sg http = True,\n", - " associations con_infra nginx = True,\n", - " associations con_infra https = True,\n", - " elem_class name commons_SProperty = True,\n", - " attribute_mult_ub infrastructure_AutoScalingGroup::max = True,\n", - " association_mult_lb concrete_ComputingGroup::maps = True,\n", - " attribute_mult_ub application_SoftwareComponent::configFile = True,\n", - " associations net1 ag = True,\n", - " association_mult_lb commons_Deployment::target = True,\n", - " attribute_values con_infra = True,\n", - " association_mult_ub concrete_ContainerImage::maps = True,\n", - " associations vm_flavor vm_name = True,\n", - " associations v_img concrete_vm = True,\n", - " associations concrete_vm ssh = True,\n", - " associations concrete_vm v_img = True,\n", - " attribute_st_types application_SoftwareComponent::configFile = True,\n", - " attribute_mult_ub infrastructure_AutoScalingGroup::loadBalancer = True,\n", - " associations vm1 v_img = True,\n", - " association_st_classes infrastructure_InfrastructureLayer::generators = True,\n", - " attribute_mult_ub infrastructure_ComputingNode::cost = True,\n", - " attribute_st_types application_SoftwareComponent::licenseCost = True,\n", - " associations ssh vm_key_name = True,\n", - " associations vm1 app = True,\n", - " associations concrete_vm_image name = True,\n", - " ...]\n" - ] - } - ], - "source": [ - "m = solver.model()\n", - "print(m)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "from itertools import product\n", - "for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()):\n", - " if (e1n in unbound_elems or e2n in unbound_elems) and m.eval(assoc_rel(e1, a, e2)):\n", - " print(e1, a, e2)" - ] - } - ], - "metadata": { - "interpreter": { - "hash": "a6678cf6b5907da3ee1c64f7f36cf1b3f0e5fe51f4038e28403f1c01345fc5bd" - }, - "kernelspec": { - "display_name": "Python 3.9.9 64-bit", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/mc_openapi/doml_mc/exceptions.py b/mc_openapi/doml_mc/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..a3284438af998cd6cc9a64f15561918db5694f44 --- /dev/null +++ b/mc_openapi/doml_mc/exceptions.py @@ -0,0 +1,24 @@ +class BadDOMLException(Exception): + def __init__(self, message: str = None, *args: object) -> None: + super().__init__(*args) + self.message = message or "The submitted DOML contains some kind of error." + +class UnsupportedDOMLVersionException(Exception): + def __init__(self, message: str = None, *args: object) -> None: + super().__init__(*args) + self.message = message or "The DOML version is not supported." + +class MissingInfrastructureLayerException(Exception): + def __init__(self, message: str = None, *args: object) -> None: + super().__init__(*args) + self.message = message or "Abstract infrastructure layer is missing from DOML." + +class NoActiveConcreteLayerException(Exception): + def __init__(self, message: str = None, *args: object) -> None: + super().__init__(*args) + self.message = message or "No active concrete infrastructure layer has been specified in DOML." + +class CommonRequirementException(Exception): + def __init__(self, message: str = None, *args: object) -> None: + super().__init__(*args) + self.message = message or "Couldn't get built-in requirements for this DOML version." \ No newline at end of file diff --git a/mc_openapi/doml_mc/imc.py b/mc_openapi/doml_mc/imc.py index 8efd89bdfd1a3e75eeb9f3981e933c2086331e0e..f663d9084f9b867767d7d1d4cb7d46caa223cd39 100644 --- a/mc_openapi/doml_mc/imc.py +++ b/mc_openapi/doml_mc/imc.py @@ -1,25 +1,22 @@ from collections.abc import Callable from dataclasses import dataclass +from typing import Literal -from z3 import ( - Context, FuncDeclRef, Solver, ExprRef, SortRef, DatatypeSortRef -) +from z3 import (Context, DatatypeSortRef, ExprRef, FuncDeclRef, Solver, + SortRef, Z3Exception) from .intermediate_model.doml_element import IntermediateModel -from .z3encoding.im_encoding import ( - assert_im_associations_q, assert_im_attributes, - def_elem_class_f_and_assert_classes, - mk_elem_sort_dict, mk_stringsym_sort_dict -) -from .z3encoding.metamodel_encoding import ( - def_association_rel, - def_attribute_rel, - mk_association_sort_dict, - mk_attribute_sort_dict, mk_class_sort_dict -) -from .z3encoding.types import Refs -from .z3encoding.utils import mk_adata_sort from .mc_result import MCResult, MCResults +from .z3encoding.im_encoding import (assert_im_associations, + assert_im_attributes, + def_elem_class_f_and_assert_classes, mk_attr_data_sort, + mk_elem_sort_dict, mk_stringsym_sort_dict) +from .z3encoding.metamodel_encoding import (def_association_rel, + def_attribute_rel, + mk_association_sort_dict, + mk_attribute_sort_dict, + mk_class_sort_dict) +from .z3encoding.types import Refs @dataclass @@ -46,14 +43,16 @@ class SMTSorts: @dataclass class Requirement: - assert_callable: Callable[[SMTEncoding, SMTSorts], list[ExprRef]] + assert_callable: Callable[[SMTEncoding, SMTSorts], ExprRef] assert_name: str description: str - error_description: str + error_description: tuple[Literal["BUILTIN", "USER"], + Callable[[Solver, SMTSorts, IntermediateModel], str]] + flipped: bool = False class RequirementStore: - def __init__(self, requirements: list[Requirement]): + def __init__(self, requirements: list[Requirement] = []): self.requirements = requirements pass @@ -63,6 +62,9 @@ class RequirementStore: def get_one_requirement(self, index: int) -> Requirement: return self.get_all_requirements()[index] + def skip_requirements_by_id(self, requirement_ids: list[str]): + self.requirements = [r for r in self.requirements if not r.assert_name in requirement_ids] + def __len__(self): return len(self.get_all_requirements()) @@ -72,75 +74,83 @@ class RequirementStore: class IntermediateModelChecker: def __init__(self, metamodel, inv_assoc, intermediate_model: IntermediateModel): - def instantiate_solver(): - self.z3Context = Context() - self.solver = Solver(ctx=self.z3Context) - - class_sort, class_ = mk_class_sort_dict(self.metamodel, self.z3Context) - assoc_sort, assoc = mk_association_sort_dict(self.metamodel, self.z3Context) - attr_sort, attr = mk_attribute_sort_dict(self.metamodel, self.z3Context) - elem_sort, elem = mk_elem_sort_dict(self.intermediate_model, self.z3Context) - ss_sort, ss = mk_stringsym_sort_dict(self.intermediate_model, self.metamodel, self.z3Context) - AData = mk_adata_sort(ss_sort, self.z3Context) - elem_class_f = def_elem_class_f_and_assert_classes( - self.intermediate_model, - self.solver, - elem_sort, - elem, - class_sort, - class_ - ) - attr_rel = def_attribute_rel( - attr_sort, - elem_sort, - AData - ) - assert_im_attributes( - attr_rel, - self.solver, - self.intermediate_model, - self.metamodel, - elem, - attr_sort, - attr, - AData, - ss - ) - assoc_rel = def_association_rel( - assoc_sort, - elem_sort - ) - assert_im_associations_q( - assoc_rel, - self.solver, - {k: v for k, v in self.intermediate_model.items()}, - elem, - assoc_sort, - assoc, - ) - self.smt_encoding = SMTEncoding( - class_, - assoc, - attr, - elem, - ss, - elem_class_f, - attr_rel, - assoc_rel - ) - self.smt_sorts = SMTSorts( - class_sort, - assoc_sort, - attr_sort, - elem_sort, - ss_sort, - AData - ) - self.metamodel = metamodel self.inv_assoc = inv_assoc self.intermediate_model = intermediate_model - instantiate_solver() + self.instantiate_solver() + + def instantiate_solver(self, user_string_values=[]): + self.z3Context = Context() + self.solver = Solver(ctx=self.z3Context) + + class_sort, class_ = mk_class_sort_dict(self.metamodel, self.z3Context) + assoc_sort, assoc = mk_association_sort_dict( + self.metamodel, self.z3Context) + attr_sort, attr = mk_attribute_sort_dict( + self.metamodel, self.z3Context) + elem_sort, elem = mk_elem_sort_dict( + self.intermediate_model, self.z3Context) + str_sort, str = mk_stringsym_sort_dict( + self.intermediate_model, + self.metamodel, + self.z3Context, + user_string_values + ) + attr_data_sort = mk_attr_data_sort(str_sort, self.z3Context) + elem_class_f = def_elem_class_f_and_assert_classes( + self.intermediate_model, + self.solver, + elem_sort, + elem, + class_sort, + class_ + ) + attr_rel = def_attribute_rel( + attr_sort, + elem_sort, + attr_data_sort + ) + assert_im_attributes( + attr_rel, + self.solver, + self.intermediate_model, + self.metamodel, + elem, + attr_sort, + attr, + attr_data_sort, + str + ) + assoc_rel = def_association_rel( + assoc_sort, + elem_sort + ) + assert_im_associations( + assoc_rel, + self.solver, + {k: v for k, v in self.intermediate_model.items()}, + elem, + assoc_sort, + assoc, + ) + self.smt_encoding = SMTEncoding( + class_, + assoc, + attr, + elem, + str, + elem_class_f, + attr_rel, + assoc_rel + ) + self.smt_sorts = SMTSorts( + class_sort, + assoc_sort, + attr_sort, + elem_sort, + str_sort, + attr_data_sort + ) def check_requirements(self, reqs: RequirementStore, timeout: int = 0) -> MCResults: self.solver.set(timeout=(timeout * 1000)) @@ -151,9 +161,25 @@ class IntermediateModelChecker: self.solver.assert_and_track( req.assert_callable(self.smt_encoding, self.smt_sorts), req.assert_name - ) + ) res = self.solver.check() + req_type, req_err_desc_fn = req.error_description + req_is_sat = MCResult.from_z3result(res, flipped=req.flipped) + req_id = req.assert_name + try: + req_time = self.solver.statistics().get_key_value("time") + except Z3Exception: + req_time = "???" + + results.append(( + req_is_sat, + req_type, + req_err_desc_fn(self.solver, self.smt_sorts, self.intermediate_model) if req_is_sat else "", + req_id, + req.description, + req_time + )) self.solver.pop() - results.append((MCResult.from_z3result(res, flipped=True), req.error_description)) + # stats = self.solver.statistics() return MCResults(results) diff --git a/mc_openapi/doml_mc/intermediate_model/__init__.py b/mc_openapi/doml_mc/intermediate_model/__init__.py index 08c3bb217ef949826b63a77c3fb7e7839f02db0d..31b1c03caa88087d5951e85c4aa9458abc210cad 100644 --- a/mc_openapi/doml_mc/intermediate_model/__init__.py +++ b/mc_openapi/doml_mc/intermediate_model/__init__.py @@ -1,2 +1,2 @@ -from .metamodel import MetaModel # noqa: F401 +from .metamodel import DOMLVersion, MetaModel # noqa: F401 from .doml_element import IntermediateModel, DOMLElement # noqa: F401 diff --git a/mc_openapi/doml_mc/intermediate_model/doml_element.py b/mc_openapi/doml_mc/intermediate_model/doml_element.py index be2447bb5484d40ec175977165df06a63a719a29..d5caa8e8d1bcdf5c05ca2e78dcda14fbaf815023 100644 --- a/mc_openapi/doml_mc/intermediate_model/doml_element.py +++ b/mc_openapi/doml_mc/intermediate_model/doml_element.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Union, Optional from dataclasses import dataclass from .metamodel import ( @@ -21,6 +21,7 @@ class DOMLElement: # e.g., `"application_SoftwarePackage::isPersistent"`. attributes: Attributes associations: Associations + user_friendly_name: Optional[str] IntermediateModel = dict[str, "DOMLElement"] diff --git a/mc_openapi/doml_mc/intermediate_model/metamodel.py b/mc_openapi/doml_mc/intermediate_model/metamodel.py index 963f69570d1af65629f37fb841f45fb225b8f8cd..f1ab8f48b11e4514f7c7c0dca8ebd3d109c9fc33 100644 --- a/mc_openapi/doml_mc/intermediate_model/metamodel.py +++ b/mc_openapi/doml_mc/intermediate_model/metamodel.py @@ -1,9 +1,37 @@ +import importlib.resources as ilres from dataclasses import dataclass -from typing import cast, Literal, Optional, Union +from enum import Enum +from typing import Literal, Optional, Union, cast import networkx as nx +import yaml + +from ... import assets +from ..utils import merge_dicts + +class DOMLVersion(Enum): + # V1_0 = "v1.0" + V2_0 = "v2.0" + V2_1 = "v2.1" + V2_2 = "v2.2" + V2_2_1 = "v2.2.1" + V2_3 = "v2.3" + V3_0 = "v3.0" + V3_1 = "v3.1" + + def get(v: str): + """Retrieve DOML version from string. + Try to be less pedantic about versions + e.g.: 2.0 becomes V2_0""" + doml_ver = v.replace(".", "_").replace("v", "V") + if doml_ver[0] != "V": + doml_ver = "V" + doml_ver + return DOMLVersion[doml_ver] + + def has_DOMLR_support(v: "DOMLVersion"): + """DOMLR is available in v2.2 and later""" + return v != DOMLVersion.V2_0 and v != DOMLVersion.V2_1 -from .._utils import merge_dicts Multiplicity = tuple[Literal["0", "1"], Literal["1", "*"]] @@ -40,6 +68,11 @@ class DOMLAssociation: MetaModel = dict[str, DOMLClass] +InverseAssociation = list[tuple[str, str]] + +MetaModelDocs: dict[DOMLVersion, dict] = {} +MetaModels: dict[DOMLVersion, MetaModel] = {} +InverseAssociations: dict[DOMLVersion, InverseAssociation] = {} def parse_metamodel(mmdoc: dict) -> MetaModel: @@ -136,6 +169,17 @@ def parse_inverse_associations(doc: dict) -> list[tuple[str, str]]: ] +def init_metamodels(): + global MetaModelDocs, MetaModels, InverseAssociations + for ver in DOMLVersion: + source = ilres.files(assets).joinpath(f"metamodels/doml_meta_{ver.value}.yaml") + + mmdoc = yaml.load(source.read_text() , yaml.Loader) + MetaModelDocs[ver] = mmdoc + MetaModels[ver] = parse_metamodel(mmdoc) + InverseAssociations[ver] = parse_inverse_associations(mmdoc) + + def _find_association_class( mm: MetaModel, cname: str, diff --git a/mc_openapi/doml_mc/main.py b/mc_openapi/doml_mc/main.py new file mode 100644 index 0000000000000000000000000000000000000000..1d8c8934081bf4e78a17361fb74ac781334051a5 --- /dev/null +++ b/mc_openapi/doml_mc/main.py @@ -0,0 +1,176 @@ +import logging +from typing import Optional + +import doml_synthesis as DOMLS +from doml_synthesis import State, builtin_requirements + +from mc_openapi.doml_mc import ModelChecker +from mc_openapi.doml_mc.common_reqs import CommonRequirements +from mc_openapi.doml_mc.consistency_reqs import get_association_multiplicity_reqs, get_association_type_reqs, get_attribute_multiplicity_reqs, get_attribute_type_reqs, get_inverse_association_reqs +from mc_openapi.doml_mc.csp_compatibility import \ + CSPCompatibilityValidator as CSPCompatibility +from mc_openapi.doml_mc.domlr_parser import (DOMLRTransformer, Parser, + SynthesisDOMLRTransformer) +from mc_openapi.doml_mc.exceptions import CommonRequirementException +from mc_openapi.doml_mc.imc import RequirementStore +from mc_openapi.doml_mc.intermediate_model.metamodel import (DOMLVersion, + MetaModelDocs) +from mc_openapi.doml_mc.network_address_validator.validate import validate_network_address + + +def init_model(domlx:bytes, doml_ver: DOMLVersion): + dmc = ModelChecker(domlx, doml_ver) + logging.info("Parsed DOMLX successfully.") + return dmc + + +def verify_model( + dmc: ModelChecker, + external_domlr: Optional[str] = None, + threads: int = 2, + consistency_checks: bool = False, + skip_builtin_checks: bool = False + ): + # DOMLR parser + domlr_parser = Parser(DOMLRTransformer) + + # General req store + req_store = RequirementStore() + + # Store of Requirements and unique string constants + user_req_store, user_req_str_consts = RequirementStore(), [] + + flags = {} + + # Parse external DOMLR file + if external_domlr: + user_req_store, user_req_str_consts, flags = domlr_parser.parse(external_domlr) + + # Parse internal DOMLR requirements + if DOMLVersion.has_DOMLR_support(dmc.doml_version): + func_reqs = dmc.domlr_requirements + for _, req_text in func_reqs: + doml_req_store, doml_req_str_consts, doml_req_flags = domlr_parser.parse(req_text) + user_req_store += doml_req_store + user_req_str_consts += doml_req_str_consts + flags |= doml_req_flags + + # Remove duplicate tokens + user_req_str_consts = list(set(user_req_str_consts)) + + # Built-in requirements + if not (flags.get('_ignore_builtin', False) or skip_builtin_checks): + try: + req_store += CommonRequirements[dmc.doml_version] + # Skip selected requirements + req_store.skip_requirements_by_id([k for k,v in flags.items() if not k.startswith("_") and v is False]) + except: + logging.error('Failed to get Common Requirements. DOML Version is wrong?') + raise CommonRequirementException() + + # Consistency requirements (disabled by default) + if flags.get('_check_consistency', False) or consistency_checks: + logging.warning("Consistency checks are outdated and may break at any time.") + req_store = req_store \ + + get_attribute_type_reqs(dmc.metamodel) \ + + get_attribute_multiplicity_reqs(dmc.metamodel) \ + + get_association_type_reqs(dmc.metamodel) \ + + get_association_multiplicity_reqs(dmc.metamodel) \ + + get_inverse_association_reqs(dmc.inv_assoc) + + # Add user requirements at the end + req_store += user_req_store + + # Log all requirements to check + logging.debug("Checking following requirements: " + ", ".join([k.assert_name for k in req_store.get_all_requirements()])) + logging.debug("Flags: { " + ", ".join([f"{k}={v}" for k, v in flags.items()]) + " }") + + # Check satisfiability + results = dmc.check_requirements( + req_store, + threads=threads, + user_str_values=user_req_str_consts, + disable_multithreading=(threads == 1) + ) + + res = results.summarize() + + res['doml_version'] = dmc.doml_version.name + res['result'] = res['result'].name + res['type'] = 'message' + + # logging.info(res) + + # Check CSP + if flags.get('_csp', False): + res['csp'] = verify_csp_compatibility(dmc) + + # Validate network + res['net_validation'] = validate_network_address(dmc) + + return res + +def synthesize_model(dmc: ModelChecker, external_domlr: str, max_tries: int): + logging.warn("Synthesis is experimental and might not be up-to-date with the latest DOML.") + + synth_domlr_parser = Parser(SynthesisDOMLRTransformer) + mm = MetaModelDocs[dmc.doml_version] + im = { + k: { + 'id': v.id_, + 'name': v.user_friendly_name, + 'class': v.class_, + 'assocs': v.associations, + 'attrs': v.attributes + } + for k, v in dmc.intermediate_model.items() + } + + user_req_store, user_req_str_consts = [], [] + + + if external_domlr: + user_req_store, user_req_str_consts = synth_domlr_parser.parse(external_domlr, for_synthesis=True) + + + # Parse internal DOMLR requirements + if DOMLVersion.has_DOMLR_support(dmc.doml_version): + func_reqs = dmc.domlr_requirements + for _, req_text in func_reqs: + doml_req_store, doml_req_str_consts, doml_req_flags = synth_domlr_parser.parse(req_text, for_synthesis=True) + user_req_store += doml_req_store + user_req_str_consts += doml_req_str_consts + flags |= doml_req_flags + + # Remove duplicated strings + user_req_str_consts = list(set(user_req_str_consts)) + + state = State() + # Parse MM and IM + state = DOMLS.init_data( + state, + doml=im, + metamodel=mm, + ) + + reqs = user_req_store + + reqs += builtin_requirements + + state = DOMLS.solve( + state, + requirements=reqs, + strings=user_req_str_consts, + max_tries=max_tries + ) + # Update state + state = DOMLS.save_results(state) + # Print output + state = DOMLS.check_synth_results(state) + + +def verify_csp_compatibility(dmc: ModelChecker): + res = CSPCompatibility.check(dmc.intermediate_model, dmc.doml_version) + res['type'] = 'message' + return res + \ No newline at end of file diff --git a/mc_openapi/doml_mc/mc.py b/mc_openapi/doml_mc/mc.py index c2b2660409bdab80eae920cfe91f689b07b15652..315f186d8563d281aafd8027a13f8ec0823ee6bc 100644 --- a/mc_openapi/doml_mc/mc.py +++ b/mc_openapi/doml_mc/mc.py @@ -1,82 +1,70 @@ -from typing import Optional -import importlib.resources as ilres -import yaml -from joblib import parallel_backend, Parallel, delayed +import logging from multiprocessing import TimeoutError +from typing import Optional + +from joblib import Parallel, delayed, parallel_backend -from .. import assets -from .intermediate_model.doml_element import ( - IntermediateModel, - reciprocate_inverse_associations -) -from .intermediate_model.metamodel import ( - MetaModel, - parse_inverse_associations, - parse_metamodel -) -from .xmi_parser.doml_model import parse_doml_model -from .mc_result import MCResult, MCResults -from .imc import RequirementStore, IntermediateModelChecker from .common_reqs import CommonRequirements -from .consistency_reqs import ( - get_attribute_type_reqs, - get_attribute_multiplicity_reqs, - get_association_type_reqs, - get_association_multiplicity_reqs, - get_inverse_association_reqs -) +from .consistency_reqs import (get_association_multiplicity_reqs, + get_association_type_reqs, + get_attribute_multiplicity_reqs, + get_attribute_type_reqs, + get_inverse_association_reqs) +from .imc import IntermediateModelChecker, RequirementStore +from .intermediate_model.metamodel import (DOMLVersion, InverseAssociations, + MetaModels) +from .mc_result import MCResult, MCResults +from .xmi_parser.doml_model import parse_doml_model class ModelChecker: - metamodel: Optional[MetaModel] = None - inv_assoc: Optional[list[tuple[str, str]]] = None - - @staticmethod - def init_metamodel(): - mmdoc = yaml.load(ilres.read_text(assets, "doml_meta.yaml"), yaml.Loader) - ModelChecker.metamodel = parse_metamodel(mmdoc) - ModelChecker.inv_assoc = parse_inverse_associations(mmdoc) - - def __init__(self, xmi_model: bytes): - assert ModelChecker.metamodel and ModelChecker.inv_assoc - self.intermediate_model: IntermediateModel = parse_doml_model(xmi_model, ModelChecker.metamodel) - reciprocate_inverse_associations(self.intermediate_model, ModelChecker.inv_assoc) - - def check_common_requirements(self, threads: int = 1, consistency_checks: bool = False, timeout: Optional[int] = None) -> MCResults: - assert ModelChecker.metamodel and ModelChecker.inv_assoc - req_store = CommonRequirements - if consistency_checks: - req_store = req_store \ - + get_attribute_type_reqs(ModelChecker.metamodel) \ - + get_attribute_multiplicity_reqs(ModelChecker.metamodel) \ - + get_association_type_reqs(ModelChecker.metamodel) \ - + get_association_multiplicity_reqs(ModelChecker.metamodel) \ - + get_inverse_association_reqs(ModelChecker.inv_assoc) + def __init__(self, xmi_model: bytes, doml_version: Optional[DOMLVersion] = None): + self.intermediate_model, self.doml_version, self.domlr_requirements = parse_doml_model( + xmi_model, doml_version) + self.metamodel = MetaModels[self.doml_version] + self.inv_assoc = InverseAssociations[self.doml_version] + + def check_requirements( + self, + req_store: RequirementStore, + threads: int = 2, + user_str_values: list[str] = [], + timeout: Optional[int] = None, + disable_multithreading: bool = False + ) -> MCResults: + assert self.metamodel and self.inv_assoc + def worker(rfrom: int, rto: int): - imc = IntermediateModelChecker(ModelChecker.metamodel, ModelChecker.inv_assoc, self.intermediate_model) + imc = IntermediateModelChecker( + self.metamodel, self.inv_assoc, self.intermediate_model) rs = RequirementStore(req_store.get_all_requirements()[rfrom:rto]) + imc.instantiate_solver(user_str_values) return imc.check_requirements(rs) - if threads <= 1: - imc = IntermediateModelChecker(ModelChecker.metamodel, ModelChecker.inv_assoc, self.intermediate_model) - reqs = imc.check_requirements(req_store, timeout=(0 if timeout is None else timeout)) - return reqs - else: - def split_reqs(n_reqs: int, n_split: int): - slice_size = n_reqs // n_split - rto = 0 - while rto < n_reqs: - rfrom = rto - rto = min(rfrom + slice_size, n_reqs) - yield rfrom, rto + def split_reqs(n_reqs: int, n_split: int): + slice_size = max(n_reqs // n_split, 1) + + rto = 0 + while rto < n_reqs: + rfrom = rto + rto = min(rfrom + slice_size, n_reqs) + yield rfrom, rto + + try: + if disable_multithreading: + # Easier debug + results =[ worker(0, len(req_store) )] + + else: + with parallel_backend('loky', n_jobs=threads): + results = Parallel(timeout=timeout)(delayed(worker)( + rfrom, rto) for rfrom, rto in split_reqs(len(req_store), threads)) + + ret = MCResults([]) + for res in results: + ret.add_results(res) - try: - with parallel_backend('threading', n_jobs=threads): - results = Parallel(timeout=timeout)(delayed(worker)(rfrom, rto) for rfrom, rto in split_reqs(len(req_store), threads)) - ret = MCResults([]) - for res in results: - ret.add_results(res) - return ret - except TimeoutError: - return MCResults([(MCResult.dontknow, "")]) + return ret + except TimeoutError: + return MCResults([(MCResult.dontknow, "")]) diff --git a/mc_openapi/doml_mc/mc_result.py b/mc_openapi/doml_mc/mc_result.py index 78309c1d17958bdd972ce802ec46ac494ea30d5f..8693a421cd1377d942896f59265560382e230532 100644 --- a/mc_openapi/doml_mc/mc_result.py +++ b/mc_openapi/doml_mc/mc_result.py @@ -1,4 +1,6 @@ from enum import Enum +import logging +from typing import Literal from z3 import CheckSatResult, sat, unsat, unknown @@ -9,6 +11,10 @@ class MCResult(Enum): @staticmethod def from_z3result(z3res: CheckSatResult, flipped: bool = False) -> "MCResult": + """Returns an Enum which is either sat, unsat or dontknow. + If flipped is true, then the sat and unsat are swapped: it's useful when + we are evaluating an expression in negative form. + """ if flipped: if z3res == sat: return MCResult.unsat @@ -25,27 +31,60 @@ class MCResult(Enum): class MCResults: - dontknow_msg = "Timed out: unable to check some requirements." + DONTKNOW_MSG = "Timed out: unable to check some requirements." + SATISFIED_MSG = "All requirements are satisfied." - def __init__(self, results: list[tuple[MCResult, str]]): + def __init__(self, results: list[tuple[MCResult, Literal["BUILTIN", "USER"], str, str, str]]): + """It receives a list of tuples (result, type, error message, id, desc, time)""" self.results = results - def summarize(self) -> tuple[MCResult, str]: - some_unsat = any(res == MCResult.unsat for res, _ in self.results) - some_dontknow = any(res == MCResult.dontknow for res, _ in self.results) + def summarize(self) -> dict[str, any]: + some_unsat = any(res == MCResult.unsat for res, _, _, _, _, _ in self.results) + some_dontknow = any(res == MCResult.dontknow for res, _, _, _, _, _ in self.results) + + all_reqs = [ + { + "id": id, + "type": type, + "message": msg, + "result": res.name, + "description": desc, + "time": time + } + for res, type, msg, id, desc, time in self.results + ] + if some_unsat: - err_msg = " ".join(msg for res, msg in self.results if res == MCResult.unsat) + builtin_err_msgs = [ + (id, msg, time) for res, type, msg, id, _, time in self.results if res == MCResult.unsat and type == "BUILTIN"] + user_err_msgs = [ + (id, msg, time) for res, type, msg, id, _, time in self.results if res == MCResult.unsat and type == "USER"] + + # Print to text (instead of HTML) + builtin_err_msg = "\n".join([f"[{id}][{time}s] {msg}" for id, msg, time in builtin_err_msgs]) + user_err_msg = "\n".join([f"[{id}][{time}s] {msg}" for id, msg, time in user_err_msgs]) + + err_msg = "" + if builtin_err_msgs: + err_msg += '[Built-in]\n' + builtin_err_msg + if user_err_msgs: + err_msg += '\n[User]\n' + user_err_msg if some_dontknow: - err_msg = err_msg + MCResults.dontknow_msg - return MCResult.unsat, err_msg + err_msg += '\n' + MCResults.DONTKNOW_MSG + + return { + 'result': MCResult.unsat, + 'builtin': builtin_err_msgs, + 'user': user_err_msgs, + 'dontknow': some_dontknow, + 'description': err_msg, + 'all_reqs': all_reqs + } elif some_dontknow: - return MCResult.dontknow, MCResults.dontknow_msg + return {'result': MCResult.dontknow, 'description': MCResults.DONTKNOW_MSG } else: - return MCResult.sat, "All requirements satisfied." - - def add_result(self, result: tuple[MCResult, str]): - self.results.append(result) + return {'result': MCResult.sat, 'description': MCResults.SATISFIED_MSG, 'all_reqs': all_reqs } def add_results(self, results: "MCResults"): self.results.extend(results.results) diff --git a/mc_openapi/doml_mc/network_address_validator/__init__.py b/mc_openapi/doml_mc/network_address_validator/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b64d68b57bb369f04c53eba9a9e436a6fdb7cd1d --- /dev/null +++ b/mc_openapi/doml_mc/network_address_validator/__init__.py @@ -0,0 +1 @@ +from .validate import validate_network_address \ No newline at end of file diff --git a/mc_openapi/doml_mc/network_address_validator/validate.py b/mc_openapi/doml_mc/network_address_validator/validate.py new file mode 100644 index 0000000000000000000000000000000000000000..5cbcdc6dd54a482a895db72e1f57a790b3e58755 --- /dev/null +++ b/mc_openapi/doml_mc/network_address_validator/validate.py @@ -0,0 +1,275 @@ +import logging +from mc_openapi.doml_mc.intermediate_model import DOMLElement +from mc_openapi.doml_mc.mc import ModelChecker +from ipaddress import IPv4Address, IPv4Network + + +BASE_ADDR = '0.0.0.0' + + +CONCRETE_NETWORK = 'concrete_Network' +# associations +ASSOC_SUBNETS = 'infrastructure_Network::subnets' +ASSOC_CONCRETE_SUBNETS = 'concrete_Network::subnets' +ASSOC_CONCRETE_MAPS = 'concrete_Network::maps' +ASSOC_GATEWAYS = 'infrastructure_Network::gateways' +ASSOC_NETIFACE = 'infrastructure_Network::connectedIfaces' + +# attributes +ATTR_NET_CIDR = 'infrastructure_Network::cidr' +ATTR_GATEWAY_ADDRESS = 'infrastructure_InternetGateway::address' +ATTR_NETIFACE_ADDRESS = 'infrastructure_NetworkInterface::endPoint' +ATTR_PROTOCOL = 'infrastructure_Network::protocol' +ATTR_CONCRETE_PROTOCOL = 'concrete_Network::protocol' +ATTR_CONCRETE_ADDRESS_RANGE = 'concrete_Network::addressRange' + +def validate_network_address(imc: ModelChecker): + """ + HOW IT WORKS: + + * Infrastructure Layer + - [n] Network.protocol + - [e] InternetGateway.address + - [e] NetworkInterface.endPoint + * Concrete Layer + - [n] Network.protocol + - [n] Network.addressRange + - [n] Subnet.addressRange + + before MC + validate network + generate report + attach report to HTML output + """ + im = imc.intermediate_model + + # warnings: list[str] = [] + warnings: list[str] = [] + + ## Helpers ## + def get_attr(elem: DOMLElement, attr_id: str): + if elem := elem.attributes.get(attr_id): + return elem[0] + return None + + def get_assocs(elem: DOMLElement, assoc_id: str): + return elem.associations.get(assoc_id, []) + + def get_elem(elem: DOMLElement, assoc_id: str): + assocs = list(get_assocs(elem, assoc_id)) + if len(assocs) >= 1: + return im.get(assocs[0]) + return None + + def validate_net(cnet: DOMLElement, parent_net: DOMLElement | None = None): + + if (parent_net): + check_proper_subnet(cnet, parent_net) + + if inet := get_elem(cnet, ASSOC_CONCRETE_MAPS): + check_infr_and_conc_protocol_match(inet, cnet) + check_cidr_and_address_range(inet, cnet) + check_gateway_belongs_to_network(inet, cnet) + check_iface_belongs_to_network(inet, cnet) + + debug = f"{cnet.user_friendly_name} [concrete]\n" + debug += f"\tprotocol={get_attr(cnet, ATTR_CONCRETE_PROTOCOL)}\n" + debug += f"\taddress_range={get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)}\n" + debug += f"\tsubnets=\t{get_assocs(cnet, ASSOC_CONCRETE_SUBNETS)}\n" + if inet: + debug += f"{inet.user_friendly_name} [infrastructure]\n" + debug += f"\tprotocol={get_attr(inet, ATTR_PROTOCOL)}\n" + debug += f"\tcidr={get_attr(inet, ATTR_NET_CIDR)}\n" + debug += f"\tsubnets=\t{get_assocs(inet, ASSOC_SUBNETS)}\n" + debug += f"\tifaces=\t{get_assocs(inet, ASSOC_NETIFACE)}\n" + debug += f"\tgateways=\t{get_assocs(inet, ASSOC_GATEWAYS)}\n" + debug += "\n" + # print(debug) + + csubnet_ids = get_assocs(cnet, ASSOC_CONCRETE_SUBNETS) + for csubnet_id in csubnet_ids: + if csubnet := im.get(csubnet_id): + + validate_net(csubnet, cnet) + + ## Checks ## + def check_infr_and_conc_protocol_match(inet: DOMLElement, cnet: DOMLElement): + """Checks if the protocol of an infrastructure network matches the respective protocol of its concrete counterpart.""" + iprot = get_attr(inet, ATTR_PROTOCOL) + cprot = get_attr(cnet, ATTR_CONCRETE_PROTOCOL) + if iprot and cprot and iprot != cprot: + warnings.append(f"Protocol of infrastructure network '{inet.user_friendly_name}' must match protocol of concrete network '{cnet.user_friendly_name}'.") + + def check_cidr_and_address_range(inet: DOMLElement, cnet: DOMLElement, warnings=warnings): + """Checks if the addressRange of a concrete network respects the CIDR specified in the infrastructure layer.""" + cidr = get_attr(inet, ATTR_NET_CIDR) + addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE) + if cidr and addr_range: + try: + addr_range = IPv4Network(addr_range) + if addr_range.prefixlen != cidr: + warnings.append(f"CIDR ({cidr}) of infrastructure network '{inet.user_friendly_name}' does not match the address range of concrete network '{cnet.user_friendly_name}'.") + except: + warnings.append(f"Failed to parse concrete network '{cnet.user_friendly_name}' address range as an IPv4Network.") + + def check_proper_subnet(cnet: DOMLElement, parent_net: DOMLElement): + """Checks if a subnet address range respects the parent net.""" + addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE) + parent_addr_range = get_attr(parent_net, ATTR_CONCRETE_ADDRESS_RANGE) + if addr_range and parent_addr_range: + try: + addr_range = IPv4Network(addr_range) + parent_addr_range = IPv4Network(parent_addr_range) + + if not addr_range.subnet_of(parent_addr_range): + warnings.append(f"Subnet '{cnet.user_friendly_name}' is not a proper subnet of '{parent_net.user_friendly_name}'.") + except: + warnings.append(f"Failed to parse concrete network '{cnet.user_friendly_name}' or '{parent_net.user_friendly_name}' address range as an IPv4Network.") + + def check_gateway_belongs_to_network(inet: DOMLElement, cnet: DOMLElement): + """Checks if the address of the gateways of a network belongs to that network address range.""" + addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE) + gateway_ids = get_assocs(inet, ASSOC_GATEWAYS) + + if addr_range and gateway_ids: + for gateway_id in gateway_ids: + if gateway := im.get(gateway_id): + addr_gateway = get_attr(gateway, ATTR_GATEWAY_ADDRESS) + if addr_gateway: + try: + addr_range = IPv4Network(addr_range) + addr_gateway = IPv4Address(addr_gateway) + if addr_gateway not in addr_range: + warnings.append(f"Gateway '{gateway.user_friendly_name}' does not belong to network '{cnet.user_friendly_name}'.") + except: + warnings.append(f"Failed to parse concrete network {cnet.user_friendly_name} address range or its gateway address.") + + def check_iface_belongs_to_network(inet: DOMLElement, cnet: DOMLElement): + """Checks if the address of the network interfaces of a network belongs to that network address range.""" + addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE) + iface_ids = get_assocs(inet, ASSOC_NETIFACE) + + if addr_range and iface_ids: + for iface_id in iface_ids: + if iface := im.get(iface_id): + addr_iface = get_attr(iface, ATTR_NETIFACE_ADDRESS) + if addr_iface: + try: + addr_range = IPv4Network(addr_range) + addr_iface = IPv4Address(addr_iface) + if addr_iface not in addr_range: + warnings.append(f"Network Interface '{addr_iface.user_friendly_name}' does not belong to network '{cnet.user_friendly_name}'.") + except Exception as e: + print(e) + warnings.append(f"Failed to parse concrete network {cnet.user_friendly_name} address range or its associated network interface '{iface.user_friendly_name}' address.") + + + + + concrete_networks = [e for e in im.values() if e.class_ == CONCRETE_NETWORK] + + # print('-'*20) + # print('[DEBUG] Network Validation') + + for cnet in concrete_networks: + validate_net(cnet) + + # print('-'*20) + # print(warnings) + # print('-'*20) + + # networks = [e for e in im.values() if e.class_ == 'concrete_Network'] + # subnets = [e for e in im.values() if e.class_ == 'infrastructure_Subnet'] + # ifaces = [e for e in im.values() if e.class_ == 'infrastructure_NetworkInterface'] + + + # def visit_subnet(net: DOMLElement, acc: list): + # """Recursively navigate subnets to populate the `acc` list with all the subnet in a network.""" + # for subnet in get_assocs(net, ASSOC_SUBNETS): + # subnet = im[subnet] + # subnet_addr = fix_invalid_address(get_attr(subnet, ATTR_NET_ADDRESS), net, warnings) + # acc.append((subnet, IPv4Network(subnet_addr))) + # visit_subnet(subnet, acc) + + # def fix_invalid_address(address: any, net: DOMLElement, warning: list): + # # TODO: Use a match statement or use regexps once syntax for CIDR/Address is clear + # if isinstance(address, str) and address.startswith('/'): + # warning.append(("Network", f"Net '{net.user_friendly_name}' has an incomplete address: '{address}'. '0.0.0.0' has been temporarily assigned.")) + # return f"{BASE_ADDR}{address}" + + # return address + + + # for network in networks: + + # warning = [] + + # # Tuple(elem, cidr) + # subnets: list[tuple[DOMLElement, IPv4Network]] = [] + # # Tuple(elem, address) + # addresses: list[tuple[DOMLElement, IPv4Address]] = [] + + # # Add subnets (Networks) + # visit_subnet(network, subnets) + + # # pprint("SUBNETS:") + # # pprint(subnets) + + # # Add addresses (gateways, ifaces) + # for gateway in get_assocs(network, ASSOC_GATEWAYS): + # gateway = im[gateway] + # if gateway_address := get_attr(gateway, ATTR_GATEWAY_ADDRESS): + # addresses.append((gateway, IPv4Address(gateway_address))) + + # for iface in ifaces: + # if owner_id := get_assocs(iface, ASSOC_IFACE_NET): + # owner = im[list(owner_id)[0]] + # if owner.id_ in [s.id_ for (s, _) in subnets] + [network.id_]: + # if ((iface_address := get_attr(iface, ATTR_NETIFACE_ADDRESS)) + # and (owner_address := get_attr(owner, ATTR_NET_ADDRESS))): + # owner_address = fix_invalid_address(owner_address, owner, warning) + # iface_address = IPv4Address(iface_address) + # owner_address = IPv4Network(owner_address) + # # TODO: Remove? + # logging.info(f"{iface.user_friendly_name} ({iface_address}) belongs to {owner.user_friendly_name} ({owner_address})? {iface_address in owner_address.hosts()}") + + # addresses.append((iface, iface_address)) + # else: + # logging.info(f"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'.") + # warning.append(( + # "Address", f"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'." + # )) + + # # Validate Network and Subnets + # net_addr = fix_invalid_address(get_attr(network, ATTR_NET_ADDRESS), network, warning) + # # prepend 0.0.0.0 if starts with / i guess, print a warning + # print(f"{net_addr}\t{network.user_friendly_name}") + + # net = IPv4Network(net_addr) + + # if len(subnets) > 0: + # for (obj, sn) in subnets: + # logging.info(f"{sn}\t{obj.user_friendly_name} belongs? {sn.subnet_of(net)}") + # if not sn.subnet_of(net): + # warning.append(( + # "Subnet", f"Subnet {obj.user_friendly_name} ({sn}) does not belong to net '{network.user_friendly_name}' ({net_addr})." + # )) + # else: + # print("No subnets found!") + + # # Validate addresses (again) + # for (obj, addr) in addresses: + # if addr not in net.hosts(): + # warning.append(( + # "Address", f"'{obj.user_friendly_name}' [{obj.class_}] ({addr}) does not belong to net '{network.user_friendly_name}' ({net_addr})." + # )) + # logging.info(f"NetworkInterface '{obj.user_friendly_name}' ({addr}) belong to net '{network.user_friendly_name}' ({net_addr})? {addr in net.hosts()}") + + # warnings.append((network.user_friendly_name, list(set(warning)))) + + return warnings + + + + + diff --git a/mc_openapi/doml_mc/_utils.py b/mc_openapi/doml_mc/utils.py similarity index 86% rename from mc_openapi/doml_mc/_utils.py rename to mc_openapi/doml_mc/utils.py index 458c453bc55b6d4975d1cb4c61bd836f206177f6..ac0a3c7e1688c4ec5ece0f1a9c8b6968754b8a10 100644 --- a/mc_openapi/doml_mc/_utils.py +++ b/mc_openapi/doml_mc/utils.py @@ -1,10 +1,11 @@ from typing import TypeVar from collections.abc import Iterable - _K = TypeVar("_K") _V = TypeVar("_V") - def merge_dicts(it: Iterable[dict[_K, _V]]) -> dict[_K, _V]: return dict(kv for d in it for kv in d.items()) + +def Iff(a, b): + return a == b diff --git a/mc_openapi/doml_mc/xmi_parser/__init__.py b/mc_openapi/doml_mc/xmi_parser/__init__.py index 381f99a5015e215f99c790d736aaf19381518b65..bd8687bbfaa74eaf679c6de2bae1bcd0c9dc1932 100644 --- a/mc_openapi/doml_mc/xmi_parser/__init__.py +++ b/mc_openapi/doml_mc/xmi_parser/__init__.py @@ -1,3 +1 @@ -from .doml_model import parse_doml_model, init_doml_rset # noqa: F401 - -init_doml_rset() +from .doml_model import parse_doml_model # noqa: F401 diff --git a/mc_openapi/bytes_uri.py b/mc_openapi/doml_mc/xmi_parser/bytes_uri.py similarity index 100% rename from mc_openapi/bytes_uri.py rename to mc_openapi/doml_mc/xmi_parser/bytes_uri.py diff --git a/mc_openapi/doml_mc/xmi_parser/doml_model.py b/mc_openapi/doml_mc/xmi_parser/doml_model.py index ccee10de3c1e746dec2ed9b8d24652b13354d323..05a13d33823bd9e0135706380a7708b5d76e6eef 100644 --- a/mc_openapi/doml_mc/xmi_parser/doml_model.py +++ b/mc_openapi/doml_mc/xmi_parser/doml_model.py @@ -1,68 +1,126 @@ import copy import importlib.resources as ilres -from ipaddress import ip_address, ip_network +import logging +import sys +from typing import Optional, Tuple -from mc_openapi import assets -from mc_openapi.bytes_uri import BytesURI +from lxml import etree from pyecore.ecore import EObject from pyecore.resources import ResourceSet -from ..intermediate_model.doml_element import Attributes, IntermediateModel -from ..intermediate_model.metamodel import MetaModel -from .ecore import ELayerParser, SpecialParser +from mc_openapi import assets +from mc_openapi.doml_mc.exceptions import BadDOMLException, MissingInfrastructureLayerException, NoActiveConcreteLayerException, UnsupportedDOMLVersionException +from ..intermediate_model.doml_element import ( + IntermediateModel, reciprocate_inverse_associations) +from ..intermediate_model.metamodel import (DOMLVersion, InverseAssociations, + MetaModels) +from .bytes_uri import BytesURI +from .ecore import ELayerParser +from .special_parsers import SpecialParsers -doml_rset = None -def init_doml_rset(): # noqa: E302 - global doml_rset - rset = ResourceSet() - resource = rset.get_resource(BytesURI( - "doml", bytes=ilres.read_binary(assets, "doml.ecore") - )) - doml_metamodel = resource.contents[0] +doml_rsets = {} +def init_doml_rsets(): # noqa: E302 + global doml_rsets + for ver in DOMLVersion: + rset = ResourceSet() + source = ilres.files(assets).joinpath(f"metamodels/doml_{ver.value}.ecore") + resource = rset.get_resource(BytesURI( + "doml", bytes=source.read_bytes() + )) + doml_metamodel = resource.contents[0] - rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel - for subp in doml_metamodel.eSubpackages: - rset.metamodel_registry[subp.nsURI] = subp + rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel + # .ecore file is loaded in the rset as a metamodel + for subp in doml_metamodel.eSubpackages: + rset.metamodel_registry[subp.nsURI] = subp - doml_rset = rset + doml_rsets[ver] = rset -def get_rset(): - assert doml_rset is not None - return copy.copy(doml_rset) +def get_rset(doml_version: DOMLVersion) -> ResourceSet: + return copy.copy(doml_rsets[doml_version]) -def parse_xmi_model(raw_model: bytes) -> EObject: - rset = get_rset() +def parse_xmi_model(raw_model: bytes, doml_version: DOMLVersion) -> EObject: + rset = get_rset(doml_version) doml_uri = BytesURI("user_doml", bytes=raw_model) resource = rset.create_resource(doml_uri) resource.load() return resource.contents[0] - -def parse_doml_model(raw_model: bytes, mm: MetaModel) -> IntermediateModel: - def parse_network_address_range(arange: str) -> Attributes: - ipnet = ip_network(arange) - return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]} - - def parse_iface_address(addrport: str) -> Attributes: - addr, _, port = addrport.rpartition(":") - if addr == "": - addr = port - return {"endPoint": [int(ip_address(addr))]} - - model = parse_xmi_model(raw_model) - - sp = SpecialParser(mm, { - ("infrastructure_Network", "addressRange"): parse_network_address_range, - ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, - ("commons_FProperty", "value"): lambda fval: {"value": [str(fval)]}, - }) - elp = ELayerParser(mm, sp) - elp.parse_elayer(model.application) - elp.parse_elayer(model.infrastructure) - elp.parse_elayer(model.activeConfiguration) - im = elp.parse_elayer(model.activeInfrastructure) - - return im +DOMLRRawRequirements = list[tuple[str, str]] + +def parse_doml_model(raw_model: bytes, doml_version: Optional[DOMLVersion]) -> Tuple[IntermediateModel, DOMLVersion, Optional[DOMLRRawRequirements]]: + # if doml_version is None: + # doml_version = infer_domlx_version(raw_model) + + # Try every DOML version until one works! + if doml_version is None: + + doml_versions = [x for x in DOMLVersion] + # Use the most recent DOML version first + doml_versions.reverse() + + def get_model(raw_model, doml_version): + try: + dv = doml_versions.pop(0) + doml_version = dv + parsed_xmi_model = parse_xmi_model(raw_model, dv) + # Try to extract the user-specified version from the DOML + try: + model_version = parsed_xmi_model.version + if model_version: + try: + dv = DOMLVersion.get(model_version) + return parse_xmi_model(raw_model, dv), dv + except: + MSG_ERR_INVALID_DOML_VERSION = f"DOML requires version \"{model_version}\", but could not parse it with that version. Is the version valid?" + logging.error(MSG_ERR_INVALID_DOML_VERSION) + raise UnsupportedDOMLVersionException(MSG_ERR_INVALID_DOML_VERSION) + except: + pass + # DOML version is not specified, proceed as usual + return parsed_xmi_model, dv + except Exception as e: + logging.info(f"Couldn't parse with DOML {dv.value}. Trying another version...") + if len(doml_versions) == 0: + MSG_ERR_NO_DOML_VERSIONS = "No other compatible DOML versions found!" + logging.error(MSG_ERR_NO_DOML_VERSIONS) + raise UnsupportedDOMLVersionException(MSG_ERR_NO_DOML_VERSIONS) + else: + return get_model(raw_model, doml_version) + + model, doml_version = get_model(raw_model, doml_version) + else: # if user specifies DOML version, respect that choice! + try: + model = parse_xmi_model(raw_model, doml_version) + except: + raise BadDOMLException("Parsing of DOML failed. Perhaps you are using the wrong DOML version or IDE?") + + logging.info(f"Model '{model.name}' parsed as DOML {doml_version.value}") + + elp = ELayerParser(MetaModels[doml_version], SpecialParsers[doml_version]) + if model.application: + elp.parse_elayer(model.application) + if model.infrastructure: + elp.parse_elayer(model.infrastructure) + else: + raise MissingInfrastructureLayerException() + if model.activeConfiguration: + elp.parse_elayer(model.activeConfiguration) + if model.activeInfrastructure: + im = elp.parse_elayer(model.activeInfrastructure) + else: + raise NoActiveConcreteLayerException() + + reciprocate_inverse_associations(im, InverseAssociations[doml_version]) + + # If there are DOMLR requirements + try: + domlr = model.functionalRequirements.items + domlr = [(req.name, req.description.replace("```", "")) for req in domlr] + logging.info("Found DOMLR requirements in DOML model.") + except Exception: + domlr = None + return im, doml_version, domlr diff --git a/mc_openapi/doml_mc/xmi_parser/ecore.py b/mc_openapi/doml_mc/xmi_parser/ecore.py index 022290ada8381df89d77cf8f4ff558a8f38086f6..69f858d914c75aa7fefdc684d27a6b23a060adf8 100644 --- a/mc_openapi/doml_mc/xmi_parser/ecore.py +++ b/mc_openapi/doml_mc/xmi_parser/ecore.py @@ -1,5 +1,6 @@ +import logging import sys -from typing import Callable +from typing import Callable, Optional from pyecore.ecore import EEnumLiteral, EObject, EOrderedSet, EClass @@ -74,7 +75,7 @@ class ELayerParser: elif isinstance(val, EOrderedSet): raw_attrs[eAttr.name] = [str(v) if isinstance(v, EEnumLiteral) else v for v in val] else: - print("Attribute", eAttr.name, "has value", val, "of unexpected type.", file=sys.stderr) + logging.error(f"Attribute {eAttr.name} has value {val} of unexpected type.") attrs = parse_attributes(raw_attrs, mm_class, self.mm) # Get all references and process them @@ -89,14 +90,13 @@ class ELayerParser: assocs = parse_associations(raw_assocs, mm_class, self.mm) self.im[name] = DOMLElement( - id_=name, class_=mm_class, attributes=attrs, associations=assocs + id_=name, class_=mm_class, attributes=attrs, associations=assocs, + user_friendly_name=ELayerParser.get_user_friendly_name(doc) ) return name - def getUniqueName(self): - name = f"__generated_name__{self.nextUniqueId}" - self.nextUniqueId += 1 - return name - def mangle_eclass_name(eClass: EClass) -> str: return eClass.ePackage.name + "_" + eClass.name + + def get_user_friendly_name(doc: EObject) -> Optional[str]: + return getattr(doc, "name", None) diff --git a/mc_openapi/doml_mc/xmi_parser/special_parsers.py b/mc_openapi/doml_mc/xmi_parser/special_parsers.py new file mode 100644 index 0000000000000000000000000000000000000000..6509d13e4f6c9a4c6410a60e13072029fbd14820 --- /dev/null +++ b/mc_openapi/doml_mc/xmi_parser/special_parsers.py @@ -0,0 +1,97 @@ +from ipaddress import ip_address, ip_network + +from .ecore import SpecialParser +from ..intermediate_model.metamodel import DOMLVersion, MetaModels +from ..intermediate_model.doml_element import Attributes + + +SpecialParsers: dict[DOMLVersion, SpecialParser] = {} + + +def parse_network_address_range(arange: str) -> Attributes: + ipnet = ip_network(arange) + return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]} + + +def parse_iface_address(addrport: str) -> Attributes: + addr, _, port = addrport.rpartition(":") + if addr == "": + addr = port + if addr == "": + raise Exception(f"Interface address with value '{addrport}' is not valid. It should be 'x.x.x.x/cidr'.") + return {"endPoint": [int(ip_address(addr))]} + + +def parse_memory_mb(mem: str) -> Attributes: + return {"memory_mb": [int(mem)], "memory_kb": [int(mem * 1024)]} + + +def parse_fproperty(fval: str) -> Attributes: + return {"value": [str(fval)]} + + +def parse_cidr(arange: str) -> Attributes: + attrs: Attributes = {"addressRange": [arange]} + if arange[0] == "/": + try: + attrs["cidr"] = [int(arange[1:])] + except (ValueError, IndexError): + pass + return attrs + + +def init_special_parsers(): + global SpecialParsers + assert len(MetaModels) > 0 + + attribute_parsers = { + # DOMLVersion.1_0: { + # ("infrastructure_Network", "addressRange"): parse_network_address_range, + # ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + # ("commons_FProperty", "value"): parse_fproperty, + # }, + DOMLVersion.V2_0: { + ("infrastructure_Network", "addressRange"): parse_network_address_range, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V2_1: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V2_2: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V2_2_1: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V2_3: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V3_0: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + }, + DOMLVersion.V3_1: { + ("infrastructure_Network", "addressRange"): parse_cidr, + ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address, + ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb, + ("commons_FProperty", "value"): parse_fproperty, + } + } + for ver in DOMLVersion: + SpecialParsers[ver] = SpecialParser(MetaModels[ver], attribute_parsers[ver]) diff --git a/mc_openapi/doml_mc/z3encoding/im_encoding.py b/mc_openapi/doml_mc/z3encoding/im_encoding.py index 31948d9eb04de6e6300ab5ccac03a59c53b35968..533ca401735a8368d913977c4994def3c2437577 100644 --- a/mc_openapi/doml_mc/z3encoding/im_encoding.py +++ b/mc_openapi/doml_mc/z3encoding/im_encoding.py @@ -1,31 +1,16 @@ -from typing import Union from itertools import product +from typing import Union + +from z3 import (And, BoolSort, Const, Context, Datatype, DatatypeRef, + DatatypeSortRef, ForAll, FuncDeclRef, Function, IntSort, Not, + Or, Solver, EnumSort) -from z3 import ( - And, - Const, - Context, - DatatypeRef, - DatatypeSortRef, - ForAll, - FuncDeclRef, - Function, - Not, - Or, - Solver, -) +from mc_openapi.doml_mc.z3encoding.metamodel_encoding import mk_enum_sort_dict from ..intermediate_model import IntermediateModel, MetaModel from ..intermediate_model.metamodel import get_mangled_attribute_defaults - from .types import Refs, SortAndRefs -from .utils import ( - assert_relation_tuples, - Iff, - mk_enum_sort_dict, - mk_stringsym_sort_from_strings, -) - +from ..utils import Iff def mk_elem_sort_dict( im: IntermediateModel, @@ -61,41 +46,42 @@ def assert_im_attributes( solver: Solver, im: IntermediateModel, mm: MetaModel, - elem: Refs, - attr_sort: DatatypeSortRef, - attr: Refs, - AData: DatatypeSortRef, - ss: Refs, + elems: Refs, + attr_sort: DatatypeSortRef, # Relationship sort + attrs: Refs, # Relationship data + attr_data_sort: DatatypeSortRef, # Value sort + strings: Refs, + allow_placeholders: bool = False ) -> None: """ ### Effects This procedure is effectful on `solver`. """ - def encode_adata(v: Union[str, int, bool]) -> DatatypeRef: + def encode_attr_data(v: Union[str, int, bool]) -> DatatypeRef: if type(v) is str: - return AData.ss(ss[v]) # type: ignore + return attr_data_sort.str(strings[v]) # type: ignore elif type(v) is int: - return AData.int(v) # type: ignore + return attr_data_sort.int(v) # type: ignore else: # type(v) is bool - return AData.bool(v) # type: ignore + return attr_data_sort.bool(v) # type: ignore a = Const("a", attr_sort) - d = Const("d", AData) + d = Const("d", attr_data_sort) for esn, im_es in im.items(): - mangled_attrs = get_mangled_attribute_defaults(mm, im_es.class_) | im_es.attributes - if mangled_attrs: + attr_data = get_mangled_attribute_defaults(mm, im_es.class_) | im_es.attributes + if attr_data: assn = ForAll( [a, d], Iff( - attr_rel(elem[esn], a, d), + attr_rel(elems[esn], a, d), Or( *( And( - a == attr[aname], - d == encode_adata(avalue), + a == attrs[aname], + d == encode_attr_data(avalue) ) - for aname, avalues in mangled_attrs.items() + for aname, avalues in attr_data.items() for avalue in avalues ) ), @@ -104,43 +90,14 @@ def assert_im_attributes( else: assn = ForAll( [a, d], - Not(attr_rel(elem[esn], a, d)) + Not(attr_rel(elems[esn], a, d)) ) solver.assert_and_track(assn, f"attribute_values {esn}") - def assert_im_associations( assoc_rel: FuncDeclRef, solver: Solver, - im: IntermediateModel, - mm: MetaModel, - elem: Refs, - assoc: Refs, -) -> None: - """ - ### Effects - This procedure is effectful on `solver`. - """ - elem_names = set(im.keys()) - assoc_mangled_names = { - f"{cname}::{aname}" - for cname, c in mm.items() - for aname in c.associations - } - rel_tpls = [ - [esn, amn, etn] - for esn, amn, etn in product( - elem_names, assoc_mangled_names, elem_names - ) - if etn in im[esn].associations.get(amn, set()) - ] - assert_relation_tuples(assoc_rel, solver, rel_tpls, elem, assoc, elem) - - -def assert_im_associations_q( - assoc_rel: FuncDeclRef, - solver: Solver, - im: IntermediateModel, + im: IntermediateModel, # Contains only bounded elements elem: Refs, assoc_sort: DatatypeSortRef, assoc: Refs, @@ -150,29 +107,30 @@ def assert_im_associations_q( This procedure is effectful on `solver`. """ - a = Const("a", assoc_sort) - for (esn, im_es), etn in product(im.items(), im): + assoc_ref = Const("a", assoc_sort) + for (elem_1_k, elem_1_v), elem_2_k in product(im.items(), im): assn = ForAll( - [a], + [assoc_ref], Iff( - assoc_rel(elem[esn], a, elem[etn]), + assoc_rel(elem[elem_1_k], assoc_ref, elem[elem_2_k]), Or( *( - a == assoc[amn] - for amn, etns in im_es.associations.items() - if etn in etns + assoc_ref == assoc[elem_1_assoc_k] + for elem_1_assoc_k, elem_1_assoc_elems_k in elem_1_v.associations.items() + if elem_2_k in elem_1_assoc_elems_k ), solver.ctx ), ), ) - solver.assert_and_track(assn, f"associations {esn} {etn}") + solver.assert_and_track(assn, f"associations {elem_1_k} {elem_2_k}") def mk_stringsym_sort_dict( im: IntermediateModel, mm: MetaModel, - z3ctx: Context + z3ctx: Context, + additional_strings: list[str] = [] ) -> SortAndRefs: strings = ( { @@ -191,5 +149,36 @@ def mk_stringsym_sort_dict( if isinstance(v, str) } | {"SCRIPT", "IMAGE"} # GeneratorKind values + | {"INGRESS", "EGRESS"} # TODO: Check if this fix is required + # It solves a KeyError when MC is run on openstack_template.domlx + | { + v + for v in additional_strings + } ) return mk_stringsym_sort_from_strings(list(strings), z3ctx=z3ctx) + +def mk_attr_data_sort( + str_sort: DatatypeSortRef, + z3ctx: Context +) -> DatatypeSortRef: + attr_data = Datatype("AttributeData", ctx=z3ctx) + attr_data.declare("placeholder") + attr_data.declare("int", ("get_int", IntSort(ctx=z3ctx))) + attr_data.declare("bool", ("get_bool", BoolSort(ctx=z3ctx))) + attr_data.declare("str", ("get_str", str_sort)) # str_sort is the one returned by the function above + return attr_data.create() + +def mk_stringsym_sort_from_strings( + strings: list[str], + z3ctx: Context +) -> SortAndRefs: + str_list = [f"str_{i}_{symbolize(s)}" for i, s in enumerate(strings)] + string_sort, str_refs_dict = mk_enum_sort_dict("string", str_list, z3ctx=z3ctx) + string_sort_dict = { + s: str_refs_dict[str] for s, str in zip(strings, str_list) + } + return string_sort, string_sort_dict + +def symbolize(s: str) -> str: + return "".join([c.lower() if c.isalnum() else "_" for c in s[:16]]) diff --git a/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py index 22c48484de3709b6526aa77c44d80da3aea07700..97af7a3b7860a171b652c6d724428cc035b651ae 100644 --- a/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py +++ b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py @@ -4,12 +4,11 @@ from z3 import ( DatatypeSortRef, FuncDeclRef, Function, + EnumSort ) from ..intermediate_model import MetaModel from .types import SortAndRefs -from .utils import mk_enum_sort_dict - def mk_class_sort_dict(mm: MetaModel, z3ctx: Context) -> SortAndRefs: return mk_enum_sort_dict("Class", list(mm), z3ctx) @@ -38,13 +37,18 @@ def mk_association_sort_dict( ] return mk_enum_sort_dict("Association", assocs, z3ctx) +def mk_enum_sort_dict(name: str, values: list[str], z3ctx: Context) -> SortAndRefs: + """Makes a Z3 sort and a dict indexing sort values by their name""" + + sort, datatype_refs = EnumSort(name, values, ctx=z3ctx) + return sort, dict(zip(values, datatype_refs)) def def_attribute_rel( attr_sort: DatatypeSortRef, elem_sort: DatatypeSortRef, - AData: DatatypeSortRef + attr_data_sort: DatatypeSortRef ) -> FuncDeclRef: - return Function("attribute", elem_sort, attr_sort, AData, BoolSort(ctx=elem_sort.ctx)) + return Function("attribute", elem_sort, attr_sort, attr_data_sort, BoolSort(ctx=elem_sort.ctx)) def def_association_rel( diff --git a/mc_openapi/doml_mc/z3encoding/utils.py b/mc_openapi/doml_mc/z3encoding/utils.py deleted file mode 100644 index 04730494fc3687311d439f9bc06f1f73e16a9fc2..0000000000000000000000000000000000000000 --- a/mc_openapi/doml_mc/z3encoding/utils.py +++ /dev/null @@ -1,150 +0,0 @@ -from typing import cast -from collections.abc import Sequence -from itertools import product - -from z3 import ( - BoolSort, - BoolVal, - Context, - Datatype, - DatatypeSortRef, - ExprRef, - EnumSort, - FuncDeclRef, - IntSort, - Solver, -) - -from .types import Refs, SortAndRefs - - -def mk_enum_sort_dict(name: str, values: list[str], z3ctx: Context) -> SortAndRefs: - """Makes a Z3 sort and a dict indexing sort values by their name""" - - sort, dtrefs = EnumSort(name, values, ctx=z3ctx) - return sort, dict(zip(values, dtrefs)) - - -def assert_relation_tuples( - rel: FuncDeclRef, - solver: Solver, - rel_tpls: list[list[str]], - *sig_dicts: Refs, -) -> None: - """ - ### Parameters - - `rel` is a Z3 function with return type Bool representing a relation; - - `solver` is the Z3 solver on which to assert; - - `rel_tpls` is a list of lists of names of symbols which are related in - `rel`; - - `sig_dicts` are the domains of `rel`. - - ### Effects - This procedure is effectful on `solver`. - """ - - # Length of tuples must me homogeneous and equal to the number of given - # domains. - if lengths := [len(tpl) for tpl in rel_tpls]: - assert min(lengths) == max(lengths) - assert lengths[0] == len(sig_dicts) - - sym_tpls = [ - cast( - list[ExprRef], - [dom[sym_name] for sym_name, dom in zip(doms_tpl, sig_dicts)], - ) - + [BoolVal(doms_tpl in rel_tpls, ctx=solver.ctx)] - for doms_tpl in map(list, product(*sig_dicts)) - ] - - assert_function_tuples_raw(rel, solver, sym_tpls) - - -def assert_function_tuples( - f: FuncDeclRef, - solver: Solver, - f_tpls: list[list[str]], - *sig_dicts: Refs, -) -> None: - """ - ### Parameters - - `f` is a Z3 function; - - `solver` is the Z3 solver on which to assert; - - `f_tpls` is a list of tuples of Z3 symbols. The first elements in each - tuple are the inputs of `f`, and the last element is its output; - - `sig_dicts` are the domains of `f`, the last one being its codomain. - - ### Effects - This procedure is effectful on `solver`. - """ - - # Length of tuples must me homogeneous and equal to the number of given - # domains. - if lengths := [len(tpl) for tpl in f_tpls]: - assert min(lengths) == max(lengths) - assert lengths[0] == len(sig_dicts) - - sym_tpls = [ - [dom[sym_name] for sym_name, dom in zip(f_tpl, sig_dicts)] - for f_tpl in f_tpls - ] - - assert_function_tuples_raw(f, solver, sym_tpls) - - -def assert_function_tuples_raw( - f: FuncDeclRef, - solver: Solver, - f_tpls: Sequence[Sequence[ExprRef]], -) -> None: - """ - ### Parameters - - `f` is a Z3 function; - - `solver` is the Z3 solver on which to assert; - - `f_tpls` is a list of tuples of Z3 references or otherwise accepted - values. The first elements in each tuple are the inputs of `f`, and the - last element is its output; - - ### Effects - This procedure is effectful on `solver`. - """ - # Length of tuples must me homogeneous. - if lengths := [len(tpl) for tpl in f_tpls]: - assert min(lengths) == max(lengths) - - for *xs, y in f_tpls: - solver.assert_and_track( - f(*xs) == y, - f"{f.name()} " + " ".join(str(x) for x in xs) + f" {y}", - ) - - -def mk_stringsym_sort_from_strings( - strings: list[str], - z3ctx: Context -) -> SortAndRefs: - def symbolize(s: str) -> str: - return "".join([c.lower() if c.isalnum() else "_" for c in s[:16]]) - - ss_list = [f"ss_{i}_{symbolize(s)}" for i, s in enumerate(strings)] - stringsym_sort, ss_refs_dict = mk_enum_sort_dict("StringSym", ss_list, z3ctx=z3ctx) - stringsym_sort_dict = { - s: ss_refs_dict[ss] for s, ss in zip(strings, ss_list) - } - return stringsym_sort, stringsym_sort_dict - - -def mk_adata_sort( - ss_sort: DatatypeSortRef, - z3ctx: Context -) -> DatatypeSortRef: - AData = Datatype("AttributeData", ctx=z3ctx) - AData.declare("int", ("get_int", IntSort(ctx=z3ctx))) - AData.declare("bool", ("get_bool", BoolSort(ctx=z3ctx))) - AData.declare("ss", ("get_ss", ss_sort)) - return AData.create() - - -def Iff(a, b): - return a == b diff --git a/mc_openapi/handlers.py b/mc_openapi/handlers.py deleted file mode 100644 index a362235e9d516e991b035d09761b521da846eb5c..0000000000000000000000000000000000000000 --- a/mc_openapi/handlers.py +++ /dev/null @@ -1,26 +0,0 @@ -import datetime -from .doml_mc import ModelChecker, MCResult - - -def make_error(user_msg, debug_msg=None): - result = {"message": user_msg, "timestamp": datetime.datetime.now()} - if debug_msg is not None: - result["debug_message"] = debug_msg - return result - - -def post(body, requirement=None): - doml_xmi = body - try: - dmc = ModelChecker(doml_xmi) - results = dmc.check_common_requirements(threads=2, consistency_checks=False, timeout=50) - res, msg = results.summarize() - - if res == MCResult.sat: - return {"result": "sat"} - else: - return {"result": res.name, - "description": msg} - - except Exception as e: - return make_error("Supplied with malformed DOML XMI model.", debug_msg=str(e)), 400 diff --git a/mc_openapi/notebooks/csp_compatibility.ipynb b/mc_openapi/notebooks/csp_compatibility.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..7ff29d6570a90c67a3f22f42597bb601b038c597 --- /dev/null +++ b/mc_openapi/notebooks/csp_compatibility.ipynb @@ -0,0 +1,624 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import requests\n", + "from pprint import pprint\n", + "from itertools import groupby" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'AMAZ': [{'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '4.53',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '40',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '0.5',\n", + " 'name': 't2.nano',\n", + " 'optimized for': 'GEPU',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'IEEU'},\n", + " {'availability': '98.2',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '39.75',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '60',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 't2.medium',\n", + " 'optimized for': 'GEPU',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '640',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '120',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '64',\n", + " 'name': 'm4.4xlarge',\n", + " 'optimized for': 'GEPU',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '16',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99.2',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '323',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '100',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '32',\n", + " 'name': 'm5.2xlarge',\n", + " 'optimized for': 'GEPU',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': None,\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99.4',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '268',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '80',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '16',\n", + " 'name': 'c5.2xlarge',\n", + " 'optimized for': 'COOP',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'CANA'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '1304',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '200',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '60',\n", + " 'name': 'c4.8xlarge',\n", + " 'optimized for': 'COOP',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '36',\n", + " 'zone': 'IEEU'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '2209',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '220',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '244',\n", + " 'name': 'g3.8xlarge',\n", + " 'optimized for': 'GPUI',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '32',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99.9',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '5600',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '250',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '488',\n", + " 'name': 'p2.8xlarge',\n", + " 'optimized for': 'GPUI',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '32',\n", + " 'zone': 'UKEU'},\n", + " {'availability': '98.5',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '214',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '70',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '30.5',\n", + " 'name': 'r4.xlarge',\n", + " 'optimized for': 'MEOP',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '4',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '3376',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '80',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '488',\n", + " 'name': 'x1e.4xlarge',\n", + " 'optimized for': 'MEOP',\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '16',\n", + " 'zone': 'DEEU'},\n", + " {'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '200',\n", + " 'frequency per core': None,\n", + " 'instance storage': '410',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '3.7',\n", + " 'name': 'm1.medium',\n", + " 'optimized for': None,\n", + " 'provider': 'AMAZ',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '100',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'USNA'}],\n", + " 'ARSY': [{'availability': '99.5',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '15',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '40',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '1',\n", + " 'name': 'C1_Spain',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99.5',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '15',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '40',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '1',\n", + " 'name': 'C1_USA',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': None,\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99.6',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '40',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '60',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'C2_Europe',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'DEEU'},\n", + " {'availability': '99.6',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '40',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '60',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'C2_UnitedKingdom',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'UKEU'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '80',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '100',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '8',\n", + " 'name': 'C4_Europe',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '4',\n", + " 'zone': None},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '80',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '100',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '8',\n", + " 'name': 'C4_USA',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': None,\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '4',\n", + " 'zone': 'USNA'},\n", + " {'availability': '99.9',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '150',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '200',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '16',\n", + " 'name': 'C8_Germany',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'DEEU'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '150',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '200',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '16',\n", + " 'name': 'C8_Spain',\n", + " 'optimized for': None,\n", + " 'provider': 'ARSY',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': 'VmWare',\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '98.5',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '77',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '100',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '8',\n", + " 'name': 'm5.large',\n", + " 'optimized for': 'GEPU',\n", + " 'provider': 'ARSY',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '1',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'CANA'}],\n", + " 'AZUR': [{'availability': '95',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '93.60',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '20',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'A2v2',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'IEEU'},\n", + " {'availability': '95',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '67',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '20',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'A2v2_USA',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'USNA'},\n", + " {'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '242',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '64',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '32',\n", + " 'name': 'B8_USA',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': None},\n", + " {'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '170',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '64',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '32',\n", + " 'name': 'B8_Germany',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'DEEU'},\n", + " {'availability': '96',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '193',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '120',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '7',\n", + " 'name': 'A3_France',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '4',\n", + " 'zone': 'FREU'},\n", + " {'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '541',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '112',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '56',\n", + " 'name': 'DS13v2',\n", + " 'optimized for': None,\n", + " 'provider': 'AZUR',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': None}],\n", + " 'CLSI': [{'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '186',\n", + " 'frequency per core': '5200',\n", + " 'instance storage': '256',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'VM_1_CS',\n", + " 'optimized for': None,\n", + " 'provider': 'CLSI',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '100',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'ZUEU'}],\n", + " 'GOOG': [{'availability': '96',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '500',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '300',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '60',\n", + " 'name': 'n1-standard-16',\n", + " 'optimized for': None,\n", + " 'provider': 'GOOG',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '4',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '16',\n", + " 'zone': 'DEEU'},\n", + " {'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '552',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '300',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '104',\n", + " 'name': 'n1-highmem-16',\n", + " 'optimized for': 'MEOP',\n", + " 'provider': 'GOOG',\n", + " 'public ip': None,\n", + " 'region': '00NA',\n", + " 'response time: virtual machine performance': '4',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '16',\n", + " 'zone': 'USNA'}],\n", + " 'OPEN': [{'availability': '98',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '10',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '1',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '512',\n", + " 'name': 'm1.tiny',\n", + " 'optimized for': None,\n", + " 'provider': 'OPEN',\n", + " 'public ip': 'IPV4',\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '10',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '20',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '20',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '2',\n", + " 'name': 'm1.small',\n", + " 'optimized for': None,\n", + " 'provider': 'OPEN',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '5',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '1',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99.5',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '40',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '40',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '4',\n", + " 'name': 'm1.medium',\n", + " 'optimized for': None,\n", + " 'provider': 'OPEN',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '4',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '2',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99.6',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '80',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '80',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '8',\n", + " 'name': 'm1.large',\n", + " 'optimized for': None,\n", + " 'provider': 'OPEN',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '3',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '4',\n", + " 'zone': 'SPEU'},\n", + " {'availability': '99.8',\n", + " 'class': 'Virtual Machine',\n", + " 'cost/currency': '160',\n", + " 'frequency per core': '1500',\n", + " 'instance storage': '160',\n", + " 'legal level/accreditations': None,\n", + " 'memory': '16',\n", + " 'name': 'm1.xlarge',\n", + " 'optimized for': None,\n", + " 'provider': 'OPEN',\n", + " 'public ip': None,\n", + " 'region': '00EU',\n", + " 'response time: virtual machine performance': '2',\n", + " 'underpinning technology': None,\n", + " 'virtual cpu cores': '8',\n", + " 'zone': 'SPEU'}]}\n" + ] + } + ], + "source": [ + "IEC_API = 'https://iec.ci.piacere.digital.tecnalia.dev/services/iecbackend/api/root-services/catalogue'\n", + "all_json = requests.get(IEC_API).json()\n", + "\n", + "all_json = [\n", + " {\n", + " 'name': x['serviceName'],\n", + " 'class': x['serviceClass']['serviceClassName'],\n", + " 'props': x['serviceAttributeValues']\n", + " }\n", + " for x in all_json\n", + "]\n", + "\n", + "vms = [vm for vm in all_json if vm['class'] == 'Virtual Machine']\n", + "stos = [vm for vm in all_json if vm['class'] == 'Storage']\n", + "dbs = [vm for vm in all_json if vm['class'] == 'Database']\n", + "\n", + "def flatten_properties(el):\n", + " for p in el['props']:\n", + " el[p['serviceAttributeType']['name'].lower()] = p['serviceAttributeValue'] or None\n", + " el.pop('props', None)\n", + " return el\n", + "\n", + "vms = [flatten_properties(vm) for vm in vms]\n", + "\n", + "vms ={ k: list(v) for k, v in groupby(sorted(vms, key=lambda vm: vm['provider']), lambda vm: vm['provider'])}\n", + "\n", + "pprint(vms)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/dict_reference.ipynb b/mc_openapi/notebooks/dict_reference.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..7307d91f12c97fa324e54f9ef42888f49b86d824 --- /dev/null +++ b/mc_openapi/notebooks/dict_reference.ipynb @@ -0,0 +1,251 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from pprint import pprint\n", + "\n", + "from mc_openapi.doml_mc import ModelChecker, DOMLVersion\n", + "\n", + "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n", + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n", + "# doml_document_path = \"../../tests/doml/faas.domlx\"\n", + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "model_checker = ModelChecker(doc, DOMLVersion.V2_0)\n", + "meta_model = model_checker.metamodel\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "f-string: unmatched '(' (2134446349.py, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn [13], line 2\u001b[0;36m\u001b[0m\n\u001b[0;31m f\"{cname.replace(\"_\", \".\")}.{aname}\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m f-string: unmatched '('\n" + ] + } + ], + "source": [ + "atts = [\n", + " f\"{cname}::{aname}\"\n", + " for cname, c in meta_model.items()\n", + " for aname in c.attributes\n", + "]\n", + "\n", + "pprint(atts)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['commons_DOMLElement.annotations',\n", + " 'commons_Property.reference',\n", + " 'commons_Configuration.deployments',\n", + " 'commons_Deployment.component',\n", + " 'commons_Deployment.node',\n", + " 'application_ApplicationLayer.components',\n", + " 'application_SoftwareComponent.exposedInterfaces',\n", + " 'application_SoftwareComponent.consumedInterfaces',\n", + " 'application_SaaS.exposedInterfaces',\n", + " 'infrastructure_InfrastructureLayer.nodes',\n", + " 'infrastructure_InfrastructureLayer.generators',\n", + " 'infrastructure_InfrastructureLayer.storages',\n", + " 'infrastructure_InfrastructureLayer.faas',\n", + " 'infrastructure_InfrastructureLayer.credentials',\n", + " 'infrastructure_InfrastructureLayer.groups',\n", + " 'infrastructure_InfrastructureLayer.securityGroups',\n", + " 'infrastructure_InfrastructureLayer.networks',\n", + " 'infrastructure_ComputingNode.ifaces',\n", + " 'infrastructure_ComputingNode.location',\n", + " 'infrastructure_ComputingNode.credentials',\n", + " 'infrastructure_ComputingNode.group',\n", + " 'infrastructure_VirtualMachine.generatedFrom',\n", + " 'infrastructure_Container.generatedFrom',\n", + " 'infrastructure_Container.hosts',\n", + " 'infrastructure_VMImage.generatedVMs',\n", + " 'infrastructure_ContainerImage.generatedContainers',\n", + " 'infrastructure_AutoScalingGroup.machineDefinition',\n", + " 'infrastructure_AutoScalingGroup.deploymentNetwork',\n", + " 'infrastructure_AutoScalingGroup.securityGroup',\n", + " 'infrastructure_Storage.ifaces',\n", + " 'infrastructure_FunctionAsAService.ifaces',\n", + " 'infrastructure_Network.connectedIfaces',\n", + " 'infrastructure_Network.igws',\n", + " 'infrastructure_Network.subnets',\n", + " 'infrastructure_Subnet.connectedTo',\n", + " 'infrastructure_NetworkInterface.belongsTo',\n", + " 'infrastructure_NetworkInterface.associated',\n", + " 'infrastructure_ComputingGroup.groupedNodes',\n", + " 'infrastructure_SecurityGroup.rules',\n", + " 'infrastructure_SecurityGroup.ifaces',\n", + " 'infrastructure_SwarmRole.nodes',\n", + " 'infrastructure_Swarm.roles',\n", + " 'concrete_ConcreteInfrastructure.providers',\n", + " 'concrete_RuntimeProvider.vms',\n", + " 'concrete_RuntimeProvider.vmImages',\n", + " 'concrete_RuntimeProvider.containerImages',\n", + " 'concrete_RuntimeProvider.networks',\n", + " 'concrete_RuntimeProvider.storages',\n", + " 'concrete_RuntimeProvider.faas',\n", + " 'concrete_RuntimeProvider.group',\n", + " 'concrete_VirtualMachine.maps',\n", + " 'concrete_VMImage.maps',\n", + " 'concrete_ContainerImage.maps',\n", + " 'concrete_Network.maps',\n", + " 'concrete_Storage.maps',\n", + " 'concrete_FunctionAsAService.maps',\n", + " 'concrete_ComputingGroup.maps']\n" + ] + } + ], + "source": [ + "assocs = [\n", + " f\"{cname}::{aname}\"\n", + " for cname, c in meta_model.items()\n", + " for aname in c.associations\n", + "]\n", + "\n", + "pprint(assocs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'mm' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [10], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m strings \u001b[39m=\u001b[39m [v\n\u001b[0;32m----> 2\u001b[0m \u001b[39mfor\u001b[39;00m c \u001b[39min\u001b[39;00m mm\u001b[39m.\u001b[39mvalues()\n\u001b[1;32m 3\u001b[0m \u001b[39mfor\u001b[39;00m a \u001b[39min\u001b[39;00m c\u001b[39m.\u001b[39mattributes\u001b[39m.\u001b[39mvalues()\n\u001b[1;32m 4\u001b[0m \u001b[39mif\u001b[39;00m a\u001b[39m.\u001b[39mdefault \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m 5\u001b[0m \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m a\u001b[39m.\u001b[39mdefault\n\u001b[1;32m 6\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(v, \u001b[39mstr\u001b[39m)]\n\u001b[1;32m 8\u001b[0m pprint(strings)\n", + "\u001b[0;31mNameError\u001b[0m: name 'mm' is not defined" + ] + } + ], + "source": [ + "strings = [v\n", + " for c in mm.values()\n", + " for a in c.attributes.values()\n", + " if a.default is not None\n", + " for v in a.default\n", + " if isinstance(v, str)]\n", + "\n", + "pprint(strings)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['commons_DOMLElement',\n", + " 'commons_Property',\n", + " 'commons_IProperty',\n", + " 'commons_SProperty',\n", + " 'commons_FProperty',\n", + " 'commons_BProperty',\n", + " 'commons_Configuration',\n", + " 'commons_Deployment',\n", + " 'application_ApplicationLayer',\n", + " 'application_ApplicationComponent',\n", + " 'application_SoftwareComponent',\n", + " 'application_SaaS',\n", + " 'application_SoftwareInterface',\n", + " 'application_DBMS',\n", + " 'application_SaaSDBMS',\n", + " 'infrastructure_InfrastructureLayer',\n", + " 'infrastructure_InfrastructureElement',\n", + " 'infrastructure_ComputingNode',\n", + " 'infrastructure_PhysicalComputingNode',\n", + " 'infrastructure_VirtualMachine',\n", + " 'infrastructure_Location',\n", + " 'infrastructure_Container',\n", + " 'infrastructure_ComputingNodeGenerator',\n", + " 'infrastructure_VMImage',\n", + " 'infrastructure_ContainerImage',\n", + " 'infrastructure_AutoScalingGroup',\n", + " 'infrastructure_Storage',\n", + " 'infrastructure_FunctionAsAService',\n", + " 'infrastructure_Network',\n", + " 'infrastructure_Subnet',\n", + " 'infrastructure_NetworkInterface',\n", + " 'infrastructure_InternetGateway',\n", + " 'infrastructure_ComputingGroup',\n", + " 'infrastructure_SecurityGroup',\n", + " 'infrastructure_Rule',\n", + " 'infrastructure_Credentials',\n", + " 'infrastructure_KeyPair',\n", + " 'infrastructure_UserPass',\n", + " 'infrastructure_SwarmRole',\n", + " 'infrastructure_Swarm',\n", + " 'infrastructure_ExtInfrastructureElement',\n", + " 'concrete_ConcreteInfrastructure',\n", + " 'concrete_ConcreteElement',\n", + " 'concrete_RuntimeProvider',\n", + " 'concrete_VirtualMachine',\n", + " 'concrete_VMImage',\n", + " 'concrete_ContainerImage',\n", + " 'concrete_Network',\n", + " 'concrete_Storage',\n", + " 'concrete_FunctionAsAService',\n", + " 'concrete_ComputingGroup']\n" + ] + } + ], + "source": [ + "keys = list(meta_model.keys())\n", + "\n", + "pprint(keys)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.11.0 ('.venv': poetry)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/doml_mc/example_faas.ipynb b/mc_openapi/notebooks/example_faas.ipynb similarity index 87% rename from mc_openapi/doml_mc/example_faas.ipynb rename to mc_openapi/notebooks/example_faas.ipynb index 00f4e0b2e9fb16ed9ec811a36a33ed6837967329..b377059a68a10a6b6c3adbaeb424bfd59e37f9f8 100644 --- a/mc_openapi/doml_mc/example_faas.ipynb +++ b/mc_openapi/notebooks/example_faas.ipynb @@ -8,7 +8,7 @@ "source": [ "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n", "import yaml\n", - "with open(\"../assets/doml_meta.yaml\") as mmf:\n", + "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n", " mmdoc = yaml.load(mmf, yaml.Loader)\n", "mm = parse_metamodel(mmdoc)\n", "inv_assoc = parse_inverse_associations(mmdoc)" @@ -49,23 +49,13 @@ "outputs": [], "source": [ "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n", - "doml_document_path = \"../../tests/doml/faas.domlx\"\n", - "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n", + "from mc_openapi.doml_mc import DOMLVersion\n", + "doml_document_path = \"../../tests/doml/v2.0/faas.domlx\"\n", "with open(doml_document_path, \"rb\") as xmif:\n", " doc = xmif.read()\n", "\n", - "im = parse_doml_model(doc, mm)\n", - "print(im)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from mc_openapi.doml_mc.intermediate_model.doml_element import reciprocate_inverse_associations\n", - "reciprocate_inverse_associations(im, inv_assoc)" + "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n", + "# print(im)" ] }, { @@ -75,7 +65,7 @@ "outputs": [], "source": [ "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n", - "pp.pprint(im)" + "# pp.pprint(im)" ] }, { @@ -98,9 +88,7 @@ "\n", "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n", " def_association_rel,\n", - " assert_association_rel_constraints,\n", " def_attribute_rel,\n", - " assert_attribute_rel_constraints,\n", " mk_association_sort_dict,\n", " mk_attribute_sort_dict,\n", " mk_class_sort_dict\n", @@ -116,12 +104,12 @@ "\n", "solver = Solver()\n", "\n", - "class_sort, class_ = mk_class_sort_dict(mm)\n", - "assoc_sort, assoc = mk_association_sort_dict(mm)\n", - "attr_sort, attr = mk_attribute_sort_dict(mm)\n", - "elem_sort, elem = mk_elem_sort_dict(im, unbound_elems)\n", - "ss_sort, ss = mk_stringsym_sort_dict(im, mm)\n", - "AData = mk_adata_sort(ss_sort)\n", + "class_sort, class_ = mk_class_sort_dict(mm, solver.ctx)\n", + "assoc_sort, assoc = mk_association_sort_dict(mm, solver.ctx)\n", + "attr_sort, attr = mk_attribute_sort_dict(mm, solver.ctx)\n", + "elem_sort, elem = mk_elem_sort_dict(im, solver.ctx, unbound_elems)\n", + "str_sort, str = mk_stringsym_sort_dict(im, mm, solver.ctx)\n", + "AData = mk_adata_sort(str_sort, solver.ctx)\n", "elem_class_f = def_elem_class_f_and_assert_classes(\n", " im,\n", " solver,\n", @@ -144,7 +132,7 @@ " attr_sort,\n", " attr,\n", " AData,\n", - " ss\n", + " str\n", ")\n", "assoc_rel = def_association_rel(\n", " assoc_sort,\n", @@ -166,36 +154,7 @@ "metadata": {}, "outputs": [], "source": [ - "assert_attribute_rel_constraints(\n", - " mm,\n", - " solver,\n", - " attr_rel,\n", - " attr,\n", - " class_,\n", - " elem_class_f,\n", - " elem_sort,\n", - " AData,\n", - " ss\n", - ")\n", - "assert_association_rel_constraints(\n", - " mm,\n", - " solver,\n", - " assoc_rel,\n", - " assoc,\n", - " class_,\n", - " elem_class_f,\n", - " elem_sort,\n", - " inv_assoc\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# solver.push()" + "solver.push()" ] }, { @@ -246,7 +205,7 @@ "print(\"Number of attributes (IM):\", n_attrs_im)\n", "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n", "print(\"Number of associations (IM):\", n_assocs_im)\n", - "print(\"Number of string symbols:\", len(ss))\n", + "print(\"Number of string symbols:\", len(str))\n", "print(\"Number of IM attribute assertions:\", n_elems)\n", "print(\"Number of IM association assertions:\", n_elems ** 2)" ] @@ -266,16 +225,7 @@ "metadata": {}, "outputs": [], "source": [ - "# solver.unsat_core()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# solver.statistics()" + "solver.unsat_core()" ] }, { @@ -293,7 +243,7 @@ "metadata": {}, "outputs": [], "source": [ - "# All VMs have a network interface.\n", + "# 1. All VMs have a network interface.\n", "vm, iface = Consts(\"vm iface\", elem_sort)\n", "vmIfaceAssertion = ForAll(\n", " [vm],\n", @@ -314,7 +264,7 @@ "metadata": {}, "outputs": [], "source": [ - "# All software packages can see the interfaces they need through a common network.\n", + "# 2. All software packages can see the interfaces they need through a common network.\n", "asc_consumer, asc_exposer, siface, net, net_iface, cn, vm, deployment, dc = Consts(\n", " \"asc_consumer asc_exposer siface net net_iface cn vm deployment dc\", elem_sort\n", ")\n", @@ -383,20 +333,20 @@ "metadata": {}, "outputs": [], "source": [ - "# SoftwareComponents have a source_code property\n", + "# 3. SoftwareComponents have a source_code property\n", "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n", "nginxSourceCode = ForAll(\n", " [softwareComponent],\n", " Implies(\n", " And(\n", " elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n", - " # attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"web\"]))\n", + " # attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"web\"]))\n", " ),\n", " Exists(\n", " [prop],\n", " And(\n", " elem_class_f(prop) == class_[\"commons_SProperty\"],\n", - " attr_rel(prop, attr[\"commons_Property::key\"], AData.ss(ss[\"source_code\"])),\n", + " attr_rel(prop, attr[\"commons_Property::key\"], ADatastr(str[\"source_code\"])),\n", " assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n", " )\n", " )\n", @@ -411,7 +361,7 @@ "metadata": {}, "outputs": [], "source": [ - "# There are no duplicated interfaces\n", + "# 4. There are no duplicated interfaces\n", "def any_iface(elem, iface):\n", " ifaces_assocs = [\n", " \"infrastructure_ComputingNode::ifaces\",\n", @@ -438,7 +388,7 @@ "metadata": {}, "outputs": [], "source": [ - "# All SoftwareComponents have been deployed somewhere\n", + "# 5. All SoftwareComponents have been deployed somewhere\n", "sc, deployment, ielem = Consts(\"sc deployment ielem\", elem_sort)\n", "assn = ForAll(\n", " [sc],\n", @@ -462,7 +412,7 @@ "metadata": {}, "outputs": [], "source": [ - "# All abstract infrastructure elements are mapped to an element in the active concretization\n", + "# 6. All abstract infrastructure elements are mapped to an element in the active concretization\n", "def checkOneClass(ielem, concr, provider, celem, ielemClass, providerAssoc, celemAssoc):\n", " return Implies(\n", " elem_class_f(ielem) == class_[ielemClass],\n", @@ -521,12 +471,12 @@ "metadata": {}, "outputs": [], "source": [ - "# The \"web\" component has access to the Internet through https\n", + "# 7. The \"web\" component has access to the Internet through https\n", "web, deployment, ielem1, ielem2, iface, sg, rule = Consts(\"web deployment ielem1 ielem2 iface sg rule\", elem_sort)\n", "assn = ForAll(\n", " [web],\n", " Implies(\n", - " attr_rel(web, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"web\"])),\n", + " attr_rel(web, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"web\"])),\n", " Exists( # web is deployed on a container hosting a VM with an interface in network n\n", " [deployment, ielem1, ielem2, iface, rule],\n", " And(\n", @@ -538,7 +488,7 @@ " assoc_rel(sg, assoc[\"infrastructure_SecurityGroup::rules\"], rule),\n", " attr_rel(rule, attr[\"infrastructure_Rule::fromPort\"], AData.int(443)),\n", " attr_rel(rule, attr[\"infrastructure_Rule::toPort\"], AData.int(443)),\n", - " attr_rel(rule, attr[\"infrastructure_Rule::kind\"], AData.ss(ss[\"INGRESS\"]))\n", + " attr_rel(rule, attr[\"infrastructure_Rule::kind\"], ADatastr(str[\"INGRESS\"]))\n", " ),\n", " )\n", " )\n", @@ -597,13 +547,10 @@ } ], "metadata": { - "interpreter": { - "hash": "a6678cf6b5907da3ee1c64f7f36cf1b3f0e5fe51f4038e28403f1c01345fc5bd" - }, "kernelspec": { - "display_name": "mc_openapi", + "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')", "language": "python", - "name": "mc_openapi" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -615,9 +562,14 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.10.6" }, - "orig_nbformat": 4 + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed" + } + } }, "nbformat": 4, "nbformat_minor": 2 diff --git a/mc_openapi/notebooks/example_nginx.ipynb b/mc_openapi/notebooks/example_nginx.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..5d6213826f7166dc742f389feb62068f5d34c11d --- /dev/null +++ b/mc_openapi/notebooks/example_nginx.ipynb @@ -0,0 +1,411 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n", + "import yaml\n", + "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n", + " mmdoc = yaml.load(mmf, yaml.Loader)\n", + "mm = parse_metamodel(mmdoc)\n", + "inv_assoc = parse_inverse_associations(mmdoc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import prettyprinter as pp\n", + "from prettyprinter.prettyprinter import IMPLICIT_MODULES\n", + "pp.install_extras(include=['dataclasses'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "IMPLICIT_MODULES.add('doml_mc.intermediate_model.metamodel')\n", + "pp.pprint(mm[\"application_SoftwareComponent\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load the DOML document here:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n", + "from mc_openapi.doml_mc import DOMLVersion\n", + "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n", + "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n", + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n", + "print(im)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n", + "doml_xmi = parse_xmi_model(doc, DOMLVersion.V2_0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(dir(doml_xmi.eClass))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n", + "pp.pprint(im)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "unbound_elems_n = 0\n", + "unbound_elems = [f\"unbound{i}\" for i in range(unbound_elems_n)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from z3 import Solver\n", + "\n", + "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n", + " def_association_rel,\n", + " def_attribute_rel,\n", + " mk_association_sort_dict,\n", + " mk_attribute_sort_dict,\n", + " mk_class_sort_dict\n", + ")\n", + "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n", + " assert_im_associations_q,\n", + " assert_im_attributes,\n", + " def_elem_class_f_and_assert_classes,\n", + " mk_elem_sort_dict,\n", + " mk_stringsym_sort_dict\n", + ")\n", + "from mc_openapi.doml_mc.z3encoding.utils import mk_adata_sort\n", + "\n", + "solver = Solver()\n", + "\n", + "class_sort, class_ = mk_class_sort_dict(mm, solver.ctx)\n", + "assoc_sort, assoc = mk_association_sort_dict(mm, solver.ctx)\n", + "attr_sort, attr = mk_attribute_sort_dict(mm, solver.ctx)\n", + "elem_sort, elem = mk_elem_sort_dict(im, solver.ctx, unbound_elems)\n", + "str_sort, str = mk_stringsym_sort_dict(im, mm, solver.ctx)\n", + "AData = mk_adata_sort(str_sort, solver.ctx)\n", + "elem_class_f = def_elem_class_f_and_assert_classes(\n", + " im,\n", + " solver,\n", + " elem_sort,\n", + " elem,\n", + " class_sort,\n", + " class_\n", + ")\n", + "attr_rel = def_attribute_rel(\n", + " attr_sort,\n", + " elem_sort,\n", + " AData\n", + ")\n", + "assert_im_attributes(\n", + " attr_rel,\n", + " solver,\n", + " im,\n", + " mm,\n", + " elem,\n", + " attr_sort,\n", + " attr,\n", + " AData,\n", + " str\n", + ")\n", + "assoc_rel = def_association_rel(\n", + " assoc_sort,\n", + " elem_sort\n", + ")\n", + "assert_im_associations_q(\n", + " assoc_rel,\n", + " solver,\n", + " {k: v for k, v in im.items() if k not in unbound_elems},\n", + " elem,\n", + " assoc_sort,\n", + " assoc,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# solver.push()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Metamodel statistics" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import get_subclasses_dict\n", + "\n", + "print(\"Number of classes:\", len(mm))\n", + "print(\n", + " \"Number of tuples in the subclass relation:\",\n", + " sum(len(s) for s in get_subclasses_dict(mm).values())\n", + ")\n", + "n_attrs = sum(len(c.attributes) for c in mm.values())\n", + "print(\"Number of attributes:\", n_attrs)\n", + "print(\"Number of attribute assertions:\", 3 * n_attrs)\n", + "n_assocs = sum(len(c.associations) for c in mm.values())\n", + "print(\"Number of associations:\", n_assocs)\n", + "print(\"Number of associations assertions:\", 3 * n_assocs + len(inv_assoc))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DOML model statistics" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n_elems = len(im)\n", + "print(\"Number of elements:\", n_elems)\n", + "n_attrs_im = sum(len(e.attributes) for e in im.values())\n", + "print(\"Number of attributes (IM):\", n_attrs_im)\n", + "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n", + "print(\"Number of associations (IM):\", n_assocs_im)\n", + "print(\"Number of string symbols:\", len(str))\n", + "print(\"Number of IM attribute assertions:\", n_elems)\n", + "print(\"Number of IM association assertions:\", n_elems ** 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solver.check()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solver.unsat_core()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solver.statistics()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from z3 import Consts, ForAll, Exists, Implies, And, Or, Not" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# All VMs have a network interface.\n", + "vm, iface = Consts(\n", + " \"vm iface\", elem_sort\n", + ")\n", + "vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [iface],\n", + " And(\n", + " assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + " )\n", + ")\n", + "solver.assert_and_track(vmIfaceAssertion, \"vm_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Some VM has no network interface. \n", + "vm, iface = Consts(\"vm iface\", elem_sort)\n", + "vmIfaceNegAssertion = And(\n", + " elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n", + " Not(\n", + " Exists(\n", + " [iface],\n", + " assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + ")\n", + "solver.assert_and_track(vmIfaceNegAssertion, \"vm_iface_neg\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# nginx has a source code property\n", + "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n", + "nginxSourceCode = ForAll(\n", + " [softwareComponent],\n", + " Implies(\n", + " And(\n", + " elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n", + " attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"nginx\"]))\n", + " ),\n", + " Exists(\n", + " [prop],\n", + " And(\n", + " elem_class_f(prop) == class_[\"commons_SProperty\"],\n", + " attr_rel(prop, attr[\"commons_Property::key\"], ADatastr(str[\"source_code\"])),\n", + " assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n", + " )\n", + " )\n", + " )\n", + ")\n", + "solver.assert_and_track(nginxSourceCode, \"nginx_source_code\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solver.check()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solver.statistics().memory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = solver.model()\n", + "# print(model)\n", + "print(model[vm])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import product\n", + "for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()):\n", + " if (e1n in unbound_elems or e2n in unbound_elems) and m.eval(assoc_rel(e1, a, e2)):\n", + " print(e1, a, e2)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/find_missing_requirement.ipynb b/mc_openapi/notebooks/find_missing_requirement.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..8229d3b7ffdee975f835a143300012e2767a126c --- /dev/null +++ b/mc_openapi/notebooks/find_missing_requirement.ipynb @@ -0,0 +1,500 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Finding Missing Requirements\n", + "\n", + "In this notebook, I try to put together an iterative way to:\n", + "1. Add *unbound variables* until the requirement is satisfied\n", + "2. Get the *relationships* of the unbound variables\n", + "3. Filter these relationships by adding one at a time as a negated constraint\n", + " and check again the model.\n", + "4. When we find the one that makes the model unsat, it means we've found the right one.\n", + "\n", + "#### Goals\n", + "- Make the search of finding the correct relationship as fast as possible:\n", + " usually relationships are quite a lot, and we need to iterate them at least a\n", + " couple of times. We can add progressively only the relationships that remain\n", + " after each pass, always one at a time and checking the model again." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n", + "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n", + "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n", + "from mc_openapi.doml_mc import DOMLVersion\n", + "from z3 import Solver, Model, DatatypeSortRef, FuncDeclRef, Consts, Const, ForAll, Exists, Implies, And, Or, Not, Bools, sat, unsat\n", + "import yaml\n", + "\n", + "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n", + " def_association_rel,\n", + " def_attribute_rel,\n", + " mk_association_sort_dict,\n", + " mk_attribute_sort_dict,\n", + " mk_class_sort_dict\n", + ")\n", + "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n", + " assert_im_associations,\n", + " assert_im_attributes,\n", + " def_elem_class_f_and_assert_classes,\n", + " mk_elem_sort_dict,\n", + " mk_stringsym_sort_dict,\n", + " mk_attr_data_sort\n", + ")\n", + "from mc_openapi.doml_mc.z3encoding.types import Refs\n", + "\n", + "from itertools import product\n", + "from operator import itemgetter" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n", + " mmdoc = yaml.load(mmf, yaml.Loader)\n", + "mm = parse_metamodel(mmdoc)\n", + "inv_assoc = parse_inverse_associations(mmdoc)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**You can change here the input DOML file**" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0.domlx\"\n", + "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n", + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_iface_uniq.domlx\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n", + "doml_xmi = parse_xmi_model(doc, DOMLVersion.V2_0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need to initialize each time the Solver context before iterating,\n", + "since an unbound variable is an element, and elements are an EnumSort,\n", + "and EnumSorts cannot be modified and depend on the solver context.\n", + "\n", + "The following code is stuff that is already present in the `IntermediateModelChecker`." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Dict\n", + "\n", + "Context = Dict" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "def initialize_solver(\n", + " unbound_elems_quantity: int = 0,\n", + " requirements: list = []\n", + ") -> Context:\n", + " ctx = dict()\n", + " \n", + " ctx[\"solver\"] = Solver()\n", + "\n", + " ctx[\"class_sort\"], ctx[\"class_\"] = mk_class_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"assoc_sort\"], ctx[\"assoc\"] = mk_association_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"attr_sort\"], ctx[\"attr\"] = mk_attribute_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"str_sort\"], ctx[\"str\"] = mk_stringsym_sort_dict(im, mm, ctx[\"solver\"].ctx)\n", + " ctx[\"attr_data_sort\"] = mk_attr_data_sort(ctx[\"str_sort\"], ctx[\"solver\"].ctx)\n", + "\n", + " ctx[\"unbound_elems\"] = [f\"unbound{i}\" for i in range(unbound_elems_quantity)]\n", + " ctx[\"elem_sort\"], ctx[\"elem\"] = mk_elem_sort_dict(im, ctx[\"solver\"].ctx, ctx[\"unbound_elems\"])\n", + "\n", + " ctx[\"elem_class_f\"] = def_elem_class_f_and_assert_classes(\n", + " im,\n", + " ctx[\"solver\"],\n", + " ctx[\"elem_sort\"],\n", + " ctx[\"elem\"],\n", + " ctx[\"class_sort\"],\n", + " ctx[\"class_\"]\n", + " )\n", + " # attr_rel :: (elem_sort, attr_sort, attr_data_sort) -> BoolRef\n", + " ctx[\"attr_rel\"] = def_attribute_rel(\n", + " ctx[\"attr_sort\"],\n", + " ctx[\"elem_sort\"],\n", + " ctx[\"attr_data_sort\"]\n", + " )\n", + " assert_im_attributes(\n", + " ctx[\"attr_rel\"],\n", + " ctx[\"solver\"],\n", + " im,\n", + " mm,\n", + " ctx[\"elem\"],\n", + " ctx[\"attr_sort\"],\n", + " ctx[\"attr\"],\n", + " ctx[\"attr_data_sort\"],\n", + " ctx[\"str\"]\n", + " )\n", + "\n", + " # assoc_rel :: (elem_sort, assoc_sort, elem_sort) -> BoolRef\n", + " ctx[\"assoc_rel\"] = def_association_rel(\n", + " ctx[\"assoc_sort\"],\n", + " ctx[\"elem_sort\"]\n", + " )\n", + " assert_im_associations(\n", + " ctx[\"assoc_rel\"],\n", + " ctx[\"solver\"],\n", + " {k: v for k, v in im.items() if k not in ctx[\"unbound_elems\"]},\n", + " ctx[\"elem\"],\n", + " ctx[\"assoc_sort\"],\n", + " ctx[\"assoc\"],\n", + " )\n", + "\n", + " # Add requirements\n", + " for req in requirements:\n", + " req(ctx)\n", + "\n", + " return ctx" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "def req_every_vm_has_iface(ctx: Context): \n", + " vm, iface = Consts(\"vm iface\", ctx[\"elem_sort\"])\n", + " vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [iface],\n", + " And(\n", + " ctx[\"assoc_rel\"](vm, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "def req_every_iface_has_a_secgroup(ctx):\n", + " sg, iface = Consts(\"sg iface\", ctx[\"elem_sort\"])\n", + " vmIfaceSecGroupAssertion = ForAll(\n", + " [sg],\n", + " Implies(\n", + " ctx[\"elem_class_f\"](sg) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n", + " Exists([iface], \n", + " ctx[\"assoc_rel\"](iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sg)\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(vmIfaceSecGroupAssertion, \"vm_secgroup\")" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# There are no duplicated interfaces.\n", + "def req_iface_uniq(ctx):\n", + " endPointAttr = ctx[\"attr\"][\"infrastructure_NetworkInterface::endPoint\"]\n", + " ni1, ni2 = Consts(\"ni1, ni2\", ctx[\"elem_sort\"])\n", + " value = Const(\"value\", ctx[\"attr_data_sort\"])\n", + " uniqueIfaceAssertion = And(\n", + " ctx[\"attr_rel\"](ni1, endPointAttr, value),\n", + " ctx[\"attr_rel\"](ni2, endPointAttr, value),\n", + " ni1 != ni2,\n", + " )\n", + " ctx[\"solver\"].assert_and_track(uniqueIfaceAssertion, \"unique_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "def check_with_ubvars(ubvars_n: int = 0, requirements: list = []) -> Context:\n", + " ctx = initialize_solver(ubvars_n, requirements)\n", + " solver = ctx[\"solver\"]\n", + "\n", + " res = solver.check()\n", + "\n", + " if res == sat:\n", + " print(f\"Sat with {ubvars_n} unbounded variables\")\n", + " return ctx\n", + " elif res == unsat:\n", + " # print(f\"ubvars={ubvars_n}; UNSAT_CORE:\")\n", + " # print(solver.unsat_core())\n", + " print(f\"Increasing unbound vars to {ubvars_n + 1}\")\n", + " return check_with_ubvars(ubvars_n + 1, requirements=requirements)\n", + " else:\n", + " raise RuntimeError(\"It took too long to decide.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "REQUIREMENTS = [\n", + " req_every_vm_has_iface,\n", + " req_every_iface_has_a_secgroup,\n", + " req_iface_uniq\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Increasing unbound vars to 1\n", + "Increasing unbound vars to 2\n", + "Sat with 2 unbounded variables\n" + ] + } + ], + "source": [ + "solved_ctx = check_with_ubvars(requirements=REQUIREMENTS)\n", + "solved_model = solved_ctx[\"solver\"].model()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "def get_ubvars_and_assoc(ctx: Context, model: Model):\n", + " elem, assoc, assoc_rel, unbound_elems = itemgetter(\"elem\", \"assoc\", \"assoc_rel\", \"unbound_elems\")(ctx)\n", + "\n", + " return [ ((e1n, e1), a, (e2n, e2)) \n", + " for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()) \n", + " if (e1n in unbound_elems or e2n in unbound_elems) and model.eval(assoc_rel(e1, a, e2))\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "def pretty_ubvar_assoc(assoc):\n", + " (e1n, e1), a, (e2n, e2) = assoc\n", + " tokens = str(str(e1) + \" \" + str(a) + \" \" + str(e2)).split()\n", + " ret_str = \"\"\n", + " for token in tokens:\n", + " if token[0:4] == \"elem\":\n", + " value = im.get(token)\n", + " ret_str += f\"{value.class_} ({value.user_friendly_name})\" if value else f\"<'{token}' not found>\"\n", + " else:\n", + " ret_str += token\n", + " ret_str += \" \"\n", + " return ret_str.strip()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see, there are many associations that involve the unbound variable `unbound0`.\n", + "We can see that between them, there is the one we really want:\n", + "\n", + "`infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound0`\n", + "\n", + "We now need to filter out all the others, by taking one of these lines at a time, and adding it as a negated constraint.\n", + "\n", + "NOTE: It appears that the list is not deterministic. Sometimes at the end there are associations that start from `unbound0`, sometimes there is none. " + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "ubvars_and_assoc = get_ubvars_and_assoc(solved_ctx, solved_model)\n", + "# print(\"\\n\".join([pretty_ubvar_assoc(assoc) for assoc in ubvars_and_assoc]))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-----------------------------------------\n", + "\tAdd constraint Not(infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound0)\n" + ] + }, + { + "ename": "Z3Exception", + "evalue": "True, False or Z3 Boolean expression expected. Received [__neg_{e1_name}_{str(a)}_{e2_name}] of type <class 'list'>", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mZ3Exception\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [52], line 44\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39m\\t\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m \u001b[39m+\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mjoin([pretty_ubvar_assoc(assoc) \u001b[39mfor\u001b[39;00m assoc \u001b[39min\u001b[39;00m ubvars_and_assoc[\u001b[39m1\u001b[39m:]]))\n\u001b[1;32m 41\u001b[0m \u001b[39mreturn\u001b[39;00m [\u001b[39m*\u001b[39m\u001b[39mset\u001b[39m([assoc] \u001b[39m+\u001b[39m thin_ubvars_and_assoc(ctx, ubvars_and_assoc[\u001b[39m1\u001b[39m:]))]\n\u001b[0;32m---> 44\u001b[0m assoc_to_implement \u001b[39m=\u001b[39m thin_ubvars_and_assoc(solved_ctx, ubvars_and_assoc)\n", + "Cell \u001b[0;32mIn [52], line 18\u001b[0m, in \u001b[0;36mthin_ubvars_and_assoc\u001b[0;34m(ctx, ubvars_and_assoc)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[39m# ctx[\"solver\"].assert_and_track(Not(assoc_rel), f\"__neg_{e1_name}_{str(a)}_{e2_name}\")\u001b[39;00m\n\u001b[1;32m 17\u001b[0m x \u001b[39m=\u001b[39m Bools(\u001b[39m\"\u001b[39m\u001b[39m__neg_\u001b[39m\u001b[39m{e1_name}\u001b[39;00m\u001b[39m_\u001b[39m\u001b[39m{\u001b[39m\u001b[39mstr(a)}_\u001b[39m\u001b[39m{e2_name}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m---> 18\u001b[0m ctx[\u001b[39m\"\u001b[39m\u001b[39msolver\u001b[39m\u001b[39m\"\u001b[39m]\u001b[39m.\u001b[39madd(Implies(x, Not(assoc_rel)))\n\u001b[1;32m 20\u001b[0m res \u001b[39m=\u001b[39m ctx[\u001b[39m\"\u001b[39m\u001b[39msolver\u001b[39m\u001b[39m\"\u001b[39m]\u001b[39m.\u001b[39mcheck()\n\u001b[1;32m 21\u001b[0m \u001b[39mif\u001b[39;00m res \u001b[39m==\u001b[39m sat:\n", + "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:1785\u001b[0m, in \u001b[0;36mImplies\u001b[0;34m(a, b, ctx)\u001b[0m\n\u001b[1;32m 1783\u001b[0m ctx \u001b[39m=\u001b[39m _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))\n\u001b[1;32m 1784\u001b[0m s \u001b[39m=\u001b[39m BoolSort(ctx)\n\u001b[0;32m-> 1785\u001b[0m a \u001b[39m=\u001b[39m s\u001b[39m.\u001b[39;49mcast(a)\n\u001b[1;32m 1786\u001b[0m b \u001b[39m=\u001b[39m s\u001b[39m.\u001b[39mcast(b)\n\u001b[1;32m 1787\u001b[0m \u001b[39mreturn\u001b[39;00m BoolRef(Z3_mk_implies(ctx\u001b[39m.\u001b[39mref(), a\u001b[39m.\u001b[39mas_ast(), b\u001b[39m.\u001b[39mas_ast()), ctx)\n", + "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:1528\u001b[0m, in \u001b[0;36mBoolSortRef.cast\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m 1526\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m is_expr(val):\n\u001b[1;32m 1527\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mTrue, False or Z3 Boolean expression expected. Received \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m of type \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m\n\u001b[0;32m-> 1528\u001b[0m _z3_assert(is_expr(val), msg \u001b[39m%\u001b[39;49m (val, \u001b[39mtype\u001b[39;49m(val)))\n\u001b[1;32m 1529\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39meq(val\u001b[39m.\u001b[39msort()):\n\u001b[1;32m 1530\u001b[0m _z3_assert(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39meq(val\u001b[39m.\u001b[39msort()), \u001b[39m\"\u001b[39m\u001b[39mValue cannot be converted into a Z3 Boolean value\u001b[39m\u001b[39m\"\u001b[39m)\n", + "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:107\u001b[0m, in \u001b[0;36m_z3_assert\u001b[0;34m(cond, msg)\u001b[0m\n\u001b[1;32m 105\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_z3_assert\u001b[39m(cond, msg):\n\u001b[1;32m 106\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m cond:\n\u001b[0;32m--> 107\u001b[0m \u001b[39mraise\u001b[39;00m Z3Exception(msg)\n", + "\u001b[0;31mZ3Exception\u001b[0m: True, False or Z3 Boolean expression expected. Received [__neg_{e1_name}_{str(a)}_{e2_name}] of type <class 'list'>" + ] + } + ], + "source": [ + "def thin_ubvars_and_assoc(ctx: Context, ubvars_and_assoc: list):\n", + " \"\"\"Returns a tuple where the first item is\n", + " \"\"\"\n", + " if not ubvars_and_assoc:\n", + " return []\n", + "\n", + "\n", + " (e1_name, e1), a, (e2_name, e2) = assoc = ubvars_and_assoc[0]\n", + " assoc_rel = ctx[\"assoc_rel\"](e1, a, e2)\n", + " \n", + " print(\"-----------------------------------------\")\n", + "\n", + " # Add negated constraint\n", + " print(f\"\\tAdd constraint Not({pretty_ubvar_assoc(ubvars_and_assoc[0])})\")\n", + " ctx[\"solver\"].push()\n", + " # ctx[\"solver\"].assert_and_track(Not(assoc_rel), f\"__neg_{e1_name}_{str(a)}_{e2_name}\")\n", + " ctx[\"solver\"].add(Not(assoc_rel))\n", + " \n", + " res = ctx[\"solver\"].check()\n", + " if res == sat:\n", + " print(\"SAT:\\tAdding one more constraint and trying again\")\n", + " # Get new ubvars_and_assoc\n", + " model = ctx[\"solver\"].model()\n", + " thinned_ubvars_and_assoc = get_ubvars_and_assoc(ctx, model)\n", + " \n", + " # Print table showing the diff\n", + " from difflib import context_diff\n", + " uvar_as_text = lambda input: [pretty_ubvar_assoc(assoc) for assoc in input]\n", + " print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubvars_and_assoc), uvar_as_text(thinned_ubvars_and_assoc), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n", + "\n", + " # Iterate\n", + " return thin_ubvars_and_assoc(ctx, thinned_ubvars_and_assoc)\n", + " else:\n", + " print(\"UNSAT\\tLast constraint was the association we are looking for!\")\n", + " ctx[\"solver\"].pop()\n", + " \n", + " if ubvars_and_assoc[1:]:\n", + " print(\"\\tIterating over\")\n", + " print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubvar_assoc(assoc) for assoc in ubvars_and_assoc[1:]]))\n", + " return [*set([assoc] + thin_ubvars_and_assoc(ctx, ubvars_and_assoc[1:]))]\n", + "\n", + "\n", + "assoc_to_implement = thin_ubvars_and_assoc(solved_ctx, ubvars_and_assoc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound1\n", + "unbound1 infrastructure_NetworkInterface::associated infrastructure_SecurityGroup (sg)\n" + ] + } + ], + "source": [ + "print(\"\\n\".join([pretty_ubvar_assoc(assoc) for assoc in assoc_to_implement]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From here, we should then add this in the Intermediate Model, and then in the ECore (?) to generate the DOML file somehow.\n", + "\n", + "We can then provide the new file, or a diff to be patched onto the original?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.7 ('.venv': poetry)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb b/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a30bc463263626ab2c0341274b13f75b22d171ef --- /dev/null +++ b/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb @@ -0,0 +1,773 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Finding Missing Requirements (with Attributes)\n", + "\n", + "In this notebook, I try to put together an iterative way to:\n", + "1. Add *unbound variables* until the requirement is satisfied\n", + "2. Get the *relationships* of the unbound variables\n", + "3. Filter these relationships by adding one at a time as a negated constraint\n", + " and check again the model.\n", + "4. When we find the one that makes the model unsat, it means we've found the right one.\n", + "\n", + "#### Goals\n", + "- Make the search of finding the correct relationship as fast as possible:\n", + " usually relationships are quite a lot, and we need to iterate them at least a\n", + " couple of times. We can add progressively only the relationships that remain\n", + " after each pass, always one at a time and checking the model again." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import product\n", + "from operator import itemgetter\n", + "\n", + "import yaml\n", + "from z3 import (And, Const, Consts, DatatypeSortRef, Exists, ForAll,\n", + " FuncDeclRef, Implies, Model, Not, Or, Solver, sat, unsat)\n", + "\n", + "from mc_openapi.doml_mc import DOMLVersion\n", + "from mc_openapi.doml_mc.intermediate_model.metamodel import (\n", + " parse_inverse_associations, parse_metamodel)\n", + "from mc_openapi.doml_mc.xmi_parser.doml_model import (parse_doml_model,\n", + " parse_xmi_model)\n", + "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n", + " assert_im_associations, assert_im_attributes,\n", + " def_elem_class_f_and_assert_classes, mk_attr_data_sort, mk_elem_sort_dict,\n", + " mk_stringsym_sort_dict)\n", + "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n", + " def_association_rel, def_attribute_rel, mk_association_sort_dict,\n", + " mk_attribute_sort_dict, mk_class_sort_dict)\n", + "from mc_openapi.doml_mc.z3encoding.types import Refs" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n", + " mmdoc = yaml.load(mmf, yaml.Loader)\n", + "mm = parse_metamodel(mmdoc)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**You can change here the input DOML file**" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0.domlx\"\n", + "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n", + "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_iface_uniq.domlx\"\n", + "# doml_document_path = \"../../tests/doml/saas_no_https_rule.domlx\"\n", + "# doml_document_path = \"../../tests/doml/saas_https_no_attrs.domlx\"\n", + "doml_document_path = \"../../tests/doml/openstack_template.domlx\"" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "with open(doml_document_path, \"rb\") as xmif:\n", + " doc = xmif.read()\n", + "\n", + "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need to initialize each time the Solver context before iterating,\n", + "since an unbound variable is an element, and elements are an EnumSort,\n", + "and EnumSorts cannot be modified and depend on the solver context.\n", + "\n", + "The following code is stuff that is already present in the `IntermediateModelChecker`." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Dict\n", + "\n", + "Context = Dict" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import get_mangled_attribute_defaults\n", + "\n", + "\n", + "def initialize_solver(\n", + " unbound_elems_quantity: int = 0,\n", + " unbound_values_quantity: int = 0,\n", + " requirements: list = []\n", + ") -> Context:\n", + " ctx = dict()\n", + " \n", + " ctx[\"solver\"] = Solver()\n", + "\n", + " ctx[\"class_sort\"], ctx[\"class_\"] = mk_class_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"assoc_sort\"], ctx[\"assoc\"] = mk_association_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"attr_sort\"], ctx[\"attr\"] = mk_attribute_sort_dict(mm, ctx[\"solver\"].ctx)\n", + " ctx[\"str_sort\"], ctx[\"str\"] = mk_stringsym_sort_dict(im, mm, ctx[\"solver\"].ctx)\n", + " ctx[\"attr_data_sort\"] = mk_attr_data_sort(ctx[\"str_sort\"], ctx[\"solver\"].ctx)\n", + "\n", + " ctx[\"unbound_elems\"] = [f\"unbound_elem_{i}\" for i in range(unbound_elems_quantity)]\n", + "\n", + " # Takes a list of strings and creates an Enum out of 'em\n", + " ctx[\"elem_sort\"], ctx[\"elem\"] = mk_elem_sort_dict(im, ctx[\"solver\"].ctx, ctx[\"unbound_elems\"])\n", + "\n", + " ub_val_names = [f\"unbound_val_{i}\" for i in range(unbound_values_quantity)]\n", + " ctx[\"unbound_values\"] = {\n", + " name : ctx[\"attr_data_sort\"].placeholder for name in ub_val_names\n", + " }\n", + " # Examples of values that can go in unbound_values:\n", + " # ctx[\"attr_data_sort\"].int(42), # ok\n", + " # ctx[\"attr_data_sort\"].bool(True), # ok\n", + " # ctx[\"attr_data_sort\"].str(\"x\"), # cant do: it accept a ctx[\"str\"][<str_key>] as input\n", + " # Const(\"x\", ctx[\"attr_data_sort\"]) # cant do: it is a symbolic value that cannot be converted to a BoolRef expression\n", + "\n", + " ctx[\"elem_class_f\"] = def_elem_class_f_and_assert_classes(\n", + " im,\n", + " ctx[\"solver\"],\n", + " ctx[\"elem_sort\"],\n", + " ctx[\"elem\"],\n", + " ctx[\"class_sort\"],\n", + " ctx[\"class_\"]\n", + " )\n", + " \n", + " # attr_rel :: (elem_sort, attr_sort, attr_data_sort) -> BoolRef\n", + " ctx[\"attr_rel\"] = def_attribute_rel(\n", + " ctx[\"attr_sort\"],\n", + " ctx[\"elem_sort\"],\n", + " ctx[\"attr_data_sort\"]\n", + " )\n", + "\n", + " assert_im_attributes(\n", + " ctx[\"attr_rel\"],\n", + " ctx[\"solver\"],\n", + " im,\n", + " mm,\n", + " ctx[\"elem\"],\n", + " ctx[\"attr_sort\"],\n", + " ctx[\"attr\"],\n", + " ctx[\"attr_data_sort\"],\n", + " ctx[\"str\"]\n", + " )\n", + "\n", + " # assoc_rel :: (elem_sort, assoc_sort, elem_sort) -> BoolRef\n", + " ctx[\"assoc_rel\"] = def_association_rel(\n", + " ctx[\"assoc_sort\"],\n", + " ctx[\"elem_sort\"]\n", + " )\n", + " \n", + " assert_im_associations(\n", + " ctx[\"assoc_rel\"],\n", + " ctx[\"solver\"],\n", + " {k: v for k, v in im.items() if k not in ctx[\"unbound_elems\"]},\n", + " ctx[\"elem\"],\n", + " ctx[\"assoc_sort\"],\n", + " ctx[\"assoc\"],\n", + " )\n", + "\n", + " # Add requirements\n", + " for req in requirements:\n", + " req(ctx)\n", + "\n", + " return ctx" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "def req_every_vm_has_iface(ctx: Context): \n", + " vm, iface = Consts(\"vm iface\", ctx[\"elem_sort\"])\n", + " vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [iface],\n", + " And(\n", + " ctx[\"assoc_rel\"](vm, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], iface)\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "def req_every_vm_has_cpucount(ctx: Context): \n", + " vm = Const(\"vm\", ctx[\"elem_sort\"])\n", + " CpuCount = Const(\"cpucount\", ctx[\"attr_data_sort\"])\n", + " vmIfaceAssertion = ForAll(\n", + " [vm],\n", + " Implies(\n", + " ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n", + " Exists(\n", + " [CpuCount],\n", + " And(\n", + " ctx[\"attr_rel\"](vm, ctx[\"attr\"][\"infrastructure_ComputingNode::cpu_count\"], CpuCount)\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_cpucount\")" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "def req_every_iface_has_a_secgroup(ctx):\n", + " sg, iface = Consts(\"sg iface\", ctx[\"elem_sort\"])\n", + " vmIfaceSecGroupAssertion = ForAll(\n", + " [sg],\n", + " Implies(\n", + " ctx[\"elem_class_f\"](sg) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n", + " Exists([iface], \n", + " ctx[\"assoc_rel\"](iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sg)\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(vmIfaceSecGroupAssertion, \"vm_secgroup\")" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "def req_iface_uniq(ctx):\n", + " endPointAttr = ctx[\"attr\"][\"infrastructure_NetworkInterface::endPoint\"]\n", + " ni1, ni2 = Consts(\"ni1 ni2\", ctx[\"elem_sort\"])\n", + " value = Const(\"value\", ctx[\"attr_data_sort\"])\n", + " uniqueIfaceAssertion = And(\n", + " ctx[\"attr_rel\"](ni1, endPointAttr, value),\n", + " ctx[\"attr_rel\"](ni2, endPointAttr, value),\n", + " ni1 != ni2,\n", + " )\n", + " ctx[\"solver\"].assert_and_track(uniqueIfaceAssertion, \"unique_iface\")" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "def req_external_services_must_have_https(ctx):\n", + " saas, sw_iface, sw_comp, deployment, ielem, net_iface, sec_group, rule = Consts(\"saas, sw_iface, sw_comp, deployment, ielem, net_iface, sec_group, rule\", ctx[\"elem_sort\"])\n", + " assertion = ForAll(\n", + " [saas, sec_group, sw_iface, sw_comp, deployment, ielem, net_iface],\n", + " Implies(\n", + " And(\n", + " ctx[\"elem_class_f\"](saas) == ctx[\"class_\"][\"application_SaaS\"],\n", + " ctx[\"elem_class_f\"](sec_group) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n", + " ctx[\"assoc_rel\"](saas, ctx[\"assoc\"][\"application_SaaS::exposedInterfaces\"], sw_iface),\n", + " ctx[\"assoc_rel\"](sw_comp, ctx[\"assoc\"][\"application_SoftwareComponent::consumedInterfaces\"], sw_iface),\n", + " ctx[\"assoc_rel\"](deployment, ctx[\"assoc\"][\"commons_Deployment::component\"], sw_comp),\n", + " ctx[\"assoc_rel\"](deployment, ctx[\"assoc\"][\"commons_Deployment::node\"], ielem),\n", + " ctx[\"assoc_rel\"](ielem, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], net_iface),\n", + " ctx[\"assoc_rel\"](net_iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sec_group),\n", + " ctx[\"assoc_rel\"](sec_group, ctx[\"assoc\"][\"infrastructure_SecurityGroup::rules\"], rule),\n", + " ),\n", + " Exists([rule],\n", + " And(\n", + " # Every node that contacts an external service should belong to a security group implementing HTTPS\n", + " ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::fromPort\"], ctx[\"attr_data_sort\"].int(443)),\n", + " ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::toPort\"], ctx[\"attr_data_sort\"].int(443)),\n", + " ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::kind\"], ctx[\"attr_data_sort\"].str(ctx[\"str\"][\"INGRESS\"]))\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ctx[\"solver\"].assert_and_track(assertion, \"ext_service_https\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### REMEMBER TO ADD REQUIREMENTS TO THE LIST!" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "REQUIREMENTS = [\n", + " req_every_vm_has_iface,\n", + " # req_every_vm_has_cpucount\n", + " # req_every_iface_has_a_secgroup,\n", + " # req_iface_uniq,\n", + " # req_external_services_must_have_https\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "def check_iteratively(ubelems_n: int = 0, ubvals_n: int = 0, requirements: list = [], curr_try: int = 0, max_tries: int = 10) -> Context:\n", + " if curr_try > max_tries:\n", + " raise RuntimeError(\"Max tries exceeded.\")\n", + "\n", + " ctx = initialize_solver(ubelems_n, ubvals_n, requirements)\n", + " solver = ctx[\"solver\"]\n", + "\n", + " res = solver.check()\n", + "\n", + " if res == sat:\n", + " print(\"\\033[92m\" + f\"<Sat>\\tubelems_n={ubelems_n}, ubvals_n={ubvals_n}\" + \"\\033[0m\")\n", + " return ctx\n", + " elif res == unsat:\n", + " print(\"\\033[91m\" + f\"<Unsat>\\tubelems_n={ubelems_n}, ubvals_n={ubvals_n}\" + \"\\033[0m\")\n", + " if ubelems_n > ubvals_n:\n", + " new_ubvals_n = ubvals_n * 2 if ubvals_n >= 1 else 1\n", + " return check_iteratively(ubelems_n, new_ubvals_n, requirements, curr_try + 1, max_tries)\n", + " # TODO: Choose which goes first\n", + " elif ubelems_n <= ubvals_n:\n", + " new_ubelems_n = ubelems_n * 2 if ubelems_n >= 1 else 1\n", + " return check_iteratively(new_ubelems_n, ubvals_n, requirements, curr_try + 1, max_tries)\n", + " else: # res == dontknow\n", + " raise RuntimeError(\"It took too long to decide.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[91m<Unsat>\tubelems_n=0, ubvals_n=0\u001b[0m\n", + "\u001b[92m<Sat>\tubelems_n=1, ubvals_n=0\u001b[0m\n" + ] + } + ], + "source": [ + "solved_ctx = check_iteratively(0, 0, requirements=REQUIREMENTS)\n", + "\n", + "solved_model = solved_ctx[\"solver\"].model()" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "def get_ubelems_and_assoc(ctx: Context, model: Model):\n", + " elem, assoc, assoc_rel, unbound_elems = itemgetter(\"elem\", \"assoc\", \"assoc_rel\", \"unbound_elems\")(ctx)\n", + "\n", + " return [ ((e1n, e1), a, (e2n, e2)) \n", + " for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()) \n", + " if (e1n in unbound_elems or e2n in unbound_elems) and model.eval(assoc_rel(e1, a, e2))\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "def get_ubvals_and_attr(ctx: Context, model: Model):\n", + " elem, attr, attr_rel, unbound_values = itemgetter(\"elem\", \"attr\", \"attr_rel\", \"unbound_values\")(ctx)\n", + "\n", + " return [ ((elem_k, elem_v), a, (ubval_k, ubval_v))\n", + " for (elem_k, elem_v), a, (ubval_k, ubval_v) in product(elem.items(), attr.values(), unbound_values.items())\n", + " if model.eval(attr_rel(elem_v, a, ubval_v))\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "# Utility code to print the names of associations and attributes in a human-readable way\n", + "def pretty_ubelems_assoc(assoc):\n", + " (elem_1_k, elem_1_v), a, (elem_2_k, elem_2_v) = assoc\n", + " elem_1 = im.get(elem_1_k)\n", + " if elem_1:\n", + " elem_1_name = f\"{elem_1.class_} ({elem_1.user_friendly_name})\" if elem_1_k[0:4] == \"elem\" else f\"<'{elem_1_k}' not found>\"\n", + " else:\n", + " elem_1_name = elem_1_k\n", + " \n", + " elem_2 = im.get(elem_2_k)\n", + " if elem_2:\n", + " elem_2_name = f\"{elem_2.class_} ({elem_2.user_friendly_name})\" if elem_2_k[0:4] == \"elem\" else f\"<'{elem_2_k}' not found>\"\n", + " else:\n", + " elem_2_name = elem_2_k\n", + " \n", + " assoc_name = str(a)\n", + "\n", + " return f\"{elem_1_name:<50s} {assoc_name:<60s} {elem_2_name:<30s}\"\n", + "\n", + "def pretty_ubvals_attrs(attrs):\n", + " (elem_k, elem_v), a, (ubval_k, ubval_v) = attrs\n", + "\n", + " elem_1 = im.get(elem_k)\n", + " if elem_1:\n", + " elem_1_name = f\"{elem_1.class_} ({elem_1.user_friendly_name})\" if elem_k[0:4] == \"elem\" else f\"<'{elem_k}' not found>\"\n", + " else:\n", + " elem_1_name = elem_k\n", + "\n", + " attr_name = str(a)\n", + "\n", + " val_name = str(ubval_k)\n", + "\n", + " return f\"{elem_1_name:<50s} {attr_name:<60s} {val_name:<30s}\"" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "infrastructure_VirtualMachine (vm1) commons_Property::reference unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) application_SoftwareComponent::exposedInterfaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) application_SoftwareComponent::consumedInterfaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) application_SaaS::exposedInterfaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::generators unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::storages unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::faas unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::credentials unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::groups unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::securityGroups unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::networks unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::location unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::credentials unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::group unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_VirtualMachine::generatedFrom unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Container::generatedFrom unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Container::hosts unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_VMImage::generatedVMs unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ContainerImage::generatedContainers unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::machineDefinition unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::deploymentNetwork unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::securityGroup unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Storage::ifaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_FunctionAsAService::ifaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Network::connectedIfaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Network::igws unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Network::subnets unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Subnet::connectedTo unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_NetworkInterface::belongsTo unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_NetworkInterface::associated unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingGroup::groupedNodes unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_SecurityGroup::rules unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_SecurityGroup::ifaces unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_SwarmRole::nodes unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) infrastructure_Swarm::roles unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::vmImages unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::containerImages unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::networks unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::storages unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::faas unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::group unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_VMImage::maps unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_ContainerImage::maps unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_Network::maps unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_Storage::maps unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_FunctionAsAService::maps unbound_elem_0 \n", + "infrastructure_VirtualMachine (vm1) concrete_ComputingGroup::maps unbound_elem_0 \n", + "------------------------------------------------------------------------------------------------------------------------\n", + "\n" + ] + } + ], + "source": [ + "ubelems_and_assoc = get_ubelems_and_assoc(solved_ctx, solved_model)\n", + "print(\"\\n\".join([pretty_ubelems_assoc(assoc) for assoc in ubelems_and_assoc]))\n", + "\n", + "print(\"-\" * 120)\n", + "\n", + "ubvals_and_attr = get_ubvals_and_attr(solved_ctx, solved_model)\n", + "print(\"\\n\".join([pretty_ubvals_attrs(attr) for attr in ubvals_and_attr]))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\tAdd constraint Not(infrastructure_VirtualMachine (vm1) commons_Property::reference unbound_elem_0 )\n", + "SAT:\tAdding one more constraint and trying again\n", + "*** Before\n", + "--- After\n", + "***************\n", + "*** 1,48 ****\n", + "- infrastructure_VirtualMachine (vm1) commons_Property::reference unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) application_SoftwareComponent::exposedInterfaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) application_SoftwareComponent::consumedInterfaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) application_SaaS::exposedInterfaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::generators unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::storages unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::faas unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::credentials unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::groups unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::securityGroups unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_InfrastructureLayer::networks unbound_elem_0 \n", + " infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::location unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::credentials unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::group unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_VirtualMachine::generatedFrom unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Container::generatedFrom unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Container::hosts unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_VMImage::generatedVMs unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_ContainerImage::generatedContainers unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::machineDefinition unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::deploymentNetwork unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_AutoScalingGroup::securityGroup unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Storage::ifaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_FunctionAsAService::ifaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Network::connectedIfaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Network::igws unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Network::subnets unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Subnet::connectedTo unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_NetworkInterface::belongsTo unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_NetworkInterface::associated unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_ComputingGroup::groupedNodes unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_SecurityGroup::rules unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_SecurityGroup::ifaces unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_SwarmRole::nodes unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) infrastructure_Swarm::roles unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::vmImages unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::containerImages unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::networks unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::storages unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::faas unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_RuntimeProvider::group unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_VMImage::maps unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_ContainerImage::maps unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_Network::maps unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_Storage::maps unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_FunctionAsAService::maps unbound_elem_0 \n", + "- infrastructure_VirtualMachine (vm1) concrete_ComputingGroup::maps unbound_elem_0 \n", + "--- 1 ----\n", + "\tAdd constraint Not(infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound_elem_0 )\n", + "UNSAT\tLast constraint was the association we are looking for!\n" + ] + } + ], + "source": [ + "def thin_ubelems_and_assoc(ctx: Context, ubelems_and_assoc: list):\n", + " if not ubelems_and_assoc:\n", + " return []\n", + "\n", + " (_, elem_1_v), a, (_, elem_2_v) = assoc = ubelems_and_assoc[0]\n", + " assoc_rel = ctx[\"assoc_rel\"](elem_1_v, a, elem_2_v)\n", + "\n", + " # Add negated constraint\n", + " ctx[\"solver\"].push()\n", + " print(f\"\\tAdd constraint Not({pretty_ubelems_assoc(assoc)})\")\n", + " ctx[\"solver\"].add(Not(assoc_rel))\n", + " \n", + " res = ctx[\"solver\"].check()\n", + " \n", + " if res == sat:\n", + " print(\"SAT:\\tAdding one more constraint and trying again\")\n", + " # Get new ubelems_and_assoc\n", + " model = ctx[\"solver\"].model()\n", + " thinned_ubelems_and_assoc = get_ubelems_and_assoc(ctx, model)\n", + " \n", + " # Print table showing the diff\n", + " from difflib import context_diff\n", + " uvar_as_text = lambda input: [pretty_ubelems_assoc(assoc) for assoc in input]\n", + " print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubelems_and_assoc), uvar_as_text(thinned_ubelems_and_assoc), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n", + "\n", + " # Iterate\n", + " return thin_ubelems_and_assoc(ctx, thinned_ubelems_and_assoc)\n", + " else:\n", + " print(\"UNSAT\\tLast constraint was the association we are looking for!\")\n", + " ctx[\"solver\"].pop()\n", + " \n", + " if ubelems_and_assoc[1:]:\n", + " print(\"\\tIterating over\")\n", + " print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubelems_assoc(assoc) for assoc in ubelems_and_assoc[1:]]))\n", + " return [*set([assoc] + thin_ubelems_and_assoc(ctx, ubelems_and_assoc[1:]))]\n", + "\n", + "\n", + "assoc_to_implement = thin_ubelems_and_assoc(solved_ctx, ubelems_and_assoc)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound_elem_0 \n" + ] + } + ], + "source": [ + "print(\"\\n\".join([pretty_ubelems_assoc(assoc) for assoc in assoc_to_implement]))" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "def thin_ubvals_and_attr(ctx: Context, ubvals_and_attr: list):\n", + " if not ubvals_and_attr:\n", + " return []\n", + "\n", + " (_, elem_v), a, (_, attr_v) = attr = ubvals_and_attr[0]\n", + " attr_rel = ctx[\"attr_rel\"](elem_v, a, attr_v)\n", + "\n", + " # Add negated constraint\n", + " ctx[\"solver\"].push()\n", + " print(f\"\\tAdd constraint Not({pretty_ubvals_attrs(attr)})\")\n", + " ctx[\"solver\"].add(Not(attr_rel))\n", + " \n", + " res = ctx[\"solver\"].check()\n", + " \n", + " if res == sat:\n", + " print(\"SAT:\\tAdding one more constraint and trying again\")\n", + " # Get new ubelems_and_assoc\n", + " model = ctx[\"solver\"].model()\n", + " thinned_ubvals_and_attr = get_ubvals_and_attr(ctx, model)\n", + " \n", + " # Print table showing the diff\n", + " from difflib import context_diff\n", + " uvar_as_text = lambda input: [pretty_ubvals_attrs(attr) for attr in input]\n", + " print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubelems_and_assoc), uvar_as_text(thinned_ubvals_and_attr), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n", + "\n", + " # Iterate\n", + " return thin_ubvals_and_attr(ctx, thinned_ubvals_and_attr)\n", + " else:\n", + " print(\"UNSAT\\tLast constraint was the attribute we are looking for!\")\n", + " ctx[\"solver\"].pop()\n", + " \n", + " if ubvals_and_attr[1:]:\n", + " print(\"\\tIterating over\")\n", + " print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubvals_attrs(attr) for attr in ubvals_and_attr[1:]]))\n", + " return [*set([attr] + thin_ubvals_and_attr(ctx, ubvals_and_attr[1:]))]\n", + "\n", + "\n", + "attrs_to_implement = thin_ubvals_and_attr(solved_ctx, ubvals_and_attr)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "print(\"\\n\".join([pretty_ubvals_attrs(attr) for attr in attrs_to_implement]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From here, we should then add this in the Intermediate Model, and then in the ECore (?) to generate the DOML file somehow.\n", + "\n", + "We can then provide the new file, or a diff to be patched onto the original?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.7 ('.venv': poetry)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/net_diagram.ipynb b/mc_openapi/notebooks/net_diagram.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..3f4ba4c94b2f72020349941dcaf747a0a703202c --- /dev/null +++ b/mc_openapi/notebooks/net_diagram.ipynb @@ -0,0 +1,239 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/andrea/Projects/piacere-model-checker\n" + ] + } + ], + "source": [ + "%cd ../.." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting diagrams\n", + " Downloading diagrams-0.23.3-py3-none-any.whl (24.4 MB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.4/24.4 MB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mm eta \u001b[36m0:00:01\u001b[0m[36m0:00:01\u001b[0m\n", + "\u001b[?25hCollecting graphviz<0.21.0,>=0.13.2 (from diagrams)\n", + " Downloading graphviz-0.20.1-py3-none-any.whl (47 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m47.0/47.0 kB\u001b[0m \u001b[31m16.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: jinja2<4.0,>=2.10 in ./.venv/lib64/python3.11/site-packages (from diagrams) (3.1.2)\n", + "Collecting typed-ast<2.0.0,>=1.5.4 (from diagrams)\n", + " Downloading typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (860 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m860.3/860.3 kB\u001b[0m \u001b[31m14.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m31m15.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib64/python3.11/site-packages (from jinja2<4.0,>=2.10->diagrams) (2.1.2)\n", + "Installing collected packages: typed-ast, graphviz, diagrams\n", + "Successfully installed diagrams-0.23.3 graphviz-0.20.1 typed-ast-1.5.5\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.1.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.2.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install diagrams" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [], + "source": [ + "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia.domlx\"\n", + "XMI_PATH = \"./tests/doml/CaseStudies/nio3_test_exec_env.domlx\"\n", + "\n", + "with open(XMI_PATH, 'rb') as f:\n", + " doml_xmi = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion\n", + "from mc_openapi.doml_mc.main import init_model\n", + "\n", + "dmc = init_model(doml_xmi, doml_ver=None)\n", + "\n", + "[x for x in dmc.intermediate_model.values() if x.user_friendly_name and x.user_friendly_name.startswith(\"co1\")]" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "from diagrams import Diagram, Cluster, Node, Edge\n", + "from diagrams.aws.compute import EC2, ECS, AutoScaling, AMI, Compute, EC2Instance, AppRunner\n", + "from diagrams.aws.network import CloudFront, APIGateway, TransitGateway\n", + "from diagrams.aws.storage import S3\n", + "from diagrams.aws.security import Shield, IAMPermissions, IdentityAndAccessManagementIamAddOn as KeyPair\n", + "from diagrams.aws.general import General\n", + "from diagrams.aws.database import DB\n", + "from diagrams.aws.mobile import APIGateway\n", + "\n", + "from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement\n", + "\n", + "elems = [elem for elem in dmc.intermediate_model.values()]\n", + "\n", + "common_elems = [e for e in elems if e.class_.startswith(\"commons_\") if e.class_ not in [\"commons_Deployment\", \"commons_Configuration\", \"commons_SProperty\", \"commons_FProperty\", \"commons_BProperty\"]] \n", + "deployments = [e for e in elems if e.class_ == \"commons_Deployment\"] \n", + "app_elems = [e for e in elems if e.class_.startswith(\"application_\") and e.class_ != \"application_ApplicationLayer\"] \n", + "infr_elems = [e for e in elems if e.class_.startswith(\"infrastructure_\") and e.class_ != \"infrastructure_InfrastructureLayer\"] \n", + "concr_elems = [e for e in elems if e.class_.startswith(\"concrete_\") and e.class_ != \"concrete_ConcreteInfrastructure\"] \n", + "\n", + "group_elems = {\"Application\": app_elems, \"Infrastructure\": infr_elems, \"Concretization\": concr_elems}\n", + "\n", + "def prettify_class_name(name: str):\n", + " _, name = name.split('_', 1)\n", + " return name\n", + "\n", + "def prettify_assoc_name(assoc: str):\n", + " _, assoc = assoc.split('::', 1)\n", + " return assoc\n", + "\n", + "def get_component(elem: DOMLElement):\n", + " \n", + " class_name = prettify_class_name(elem.class_)\n", + "\n", + " name = f\"{elem.user_friendly_name or ''}\\n({class_name})\"\n", + "\n", + " match class_name:\n", + " case \"SoftwareComponent\":\n", + " return Compute(name)\n", + " case \"SoftwareInterface\":\n", + " return APIGateway(name)\n", + " case \"DBMS\":\n", + " return DB(name)\n", + " case \"Network\":\n", + " if address := elem.attributes.get('infrastructure_Network::cidr'):\n", + " name += f'\\nCIDR: {address[0]}'\n", + " return CloudFront(name)\n", + " case \"Subnet\":\n", + " if address := elem.attributes.get('infrastructure_Network::cidr'):\n", + " name += f'\\nCIDR: {address[0]}'\n", + " return CloudFront(name)\n", + " case \"InternetGateway\":\n", + " if address := elem.attributes.get('infrastructure_InternetGateway::address'):\n", + " name += f'\\nIP: {address[0]}'\n", + " return TransitGateway(name)\n", + " case \"NetworkInterface\":\n", + " if address := elem.attributes.get('infrastructure_NetworkInterface::endPoint'):\n", + " name += f'\\nIP: {address[0]}'\n", + " return APIGateway(name)\n", + " case \"Storage\":\n", + " return S3(name)\n", + " case \"VirtualMachine\":\n", + " return EC2(name)\n", + " case \"Container\":\n", + " return ECS(name)\n", + " case \"VMImage\":\n", + " return AMI(name)\n", + " case \"AutoScalingGroup\":\n", + " return AutoScaling(name)\n", + " case \"ComputingGroup\":\n", + " return EC2Instance(name)\n", + " case \"RuntimeProvider\":\n", + " return AppRunner(name)\n", + " case \"KeyPair\":\n", + " return KeyPair(name)\n", + " case \"UserPass\":\n", + " return KeyPair(name)\n", + " case \"SecurityGroup\":\n", + " return Shield(name)\n", + " case \"Rule\":\n", + " return IAMPermissions(name)\n", + " case _:\n", + " return General(name)\n", + " \n", + "graph_attr = {\n", + " \"pad\": \"1pt\"\n", + "}\n", + "\n", + "HIGHLIGHT_CONNECTIONS = [\n", + " 'infrastructure_NetworkInterface::belongsTo'\n", + "]\n", + "\n", + "with Diagram(\"DOML Model\", show=True, outformat=\"svg\", direction=\"TB\", graph_attr=graph_attr) as diagram:\n", + " cached_nodes: dict[str, Node] = {}\n", + " for gk, gv in group_elems.items():\n", + " with Cluster(gk):\n", + " cached_nodes |= {e.id_: get_component(e) for e in gv}\n", + " \n", + " # Dont group common elements\n", + " cached_nodes |= {e.id_: get_component(e) for e in common_elems}\n", + "\n", + " for groups in group_elems.values():\n", + " for elem in groups:\n", + " for assoc_k, assocs_v in elem.associations.items():\n", + " for assoc in assocs_v:\n", + " if (start := cached_nodes.get(elem.id_)) and (end := cached_nodes.get(assoc)):\n", + " if assoc_k in HIGHLIGHT_CONNECTIONS:\n", + " start >> Edge(label=prettify_assoc_name(assoc_k), color='green', style=\"bold\") >> end\n", + " elif 'maps' in assoc_k:\n", + " start >> Edge(label=prettify_assoc_name(assoc_k), style=\"bold\") >> end\n", + " else:\n", + " start >> end\n", + "\n", + " for dep in deployments:\n", + " for _component in dep.associations.get('commons_Deployment::component'):\n", + " for _node in dep.associations.get('commons_Deployment::node'):\n", + " if (start := cached_nodes.get(_component)) and (end := cached_nodes.get(_node)):\n", + " start >> Edge(style=\"bold\") >> end\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/net_validation.ipynb b/mc_openapi/notebooks/net_validation.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..7e432991179e0387f072f7ae99e568493c701e39 --- /dev/null +++ b/mc_openapi/notebooks/net_validation.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/andrea/Projects/piacere-model-checker\n" + ] + } + ], + "source": [ + "%cd ../.." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia.domlx\"\n", + "# XMI_PATH = \"../piacere-workspace/Playground/NetValidation/test1.domlx\" # Subnets, Ifaces, Gateway\n", + "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia_IOP.domlx\" # Subnets, no Gateway\n", + "# XMI_PATH = \"../piacere-workspace/Playground/CaseStudies/nio3_test_exec_env.domlx\" # No subnets, Gateway\n", + "# XMI_PATH = \"../piacere-workspace/Playground/CaseStudies/posidonia.domlx\"\n", + "XMI_PATH = \"../piacere-workspace/Playground/3.1/Ericsson_DOML.domlx\"\n", + "\n", + "with open(XMI_PATH, 'rb') as f:\n", + " doml_xmi = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from mc_openapi.doml_mc.main import init_model\n", + "\n", + "dmc = init_model(doml_xmi, doml_ver=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "ename": "AddressValueError", + "evalue": "Expected 4 octets in 'None'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAddressValueError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m1\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=99'>100</a>\u001b[0m \u001b[39mfor\u001b[39;00m (obj, addr) \u001b[39min\u001b[39;00m addresses:\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=100'>101</a>\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNetworkInterface \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mobj\u001b[39m.\u001b[39muser_friendly_name\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m (\u001b[39m\u001b[39m{\u001b[39;00maddr\u001b[39m}\u001b[39;00m\u001b[39m) belong to net \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mnetwork\u001b[39m.\u001b[39muser_friendly_name\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m (\u001b[39m\u001b[39m{\u001b[39;00mnet_addr\u001b[39m}\u001b[39;00m\u001b[39m)? \u001b[39m\u001b[39m{\u001b[39;00maddr\u001b[39m \u001b[39m\u001b[39min\u001b[39;00m\u001b[39m \u001b[39mnet\u001b[39m.\u001b[39mhosts()\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=104'>105</a>\u001b[0m validate_network_address(dmc)\n", + "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m6\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=56'>57</a>\u001b[0m addresses: \u001b[39mlist\u001b[39m[\u001b[39mtuple\u001b[39m[DOMLElement, IPv4Address]] \u001b[39m=\u001b[39m []\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=58'>59</a>\u001b[0m \u001b[39m# Add subnets (Networks)\u001b[39;00m\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=59'>60</a>\u001b[0m visit_subnet(network, subnets)\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=61'>62</a>\u001b[0m \u001b[39m# pprint(\"SUBNETS:\")\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=62'>63</a>\u001b[0m \u001b[39m# pprint(subnets)\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=63'>64</a>\u001b[0m \n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=64'>65</a>\u001b[0m \u001b[39m# Add addresses (gateways, ifaces)\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=65'>66</a>\u001b[0m \u001b[39mfor\u001b[39;00m gateway \u001b[39min\u001b[39;00m get_assocs(network, ASSOC_GATEWAYS):\n", + "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m4\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=40'>41</a>\u001b[0m subnet \u001b[39m=\u001b[39m im[subnet]\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=41'>42</a>\u001b[0m subnet_addr \u001b[39m=\u001b[39m fix_invalid_address( get_attr(subnet, ATTR_NET_ADDRESS) )\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=42'>43</a>\u001b[0m acc\u001b[39m.\u001b[39mappend((subnet, IPv4Network(subnet_addr)))\n\u001b[1;32m <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=43'>44</a>\u001b[0m visit_subnet(subnet, acc)\n", + "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1512\u001b[0m, in \u001b[0;36mIPv4Network.__init__\u001b[0;34m(self, address, strict)\u001b[0m\n\u001b[1;32m 1476\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Instantiate a new IPv4 network object.\u001b[39;00m\n\u001b[1;32m 1477\u001b[0m \n\u001b[1;32m 1478\u001b[0m \u001b[39mArgs:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1508\u001b[0m \u001b[39m supplied.\u001b[39;00m\n\u001b[1;32m 1509\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 1510\u001b[0m addr, mask \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_split_addr_prefix(address)\n\u001b[0;32m-> 1512\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetwork_address \u001b[39m=\u001b[39m IPv4Address(addr)\n\u001b[1;32m 1513\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetmask, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_prefixlen \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_make_netmask(mask)\n\u001b[1;32m 1514\u001b[0m packed \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetwork_address)\n", + "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1315\u001b[0m, in \u001b[0;36mIPv4Address.__init__\u001b[0;34m(self, address)\u001b[0m\n\u001b[1;32m 1313\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m'\u001b[39m\u001b[39m/\u001b[39m\u001b[39m'\u001b[39m \u001b[39min\u001b[39;00m addr_str:\n\u001b[1;32m 1314\u001b[0m \u001b[39mraise\u001b[39;00m AddressValueError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mUnexpected \u001b[39m\u001b[39m'\u001b[39m\u001b[39m/\u001b[39m\u001b[39m'\u001b[39m\u001b[39m in \u001b[39m\u001b[39m{\u001b[39;00maddress\u001b[39m!r}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m-> 1315\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_ip \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_ip_int_from_string(addr_str)\n", + "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1202\u001b[0m, in \u001b[0;36m_BaseV4._ip_int_from_string\u001b[0;34m(cls, ip_str)\u001b[0m\n\u001b[1;32m 1200\u001b[0m octets \u001b[39m=\u001b[39m ip_str\u001b[39m.\u001b[39msplit(\u001b[39m'\u001b[39m\u001b[39m.\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 1201\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(octets) \u001b[39m!=\u001b[39m \u001b[39m4\u001b[39m:\n\u001b[0;32m-> 1202\u001b[0m \u001b[39mraise\u001b[39;00m AddressValueError(\u001b[39m\"\u001b[39m\u001b[39mExpected 4 octets in \u001b[39m\u001b[39m%r\u001b[39;00m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m ip_str)\n\u001b[1;32m 1204\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 1205\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mint\u001b[39m\u001b[39m.\u001b[39mfrom_bytes(\u001b[39mmap\u001b[39m(\u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_parse_octet, octets), \u001b[39m'\u001b[39m\u001b[39mbig\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[0;31mAddressValueError\u001b[0m: Expected 4 octets in 'None'" + ] + } + ], + "source": [ + "from pprint import pprint\n", + "from mc_openapi.doml_mc.intermediate_model import DOMLElement\n", + "from mc_openapi.doml_mc.mc import ModelChecker\n", + "\n", + "from ipaddress import IPv4Address, IPv4Network\n", + "\n", + "BASE_ADDR = '0.0.0.0'\n", + "\n", + "ASSOC_SUBNETS = 'infrastructure_Network::subnets'\n", + "ASSOC_GATEWAYS = 'infrastructure_Network::gateways'\n", + "ASSOC_IFACE_NET = 'infrastructure_NetworkInterface::belongsTo'\n", + "\n", + "ATTR_NET_ADDRESS = 'infrastructure_Network::cidr' # not here anymore\n", + "ATTR_GATEWAY_ADDRESS = 'infrastructure_InternetGateway::address'\n", + "ATTR_IFACE_ADDRESS = 'infrastructure_NetworkInterface::endPoint'\n", + "\n", + "def get_attr(elem: DOMLElement, attr_id: str):\n", + " if elem := elem.attributes.get(attr_id):\n", + " return elem[0]\n", + " return None\n", + " \n", + "def get_assocs(elem: DOMLElement, assoc_id: str):\n", + " return elem.associations.get(assoc_id, [])\n", + "\n", + "def validate_network_address(dmc: ModelChecker):\n", + " im = dmc.intermediate_model\n", + "\n", + " networks = [e for e in im.values() if e.class_ == 'infrastructure_Network']\n", + " ifaces = [e for e in im.values() if e.class_ == 'infrastructure_NetworkInterface']\n", + " subnets = [e for e in im.values() if e.class_ == 'infrastructure_Subnet']\n", + "\n", + "# Network/24\n", + "# Subnet/28\n", + "# Subnet/30\n", + "# Address\n", + "# Address\n", + "\n", + " def visit_subnet(net: DOMLElement, acc: list):\n", + " \"\"\"Recursively navigate subnets to populate the `acc` list with all the subnet in a network.\"\"\"\n", + " for subnet in get_assocs(net, ASSOC_SUBNETS):\n", + " subnet = im[subnet]\n", + " subnet_addr = fix_invalid_address( get_attr(subnet, ATTR_NET_ADDRESS) )\n", + " acc.append((subnet, IPv4Network(subnet_addr)))\n", + " visit_subnet(subnet, acc)\n", + "\n", + " def fix_invalid_address(address: any):\n", + " if isinstance(address, str) and address.startswith('/'):\n", + " return f\"{BASE_ADDR}{address}\"\n", + "\n", + " return address\n", + "\n", + "\n", + " for network in networks:\n", + " # Tuple(elem, cidr)\n", + " subnets: list[tuple[DOMLElement, IPv4Network]] = []\n", + " # Tuple(elem, address)\n", + " addresses: list[tuple[DOMLElement, IPv4Address]] = []\n", + "\n", + " # Add subnets (Networks)\n", + " visit_subnet(network, subnets)\n", + "\n", + " # pprint(\"SUBNETS:\")\n", + " # pprint(subnets)\n", + "\n", + " # Add addresses (gateways, ifaces)\n", + " for gateway in get_assocs(network, ASSOC_GATEWAYS):\n", + " gateway = im[gateway]\n", + " if gateway_address := get_attr(gateway, ATTR_GATEWAY_ADDRESS):\n", + " addresses.append((gateway, IPv4Address(gateway_address)))\n", + "\n", + " for iface in ifaces:\n", + " if owner_id := get_assocs(iface, ASSOC_IFACE_NET):\n", + " owner = im[list(owner_id)[0]]\n", + " if owner.id_ in [s.id_ for (s, _) in subnets] + [network.id_]:\n", + " if ((iface_address := get_attr(iface, ATTR_IFACE_ADDRESS))\n", + " and (owner_address := get_attr(owner, ATTR_NET_ADDRESS))):\n", + " owner_address = fix_invalid_address(owner_address)\n", + " iface_address = IPv4Address(iface_address)\n", + " owner_address = IPv4Network(owner_address)\n", + " print(f\"{iface.user_friendly_name} ({iface_address}) belongs to {owner.user_friendly_name} ({owner_address})? {iface_address in owner_address.hosts()}\")\n", + "\n", + " addresses.append((iface, iface_address))\n", + " else:\n", + " print(f\"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'.\")\n", + "\n", + " # Validate Network and Subnets\n", + " net_addr = fix_invalid_address( get_attr(network, ATTR_NET_ADDRESS) )\n", + " # prepend 0.0.0.0 if starts with / i guess, print a warning\n", + " print(f\"{net_addr}\\t{network.user_friendly_name}\")\n", + "\n", + " net = IPv4Network(net_addr)\n", + "\n", + " if len(subnets) > 0:\n", + " for (obj, sn) in subnets:\n", + " print(f\"{sn}\\t{obj.user_friendly_name} belongs? {sn.subnet_of(net)}\")\n", + " else:\n", + " print(\"No subnets!\")\n", + "\n", + " # Validate addresses (again)\n", + " for (obj, addr) in addresses:\n", + " print(f\"NetworkInterface '{obj.user_friendly_name}' ({addr}) belong to net '{network.user_friendly_name}' ({net_addr})? {addr in net.hosts()}\")\n", + "\n", + " \n", + "\n", + "validate_network_address(dmc)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/notebooks/stats.ipynb b/mc_openapi/notebooks/stats.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..08318bbb50f864e2df5ce8456edd537b4b5e89ae --- /dev/null +++ b/mc_openapi/notebooks/stats.ipynb @@ -0,0 +1,297 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 246, + "metadata": {}, + "outputs": [], + "source": [ + "PROJ_PATH = '/home/andrea/Projects/piacere-model-checker'\n", + "TESTS_PATH = PROJ_PATH + '/tests/doml/CaseStudies/*.domlx'" + ] + }, + { + "cell_type": "code", + "execution_count": 247, + "metadata": {}, + "outputs": [], + "source": [ + "from glob import glob" + ] + }, + { + "cell_type": "code", + "execution_count": 248, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx',\n", + " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/nio3_test_exec_env.domlx',\n", + " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/posidonia.domlx',\n", + " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/posidonia_IOP.domlx',\n", + " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/uc3-openstack_v2.domlx']" + ] + }, + "execution_count": 248, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "domlx_files = glob(TESTS_PATH)\n", + "\n", + "domlx_files" + ] + }, + { + "cell_type": "code", + "execution_count": 249, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/andrea/Projects/piacere-model-checker\n", + "Using DOML v2.2.1\n", + "[RESULT]\n", + "unsat\n", + "[ERRORS]\n", + "\u001b[91m[Built-in]\n", + "Software component 'nio3_git' is not deployed to any abstract infrastructure node.\u001b[00m\n", + "[STATS]\n", + "memory,conflicts,quant instantiations\n", + "40.38,1273,1253\n", + "\n", + "\n", + "Using DOML v2.2.1\n", + "[RESULT]\n", + "sat\n", + "[STATS]\n", + "memory,conflicts,quant instantiations\n", + "43.29,2592,2614\n", + "\n", + "\n", + "Using DOML v2.2.1\n", + "[RESULT]\n", + "unsat\n", + "[ERRORS]\n", + "\u001b[91m[Built-in]\n", + "Virtual machine gestaut_vm is connected to no network interface.\n", + "Software components 'Database' and 'Gestaut' are supposed to communicate through interface 'dbAccess', but they are deployed to nodes that cannot communicate through a common network.\n", + "Abstract infrastructure element 'gestaut_vm' has not been mapped to any element in the active concretization.\n", + "Security group 'sg' is not associated with any network interface.\u001b[00m\n", + "[STATS]\n", + "memory,conflicts,quant instantiations\n", + "91.13,1875,2794\n", + "\n", + "\n", + "Using DOML v2.2.1\n", + "[RESULT]\n", + "unsat\n", + "[ERRORS]\n", + "\u001b[91m[Built-in]\n", + "Virtual machine gestaut_vm is connected to no network interface.\n", + "Software components 'Database' and 'Gestaut' are supposed to communicate through interface 'dbAccess', but they are deployed to nodes that cannot communicate through a common network.\n", + "Abstract infrastructure element 'gestaut_vm' has not been mapped to any element in the active concretization.\n", + "Security group 'sg' is not associated with any network interface.\u001b[00m\n", + "[STATS]\n", + "memory,conflicts,quant instantiations\n", + "91.45,1417,2263\n", + "\n", + "\n", + "Using DOML v2.2.1\n", + "[RESULT]\n", + "unsat\n", + "[ERRORS]\n", + "\u001b[91m[Built-in]\n", + "Security group 'sg' is not associated with any network interface.\u001b[00m\n", + "[STATS]\n", + "memory,conflicts,quant instantiations\n", + "91.29,7649,8422\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>filename</th>\n", + " <th>time</th>\n", + " <th>doml_ver</th>\n", + " <th>result</th>\n", + " <th>#error</th>\n", + " <th>memory</th>\n", + " <th>conflicts</th>\n", + " <th>quant inst</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>SIMPA_Validation_v2.domlx</td>\n", + " <td>1.344904</td>\n", + " <td>2.2.1</td>\n", + " <td>unsat</td>\n", + " <td>3</td>\n", + " <td>40.38</td>\n", + " <td>1273</td>\n", + " <td>1253</td>\n", + " </tr>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>nio3_test_exec_env.domlx</td>\n", + " <td>1.602703</td>\n", + " <td>2.2.1</td>\n", + " <td></td>\n", + " <td>2</td>\n", + " <td>43.29</td>\n", + " <td>2592</td>\n", + " <td>2614</td>\n", + " </tr>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>posidonia.domlx</td>\n", + " <td>16.781076</td>\n", + " <td>2.2.1</td>\n", + " <td>unsat</td>\n", + " <td>6</td>\n", + " <td>91.13</td>\n", + " <td>1875</td>\n", + " <td>2794</td>\n", + " </tr>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>posidonia_IOP.domlx</td>\n", + " <td>16.956536</td>\n", + " <td>2.2.1</td>\n", + " <td>unsat</td>\n", + " <td>6</td>\n", + " <td>91.45</td>\n", + " <td>1417</td>\n", + " <td>2263</td>\n", + " </tr>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>uc3-openstack_v2.domlx</td>\n", + " <td>10.553367</td>\n", + " <td>2.2.1</td>\n", + " <td>unsat</td>\n", + " <td>3</td>\n", + " <td>91.29</td>\n", + " <td>7649</td>\n", + " <td>8422</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " filename time doml_ver result #error memory \\\n", + "0 SIMPA_Validation_v2.domlx 1.344904 2.2.1 unsat 3 40.38 \n", + "0 nio3_test_exec_env.domlx 1.602703 2.2.1 2 43.29 \n", + "0 posidonia.domlx 16.781076 2.2.1 unsat 6 91.13 \n", + "0 posidonia_IOP.domlx 16.956536 2.2.1 unsat 6 91.45 \n", + "0 uc3-openstack_v2.domlx 10.553367 2.2.1 unsat 3 91.29 \n", + "\n", + " conflicts quant inst \n", + "0 1273 1253 \n", + "0 2592 2614 \n", + "0 1875 2794 \n", + "0 1417 2263 \n", + "0 7649 8422 " + ] + }, + "execution_count": 249, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import subprocess\n", + "import os\n", + "from time import time\n", + "import pandas as pd\n", + "\n", + "os.chdir(PROJ_PATH)\n", + "\n", + "print(os.getcwd())\n", + "\n", + "test_cmd = lambda file: f\"python -m mc_openapi -z -d {file}\"\n", + "\n", + "df = pd.DataFrame(columns=['filename', 'time', 'doml_ver', 'result', '#error', 'memory', 'conflicts', 'quant inst'])\n", + "\n", + "for file in domlx_files:\n", + "\n", + " filename = file.split(\"/\")[-1]\n", + "\n", + " # I know that using time is inaccurate, but it's simple and it works for generating simple benchmarks\n", + " start_time = time()\n", + " out = subprocess.run(test_cmd(file), shell=True, capture_output=True)\n", + " run_time = time() - start_time\n", + "\n", + " r = out.stdout.decode('utf-8')\n", + "\n", + " print(r)\n", + "\n", + " doml_ver, _, r = r.rpartition(\"[RESULT]\")\n", + " result, _, r = r.rpartition(\"[ERRORS]\")\n", + " errors, _, stats = r.rpartition(\"[STATS]\")\n", + " _, _, doml_ver = doml_ver.rpartition(\"v\")\n", + "\n", + " doml_ver = doml_ver.replace(\"\\n\", \"\")\n", + " result = result.replace(\"\\n\", \"\")\n", + " error_num = len(errors.split(\"\\n\")) - 1\n", + " stats = stats.split(\"\\n\")[2].split(\",\")[-3:]\n", + "\n", + " df2 = pd.DataFrame([[filename, run_time, doml_ver, result, error_num, *stats]], columns=df.columns)\n", + "\n", + " df = pd.concat([df, df2])\n", + "\n", + "df" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mc_openapi/doml_mc/test.ipynb b/mc_openapi/notebooks/test.ipynb similarity index 62% rename from mc_openapi/doml_mc/test.ipynb rename to mc_openapi/notebooks/test.ipynb index 8f66fd800269e476de78ff06491f3044e3bfca38..c94c86e4f20176442a329ef00ad45ef6d54d6de9 100644 --- a/mc_openapi/doml_mc/test.ipynb +++ b/mc_openapi/notebooks/test.ipynb @@ -8,13 +8,13 @@ "source": [ "import mc_openapi.doml_mc as mc\n", "\n", - "doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n", - "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n", - "# doml_document_path = \"../../tests/doml/faas.domlx\"\n", + "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n", + "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n", + "# doml_document_path = \"../../tests/doml/v2.0/faas.domlx\"\n", "with open(doml_document_path, \"rb\") as xmif:\n", " doc = xmif.read()\n", "\n", - "dmc = mc.ModelChecker(doc)" + "dmc = mc.ModelChecker(doc, mc.DOMLVersion.V2_0)" ] }, { @@ -23,14 +23,14 @@ "metadata": {}, "outputs": [], "source": [ - "r = dmc.check_common_requirements(2, False, 50)\n", + "r = dmc.check_requirements(2, False, 50)\n", "r.summarize()" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')", + "display_name": "Python 3.11.0 ('.venv': poetry)", "language": "python", "name": "python3" }, @@ -44,12 +44,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.11.0" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed" + "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16" } } }, diff --git a/mc_openapi/openapi/model_checker.yaml b/mc_openapi/openapi/model_checker.yaml deleted file mode 100644 index b1875dd5fcab22615fd7d6bb63595aa38d96ae98..0000000000000000000000000000000000000000 --- a/mc_openapi/openapi/model_checker.yaml +++ /dev/null @@ -1,73 +0,0 @@ -openapi: 3.0.2 -info: - license: - name: Apache-2.0 - title: PIACERE Model Checker - version: "1.0" -paths: - /modelcheck: - post: - description: Send a DOML model in XMI format and a requirement to check. - The response says whether the requirement is satisfied by the model, - with a description of the issue if it is not. - operationId: mc_openapi.handlers.post - requestBody: - content: - application/xml: - schema: - type: string - required: true - parameters: - - in: query - name: requirement - required: false - schema: - type: string - description: Requirement to be verified (optional) - responses: - "200": - content: - application/json: - schema: - type: object - properties: - result: - type: string - enum: - - sat - - unsat - - dontknow - description: - type: string - required: - - result - description: OK - model checking succeded - "400": - content: - application/json: - schema: - $ref: '#/components/schemas/error' - description: malformed request - "500": - content: - application/json: - schema: - $ref: '#/components/schemas/error' - description: internal error -components: - schemas: - error: - type: object - properties: - timestamp: - type: string - format: date-time - message: - type: string - description: Error message for the user - debug_message: - type: string - description: Detailed error message for debugging purposes - required: - - timestamp - - message diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index f8c1a69aea59cc944a26952524db9517d5389592..0000000000000000000000000000000000000000 --- a/poetry.lock +++ /dev/null @@ -1,1433 +0,0 @@ -[[package]] -name = "appnope" -version = "0.1.3" -description = "Disable App Nap on macOS >= 10.9" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "asttokens" -version = "2.0.5" -description = "Annotate AST trees with source code positions" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -six = "*" - -[package.extras] -test = ["astroid", "pytest"] - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "attrs" -version = "22.1.0" -description = "Classes Without Boilerplate" -category = "main" -optional = false -python-versions = ">=3.5" - -[package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] - -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "certifi" -version = "2022.6.15" -description = "Python package for providing Mozilla's CA Bundle." -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "cffi" -version = "1.15.1" -description = "Foreign Function Interface for Python calling C code." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "2.1.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" -optional = false -python-versions = ">=3.6.0" - -[package.extras] -unicode_backport = ["unicodedata2"] - -[[package]] -name = "click" -version = "8.1.3" -description = "Composable command line interface toolkit" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "clickclick" -version = "20.10.2" -description = "Click utility functions" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -click = ">=4.0" -PyYAML = ">=3.11" - -[[package]] -name = "colorama" -version = "0.4.5" -description = "Cross-platform colored terminal text." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "colorful" -version = "0.5.4" -description = "Terminal string styling done right, in Python." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "connexion" -version = "2.14.0" -description = "Connexion - API first applications with OpenAPI/Swagger and Flask" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -clickclick = ">=1.2,<21" -flask = ">=1.0.4,<3" -inflection = ">=0.3.1,<0.6" -itsdangerous = ">=0.24" -jsonschema = ">=2.5.1,<5" -packaging = ">=20" -PyYAML = ">=5.1,<7" -requests = ">=2.9.1,<3" -swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""} -werkzeug = ">=1.0,<3" - -[package.extras] -aiohttp = ["aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "MarkupSafe (>=0.23)"] -docs = ["sphinx-autoapi (==1.8.1)"] -flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"] -swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] -tests = ["decorator (>=5,<6)", "pytest (>=6,<7)", "pytest-cov (>=2,<3)", "testfixtures (>=6,<7)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "swagger-ui-bundle (>=0.0.2,<0.1)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "MarkupSafe (>=0.23)", "pytest-aiohttp", "aiohttp-remotes"] - -[[package]] -name = "debugpy" -version = "1.6.2" -description = "An implementation of the Debug Adapter Protocol for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -category = "dev" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "entrypoints" -version = "0.4" -description = "Discover and load entry points from installed packages." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "executing" -version = "0.9.1" -description = "Get the currently executing AST node of a frame, and other information" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "flask" -version = "2.1.3" -description = "A simple framework for building complex web applications." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -click = ">=8.0" -importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} -itsdangerous = ">=2.0" -Jinja2 = ">=3.0" -Werkzeug = ">=2.0" - -[package.extras] -async = ["asgiref (>=3.2)"] -dotenv = ["python-dotenv"] - -[[package]] -name = "future-fstrings" -version = "1.2.0" -description = "A backport of fstrings to python<3.6" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -rewrite = ["tokenize-rt (>=3)"] - -[[package]] -name = "idna" -version = "3.3" -description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "importlib-metadata" -version = "4.12.0" -description = "Read metadata from Python packages" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] -perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] - -[[package]] -name = "inflection" -version = "0.5.1" -description = "A port of Ruby on Rails inflector to Python" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "ipykernel" -version = "6.15.1" -description = "IPython Kernel for Jupyter" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -debugpy = ">=1.0" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=17" -tornado = ">=6.1" -traitlets = ">=5.1.0" - -[package.extras] -test = ["flaky", "ipyparallel", "pre-commit", "pytest-cov", "pytest-timeout", "pytest (>=6.0)"] - -[[package]] -name = "ipython" -version = "8.4.0" -description = "IPython: Productive Interactive Computing" -category = "dev" -optional = false -python-versions = ">=3.8" - -[package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5" - -[package.extras] -all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"] -black = ["black"] -doc = ["Sphinx (>=1.3)"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"] - -[[package]] -name = "itsdangerous" -version = "2.1.2" -description = "Safely pass data to untrusted environments and back." -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "jedi" -version = "0.18.1" -description = "An autocompletion tool for Python that can be used for text editors." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -parso = ">=0.8.0,<0.9.0" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "jinja2" -version = "3.1.2" -description = "A very fast and expressive template engine." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "joblib" -version = "1.1.0" -description = "Lightweight pipelining with Python functions" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "jsonschema" -version = "4.8.0" -description = "An implementation of JSON Schema validation for Python" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jupyter-client" -version = "7.3.4" -description = "Jupyter protocol implementation and client libraries" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -entrypoints = "*" -jupyter-core = ">=4.9.2" -nest-asyncio = ">=1.5.4" -python-dateutil = ">=2.8.2" -pyzmq = ">=23.0" -tornado = ">=6.0" -traitlets = "*" - -[package.extras] -doc = ["ipykernel", "myst-parser", "sphinx-rtd-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt"] -test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "jupyter-core" -version = "4.11.1" -description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = "*" - -[package.extras] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "lxml" -version = "4.9.1" -description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" - -[package.extras] -cssselect = ["cssselect (>=0.7)"] -html5 = ["html5lib"] -htmlsoup = ["beautifulsoup4"] -source = ["Cython (>=0.29.7)"] - -[[package]] -name = "markupsafe" -version = "2.1.1" -description = "Safely add untrusted strings to HTML/XML markup." -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "matplotlib-inline" -version = "0.1.3" -description = "Inline Matplotlib backend for Jupyter" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "nest-asyncio" -version = "1.5.5" -description = "Patch asyncio to allow nested event loops" -category = "dev" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "networkx" -version = "2.8.5" -description = "Python package for creating and manipulating graphs and networks" -category = "main" -optional = false -python-versions = ">=3.8" - -[package.extras] -default = ["numpy (>=1.19)", "scipy (>=1.8)", "matplotlib (>=3.4)", "pandas (>=1.3)"] -developer = ["pre-commit (>=2.19)", "mypy (>=0.960)"] -doc = ["sphinx (>=5)", "pydata-sphinx-theme (>=0.9)", "sphinx-gallery (>=0.10)", "numpydoc (>=1.4)", "pillow (>=9.1)", "nb2plots (>=0.6)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.6)", "pygraphviz (>=1.9)", "pydot (>=1.4.2)", "sympy (>=1.10)"] -test = ["pytest (>=7.1)", "pytest-cov (>=3.0)", "codecov (>=2.1)"] - -[[package]] -name = "ordered-set" -version = "4.1.0" -description = "An OrderedSet is a custom MutableSet that remembers its order, so that every" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -dev = ["pytest", "black", "mypy"] - -[[package]] -name = "packaging" -version = "21.3" -description = "Core utilities for Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pluggy" -version = "1.0.0" -description = "plugin and hook calling mechanisms for python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "prettyprinter" -version = "0.18.0" -description = "Syntax-highlighting, declarative and composable pretty printer for Python 3.5+" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -colorful = ">=0.4.0" -Pygments = ">=2.2.0" - -[[package]] -name = "prompt-toolkit" -version = "3.0.30" -description = "Library for building powerful interactive command lines in Python" -category = "dev" -optional = false -python-versions = ">=3.6.2" - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "5.9.1" -description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -test = ["ipaddress", "mock", "enum34", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -category = "dev" -optional = false -python-versions = "*" - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pyecore" -version = "0.12.2" -description = "A Python(ic) Implementation of the Eclipse Modeling Framework (EMF/Ecore)" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -future-fstrings = "*" -lxml = "*" -ordered-set = ">=4.0.1" -restrictedpython = ">=4.0b6" - -[[package]] -name = "pygments" -version = "2.12.0" -description = "Pygments is a syntax highlighting package written in Python." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" -optional = false -python-versions = ">=3.6.8" - -[package.extras] -diagrams = ["railroad-diagrams", "jinja2"] - -[[package]] -name = "pyrsistent" -version = "0.18.1" -description = "Persistent/Functional/Immutable data structures" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pywin32" -version = "304" -description = "Python for Window Extensions" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyzmq" -version = "23.2.0" -description = "Python bindings for 0MQ" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} -py = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "requests" -version = "2.28.1" -description = "Python HTTP for Humans." -category = "main" -optional = false -python-versions = ">=3.7, <4" - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "restrictedpython" -version = "5.0" -description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment." -category = "main" -optional = false -python-versions = "*" - -[package.extras] -test = ["pytest", "pytest-mock"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "stack-data" -version = "0.3.0" -description = "Extract data from python stack frames and tracebacks for informative displays" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -asttokens = "*" -executing = "*" -pure-eval = "*" - -[package.extras] -tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"] - -[[package]] -name = "swagger-ui-bundle" -version = "0.0.9" -description = "swagger_ui_bundle - swagger-ui files in a pip package" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -Jinja2 = ">=2.0" - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tornado" -version = "6.2" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "dev" -optional = false -python-versions = ">= 3.7" - -[[package]] -name = "traitlets" -version = "5.3.0" -description = "" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pre-commit", "pytest"] - -[[package]] -name = "urllib3" -version = "1.26.11" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" - -[package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "uwsgi" -version = "2.0.20" -description = "The uWSGI server" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "wcwidth" -version = "0.2.5" -description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "werkzeug" -version = "2.2.1" -description = "The comprehensive WSGI web application library." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog"] - -[[package]] -name = "z3-solver" -version = "4.10.2.0" -description = "an efficient SMT solver library" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "zipp" -version = "3.8.1" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] - -[metadata] -lock-version = "1.1" -python-versions = "^3.9" -content-hash = "a3bdfb031327e5a6361afc9fb3c81b3e132d8d8babe46c26aa671dedfe4ba70b" - -[metadata.files] -appnope = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] -asttokens = [ - {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, - {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, -] -atomicwrites = [] -attrs = [] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -certifi = [ - {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, - {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, -] -cffi = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, - {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -clickclick = [ - {file = "clickclick-20.10.2-py2.py3-none-any.whl", hash = "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5"}, - {file = "clickclick-20.10.2.tar.gz", hash = "sha256:4efb13e62353e34c5eef7ed6582c4920b418d7dedc86d819e22ee089ba01802c"}, -] -colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, -] -colorful = [ - {file = "colorful-0.5.4-py2.py3-none-any.whl", hash = "sha256:8d264b52a39aae4c0ba3e2a46afbaec81b0559a99be0d2cfe2aba4cf94531348"}, - {file = "colorful-0.5.4.tar.gz", hash = "sha256:86848ad4e2eda60cd2519d8698945d22f6f6551e23e95f3f14dfbb60997807ea"}, -] -connexion = [ - {file = "connexion-2.14.0-py2.py3-none-any.whl", hash = "sha256:4e50c1b0b6d287e20830d053c8de09a73bead5ac0760200ade074364c7362ab6"}, - {file = "connexion-2.14.0.tar.gz", hash = "sha256:ed6f9c97ca5281257935c5530570b2a2394a689ece1b171c18d855cf751adbb4"}, -] -debugpy = [] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -entrypoints = [ - {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, - {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, -] -executing = [] -flask = [] -future-fstrings = [ - {file = "future_fstrings-1.2.0-py2.py3-none-any.whl", hash = "sha256:90e49598b553d8746c4dc7d9442e0359d038c3039d802c91c0a55505da318c63"}, - {file = "future_fstrings-1.2.0.tar.gz", hash = "sha256:6cf41cbe97c398ab5a81168ce0dbb8ad95862d3caf23c21e4430627b90844089"}, -] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"}, - {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"}, -] -inflection = [ - {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, - {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -ipykernel = [] -ipython = [ - {file = "ipython-8.4.0-py3-none-any.whl", hash = "sha256:7ca74052a38fa25fe9bedf52da0be7d3fdd2fb027c3b778ea78dfe8c212937d1"}, - {file = "ipython-8.4.0.tar.gz", hash = "sha256:f2db3a10254241d9b447232cec8b424847f338d9d36f9a577a6192c332a46abd"}, -] -itsdangerous = [ - {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, - {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, -] -jedi = [ - {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, - {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, -] -jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] -joblib = [] -jsonschema = [] -jupyter-client = [ - {file = "jupyter_client-7.3.4-py3-none-any.whl", hash = "sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621"}, - {file = "jupyter_client-7.3.4.tar.gz", hash = "sha256:aa9a6c32054b290374f95f73bb0cae91455c58dfb84f65c8591912b8f65e6d56"}, -] -jupyter-core = [] -lxml = [ - {file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"}, - {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"}, - {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc"}, - {file = "lxml-4.9.1-cp27-cp27m-win32.whl", hash = "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3"}, - {file = "lxml-4.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627"}, - {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84"}, - {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837"}, - {file = "lxml-4.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad"}, - {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5"}, - {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8"}, - {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8"}, - {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d"}, - {file = "lxml-4.9.1-cp310-cp310-win32.whl", hash = "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7"}, - {file = "lxml-4.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b"}, - {file = "lxml-4.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d"}, - {file = "lxml-4.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3"}, - {file = "lxml-4.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29"}, - {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d"}, - {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318"}, - {file = "lxml-4.9.1-cp35-cp35m-win32.whl", hash = "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7"}, - {file = "lxml-4.9.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4"}, - {file = "lxml-4.9.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb"}, - {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067"}, - {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536"}, - {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8"}, - {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b"}, - {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf"}, - {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3"}, - {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391"}, - {file = "lxml-4.9.1-cp36-cp36m-win32.whl", hash = "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e"}, - {file = "lxml-4.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7"}, - {file = "lxml-4.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2"}, - {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc"}, - {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c"}, - {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4"}, - {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3"}, - {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca"}, - {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785"}, - {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785"}, - {file = "lxml-4.9.1-cp37-cp37m-win32.whl", hash = "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a"}, - {file = "lxml-4.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e"}, - {file = "lxml-4.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b"}, - {file = "lxml-4.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97"}, - {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21"}, - {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2"}, - {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130"}, - {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715"}, - {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036"}, - {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387"}, - {file = "lxml-4.9.1-cp38-cp38-win32.whl", hash = "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94"}, - {file = "lxml-4.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345"}, - {file = "lxml-4.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67"}, - {file = "lxml-4.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb"}, - {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448"}, - {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7"}, - {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91"}, - {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000"}, - {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25"}, - {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd"}, - {file = "lxml-4.9.1-cp39-cp39-win32.whl", hash = "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb"}, - {file = "lxml-4.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d"}, - {file = "lxml-4.9.1-pp37-pypy37_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c"}, - {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b"}, - {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc"}, - {file = "lxml-4.9.1-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b"}, - {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2"}, - {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73"}, - {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c"}, - {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"}, - {file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"}, -] -markupsafe = [ - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, - {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, - {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, - {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, - {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, - {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, -] -matplotlib-inline = [ - {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, - {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, -] -nest-asyncio = [ - {file = "nest_asyncio-1.5.5-py3-none-any.whl", hash = "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2"}, - {file = "nest_asyncio-1.5.5.tar.gz", hash = "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"}, -] -networkx = [] -ordered-set = [ - {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"}, - {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -parso = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] -pexpect = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] -pickleshare = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -prettyprinter = [ - {file = "prettyprinter-0.18.0-py2.py3-none-any.whl", hash = "sha256:358a58f276cb312e3ca29d7a7f244c91e4e0bda7848249d30e4f36d2eb58b67c"}, - {file = "prettyprinter-0.18.0.tar.gz", hash = "sha256:9fe5da7ec53510881dd35d7a5c677ba45f34cfe6a8e78d1abd20652cf82139a8"}, -] -prompt-toolkit = [ - {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"}, - {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"}, -] -psutil = [ - {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87"}, - {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af"}, - {file = "psutil-5.9.1-cp27-cp27m-win32.whl", hash = "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc"}, - {file = "psutil-5.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2"}, - {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0"}, - {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22"}, - {file = "psutil-5.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9"}, - {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8"}, - {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de"}, - {file = "psutil-5.9.1-cp310-cp310-win32.whl", hash = "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329"}, - {file = "psutil-5.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021"}, - {file = "psutil-5.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237"}, - {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453"}, - {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685"}, - {file = "psutil-5.9.1-cp36-cp36m-win32.whl", hash = "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36"}, - {file = "psutil-5.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d"}, - {file = "psutil-5.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc"}, - {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676"}, - {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4"}, - {file = "psutil-5.9.1-cp37-cp37m-win32.whl", hash = "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b"}, - {file = "psutil-5.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680"}, - {file = "psutil-5.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1"}, - {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4"}, - {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b"}, - {file = "psutil-5.9.1-cp38-cp38-win32.whl", hash = "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689"}, - {file = "psutil-5.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0"}, - {file = "psutil-5.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81"}, - {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e"}, - {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537"}, - {file = "psutil-5.9.1-cp39-cp39-win32.whl", hash = "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574"}, - {file = "psutil-5.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5"}, - {file = "psutil-5.9.1.tar.gz", hash = "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954"}, -] -ptyprocess = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] -pure-eval = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pycparser = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] -pyecore = [ - {file = "pyecore-0.12.2-py3-none-any.whl", hash = "sha256:8ebbefea2fcb97602ddb9eb859ae15d7c0900231128da92e10b7f9a9e1a29b76"}, - {file = "pyecore-0.12.2.tar.gz", hash = "sha256:4fb417df37fc5433da37f3d42724f7c4cc36cbbe63988f3e43ad7653e0808387"}, -] -pygments = [ - {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, - {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, -] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] -pyrsistent = [ - {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, - {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, - {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, - {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, -] -pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] -pywin32 = [ - {file = "pywin32-304-cp310-cp310-win32.whl", hash = "sha256:3c7bacf5e24298c86314f03fa20e16558a4e4138fc34615d7de4070c23e65af3"}, - {file = "pywin32-304-cp310-cp310-win_amd64.whl", hash = "sha256:4f32145913a2447736dad62495199a8e280a77a0ca662daa2332acf849f0be48"}, - {file = "pywin32-304-cp310-cp310-win_arm64.whl", hash = "sha256:d3ee45adff48e0551d1aa60d2ec066fec006083b791f5c3527c40cd8aefac71f"}, - {file = "pywin32-304-cp311-cp311-win32.whl", hash = "sha256:30c53d6ce44c12a316a06c153ea74152d3b1342610f1b99d40ba2795e5af0269"}, - {file = "pywin32-304-cp311-cp311-win_amd64.whl", hash = "sha256:7ffa0c0fa4ae4077e8b8aa73800540ef8c24530057768c3ac57c609f99a14fd4"}, - {file = "pywin32-304-cp311-cp311-win_arm64.whl", hash = "sha256:cbbe34dad39bdbaa2889a424d28752f1b4971939b14b1bb48cbf0182a3bcfc43"}, - {file = "pywin32-304-cp36-cp36m-win32.whl", hash = "sha256:be253e7b14bc601718f014d2832e4c18a5b023cbe72db826da63df76b77507a1"}, - {file = "pywin32-304-cp36-cp36m-win_amd64.whl", hash = "sha256:de9827c23321dcf43d2f288f09f3b6d772fee11e809015bdae9e69fe13213988"}, - {file = "pywin32-304-cp37-cp37m-win32.whl", hash = "sha256:f64c0377cf01b61bd5e76c25e1480ca8ab3b73f0c4add50538d332afdf8f69c5"}, - {file = "pywin32-304-cp37-cp37m-win_amd64.whl", hash = "sha256:bb2ea2aa81e96eee6a6b79d87e1d1648d3f8b87f9a64499e0b92b30d141e76df"}, - {file = "pywin32-304-cp38-cp38-win32.whl", hash = "sha256:94037b5259701988954931333aafd39cf897e990852115656b014ce72e052e96"}, - {file = "pywin32-304-cp38-cp38-win_amd64.whl", hash = "sha256:ead865a2e179b30fb717831f73cf4373401fc62fbc3455a0889a7ddac848f83e"}, - {file = "pywin32-304-cp39-cp39-win32.whl", hash = "sha256:25746d841201fd9f96b648a248f731c1dec851c9a08b8e33da8b56148e4c65cc"}, - {file = "pywin32-304-cp39-cp39-win_amd64.whl", hash = "sha256:d24a3382f013b21aa24a5cfbfad5a2cd9926610c0affde3e8ab5b3d7dbcf4ac9"}, -] -pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] -pyzmq = [ - {file = "pyzmq-23.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:22ac0243a41798e3eb5d5714b28c2f28e3d10792dffbc8a5fca092f975fdeceb"}, - {file = "pyzmq-23.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f685003d836ad0e5d4f08d1e024ee3ac7816eb2f873b2266306eef858f058133"}, - {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d4651de7316ec8560afe430fb042c0782ed8ac54c0be43a515944d7c78fddac8"}, - {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bcc6953e47bcfc9028ddf9ab2a321a3c51d7cc969db65edec092019bb837959f"}, - {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e08671dc202a1880fa522f921f35ca5925ba30da8bc96228d74a8f0643ead9c"}, - {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de727ea906033b30527b4a99498f19aca3f4d1073230a958679a5b726e2784e0"}, - {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5aa9da520e4bb8cee8189f2f541701405e7690745094ded7a37b425d60527ea"}, - {file = "pyzmq-23.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f3ff6abde52e702397949054cb5b06c1c75b5d6542f6a2ce029e46f71ffbbbf2"}, - {file = "pyzmq-23.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e2e2db5c6ef376e97c912733dfc24406f5949474d03e800d5f07b6aca4d870af"}, - {file = "pyzmq-23.2.0-cp310-cp310-win32.whl", hash = "sha256:e669913cb2179507628419ec4f0e453e48ce6f924de5884d396f18c31836089c"}, - {file = "pyzmq-23.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a3dc339f7bc185d5fd0fd976242a5baf35de404d467e056484def8a4dd95868b"}, - {file = "pyzmq-23.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:30c365e60c39c53f8eea042b37ea28304ffa6558fb7241cf278745095a5757da"}, - {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c2d8b69a2bf239ae3d987537bf3fbc2b044a405394cf4c258fc684971dd48b2"}, - {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:602835e5672ca9ca1d78e6c148fb28c4f91b748ebc41fbd2f479d8763d58bc9b"}, - {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:831da96ba3f36cc892f0afbb4fb89b28b61b387261676e55d55a682addbd29f7"}, - {file = "pyzmq-23.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c8dec8a2f3f0bb462e6439df436cd8c7ec37968e90b4209ac621e7fbc0ed3b00"}, - {file = "pyzmq-23.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:814e5aaf0c3be9991a59066eafb2d6e117aed6b413e3e7e9be45d4e55f5e2748"}, - {file = "pyzmq-23.2.0-cp36-cp36m-win32.whl", hash = "sha256:8496a2a5efd055c61ac2c6a18116c768a25c644b6747dcfde43e91620ab3453c"}, - {file = "pyzmq-23.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:60746a7e8558655420a69441c0a1d47ed225ed3ac355920b96a96d0554ef7e6b"}, - {file = "pyzmq-23.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5cb642e94337b0c76c9c8cb9bfb0f8a78654575847d080d3e1504f312d691fc3"}, - {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:444f7d615d5f686d0ef508b9edfa8a286e6d89f449a1ba37b60ef69d869220a3"}, - {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c9638e0057e3f1a8b7c5ce33c7575349d9183a033a19b5676ad55096ae36820b"}, - {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:004a431dfa0459123e6f4660d7e3c4ac19217d134ca38bacfffb2e78716fe944"}, - {file = "pyzmq-23.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5592fb4316f895922b1cacb91b04a0fa09d6f6f19bbab4442b4d0a0825177b93"}, - {file = "pyzmq-23.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c0a5f987d73fd9b46c3d180891f829afda714ab6bab30a1218724d4a0a63afd8"}, - {file = "pyzmq-23.2.0-cp37-cp37m-win32.whl", hash = "sha256:d11628212fd731b8986f1561d9bb3f8c38d9c15b330c3d8a88963519fbcd553b"}, - {file = "pyzmq-23.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:558f5f636e3e65f261b64925e8b190e8689e334911595394572cc7523879006d"}, - {file = "pyzmq-23.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b97f624da42813f74977425a3a6144d604ea21cf065616d36ea3a866d92c1c"}, - {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:693c96ae4d975eb8efa1639670e9b1fac0c3f98b7845b65c0f369141fb4bb21f"}, - {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b054525c9f7e240562185bf21671ca16d56bde92e9bd0f822c07dec7626b704"}, - {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:859059caf564f0c9398c9005278055ed3d37af4d73de6b1597821193b04ca09b"}, - {file = "pyzmq-23.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8355744fdbdeac5cfadfa4f38b82029b5f2b8cab7472a33453a217a7f3a9dce2"}, - {file = "pyzmq-23.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:420b9abd1a7330687a095373b8280a20cdee04342fbc8ccb3b56d9ec8efd4e62"}, - {file = "pyzmq-23.2.0-cp38-cp38-win32.whl", hash = "sha256:59928dfebe93cf1e203e3cb0fd5d5dd384da56b99c8305f2e1b0a933751710f6"}, - {file = "pyzmq-23.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:c882f1d4f96fbd807e92c334251d8ebd159a1ef89059ccd386ddea83fdb91bd8"}, - {file = "pyzmq-23.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ced12075cdf3c7332ecc1960f77f7439d5ebb8ea20bbd3c34c8299e694f1b0a1"}, - {file = "pyzmq-23.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3a4d87342c2737fbb9eee5c33c792db27b36b04957b4e6b7edd73a5b239a2a13"}, - {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:99cedf38eaddf263cf7e2a50e405f12c02cedf6d9df00a0d9c5d7b9417b57f76"}, - {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1610260cc672975723fcf7705c69a95f3b88802a594c9867781bedd9b13422c"}, - {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c223a13555444707a0a7ebc6f9ee63053147c8c082bd1a31fd1207a03e8b0500"}, - {file = "pyzmq-23.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5fdb00d65ec44b10cc6b9b6318ef1363b81647a4aa3270ca39565eadb2d1201"}, - {file = "pyzmq-23.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:984b232802eddf9f0be264a4d57a10b3a1fd7319df14ee6fc7b41c6d155a3e6c"}, - {file = "pyzmq-23.2.0-cp39-cp39-win32.whl", hash = "sha256:f146648941cadaaaf01254a75651a23c08159d009d36c5af42a7cc200a5e53ec"}, - {file = "pyzmq-23.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:83005d8928f8a5cebcfb33af3bfb84b1ad65d882b899141a331cc5d07d89f093"}, - {file = "pyzmq-23.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fee86542dc4ee8229e023003e3939b4d58cc2453922cf127778b69505fc9064b"}, - {file = "pyzmq-23.2.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5d57542429df6acff02ff022067aa75b677603cee70e3abb9742787545eec966"}, - {file = "pyzmq-23.2.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:057b154471e096e2dda147f7b057041acc303bb7ca4aa24c3b88c6cecdd78717"}, - {file = "pyzmq-23.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5d92e7cbeab7f70b08cc0f27255b0bb2500afc30f31075bca0b1cb87735d186c"}, - {file = "pyzmq-23.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:eb4a573a8499685d62545e806d8fd143c84ac8b3439f925cd92c8763f0ed9bd7"}, - {file = "pyzmq-23.2.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:da338e2728410d74ddeb1479ec67cfba73311607037455a40f92b6f5c62bf11d"}, - {file = "pyzmq-23.2.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1b2a21f595f8cc549abd6c8de1fcd34c83441e35fb24b8a59bf161889c62a486"}, - {file = "pyzmq-23.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8c0f4d6f8c985bab83792be26ff3233940ba42e22237610ac50cbcfc10a5c235"}, - {file = "pyzmq-23.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bbabd1df23bf63ae829e81200034c0e433499275a6ed29ca1a912ea7629426d9"}, - {file = "pyzmq-23.2.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21552624ce69e69f7924f413b802b1fb554f4c0497f837810e429faa1cd4f163"}, - {file = "pyzmq-23.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c616893a577e9d6773a3836732fd7e2a729157a108b8fccd31c87512fa01671a"}, - {file = "pyzmq-23.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ce4f71e17fa849de41a06109030d3f6815fcc33338bf98dd0dde6d456d33c929"}, - {file = "pyzmq-23.2.0.tar.gz", hash = "sha256:a51f12a8719aad9dcfb55d456022f16b90abc8dde7d3ca93ce3120b40e3fa169"}, -] -requests = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, -] -restrictedpython = [ - {file = "RestrictedPython-5.0-py2.py3-none-any.whl", hash = "sha256:9bd69505147b0ff8c68f4ff5a275975a3ab66fc43cbf3b61a195650ed767cd4e"}, - {file = "RestrictedPython-5.0.tar.gz", hash = "sha256:a080569bffdf53371ae3e754ab1732f43054b1bab904fc100f74ba68ac731abc"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -stack-data = [ - {file = "stack_data-0.3.0-py3-none-any.whl", hash = "sha256:aa1d52d14d09c7a9a12bb740e6bdfffe0f5e8f4f9218d85e7c73a8c37f7ae38d"}, - {file = "stack_data-0.3.0.tar.gz", hash = "sha256:77bec1402dcd0987e9022326473fdbcc767304892a533ed8c29888dacb7dddbc"}, -] -swagger-ui-bundle = [ - {file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"}, - {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tornado = [ - {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, - {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, - {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, - {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, - {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, -] -traitlets = [ - {file = "traitlets-5.3.0-py3-none-any.whl", hash = "sha256:65fa18961659635933100db8ca120ef6220555286949774b9cfc106f941d1c7a"}, - {file = "traitlets-5.3.0.tar.gz", hash = "sha256:0bb9f1f9f017aa8ec187d8b1b2a7a6626a2a1d877116baba52a129bfa124f8e2"}, -] -urllib3 = [] -uwsgi = [ - {file = "uwsgi-2.0.20.tar.gz", hash = "sha256:88ab9867d8973d8ae84719cf233b7dafc54326fcaec89683c3f9f77c002cdff9"}, -] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] -werkzeug = [] -z3-solver = [] -zipp = [] diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index bbde285695f94094f7b8e21a36da55253d4751a4..0000000000000000000000000000000000000000 --- a/pyproject.toml +++ /dev/null @@ -1,26 +0,0 @@ -[tool.poetry] -name = "mc_openapi" -version = "0.2.0" -description = "OpenAPI interface for the PIACERE DOML model checker." -authors = ["Michele Chiari <michele.chiari@polimi.it>", "Michele De Pascalis <michele.de.pascalis.1024@gmail.com>"] -license = "Apache-2.0" - -[tool.poetry.dependencies] -python = "^3.9" -connexion = {extras = ["swagger-ui"], version = "^2.9.0"} -uWSGI = "^2.0.20" -pyecore = "^0.12.2" -z3-solver = "^4.8.15" -PyYAML = "^6.0" -networkx = "^2.7.1" -joblib = "^1.1.0" - -[tool.poetry.dev-dependencies] -pytest = "^6.0" -requests = "^2.26.0" -ipykernel = "^6.12.1" -prettyprinter = "^0.18.0" - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index 220b8df2bcb3d25822ef6588b4a910b781b6d11c..b8a42a33b7b0df313a84955baedf2d41047d749e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,33 +1,15 @@ -attrs==22.1.0; python_version >= "3.7" -certifi==2022.6.15; python_version >= "3.7" and python_version < "4" -charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4" and python_full_version >= "3.6.0" -click==8.1.3; python_version >= "3.7" -clickclick==20.10.2; python_version >= "3.6" -colorama==0.4.5; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0" -connexion==2.14.0; python_version >= "3.6" -flask==2.1.3; python_version >= "3.7" -future-fstrings==1.2.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" -idna==3.3; python_version >= "3.7" and python_version < "4" -importlib-metadata==4.12.0; python_version < "3.10" and python_version >= "3.7" -inflection==0.5.1; python_version >= "3.6" -itsdangerous==2.1.2; python_version >= "3.7" -jinja2==3.1.2; python_version >= "3.7" -joblib==1.1.0; python_version >= "3.6" -jsonschema==4.8.0; python_version >= "3.7" -lxml==4.9.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" -markupsafe==2.1.1; python_version >= "3.7" -networkx==2.8.5; python_version >= "3.8" -ordered-set==4.1.0; python_version >= "3.7" -packaging==21.3; python_version >= "3.6" -pyecore==0.12.2 -pyparsing==3.0.9; python_full_version >= "3.6.8" and python_version >= "3.6" -pyrsistent==0.18.1; python_version >= "3.7" -pyyaml==6.0; python_version >= "3.6" -requests==2.28.1; python_version >= "3.7" and python_version < "4" -restrictedpython==5.0 -swagger-ui-bundle==0.0.9; python_version >= "3.6" -urllib3==1.26.11; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" -uwsgi==2.0.20 -werkzeug==2.2.1; python_version >= "3.7" -z3-solver==4.10.2.0 -zipp==3.8.1; python_version < "3.10" and python_version >= "3.7" +tabulate +fastapi +joblib +z3-solver==4.11.* # Else it deadlocks the MC somehow +networkx +lxml +pyecore +piacere-doml-synthesis +lark +uvicorn[standard] +pytest +pytest-xdist +pytest-subtests +jinja2 +requests diff --git a/tests/doml/CaseStudies/SIMPA_Validation_v2.doml b/tests/doml/CaseStudies/SIMPA_Validation_v2.doml new file mode 100644 index 0000000000000000000000000000000000000000..e86d7679d5bc6842826f49acf8ac79ddd83bcb7f --- /dev/null +++ b/tests/doml/CaseStudies/SIMPA_Validation_v2.doml @@ -0,0 +1,84 @@ +doml nio3_test_exec_env + +application app { + // To be discussed + software_component potainer { + source r1 { + + } + } + + software_component nio3_git { + source r1 { + entry "ansible/provision.yml" + backend "ansible" + properties { + nexus_docker_registry_user = "***"; + nexus_docker_registry_password = "***"; + } + } + } + +} + +infrastructure infra { + + container co1 { + host vm1 + } + + vm vm1 { + os "CentOS-7-2111" + cpu_count 2 + mem_mb 8192.0 + iface i1 { + address "10.0.0.1" + belongs_to net1 + } + } + + net net1 { + // cidr "/24" -> WRONG + // cidr "[10.0.0.1, 10.0.0.5]" -> WRONG + cidr "10.0.0.0/29" // -> 2^3 ips, 10.0.0.1-10.0.0.6 + protocol "tcp/ip" + } + + sto disk0 { + label "disk0" + size_gb 40 + } +} + +deployment conf { + potainer -> co1, + co1 -> vm1 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + properties {} + + vm concrete_vm { + properties { + vm_flavor = "small-centos"; + } + maps vm1 + } + + net concrete_net { + preexisting true + properties {} + maps net1 + } + + storage concrete_disk { + maps disk0 + } + } + } + active con_infra +} diff --git a/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx b/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx new file mode 100644 index 0000000000000000000000000000000000000000..4b96701c3f7b1f25c613a1a7e241c727fb849841 --- /dev/null +++ b/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="nio3_test_exec_env" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="potainer"> + <src name="r1"/> + </components> + <components xsi:type="app:SoftwareComponent" name="nio3_git"> + <src name="r1" entry="ansible/provision.yml" backend="ansible"> + <annotations xsi:type="commons:SProperty" key="nexus_docker_registry_user" value="***"/> + <annotations xsi:type="commons:SProperty" key="nexus_docker_registry_password" value="***"/> + </src> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:Container" name="co1"> + <configs host="//@infrastructure/@nodes.1"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm1" os="CentOS-7-2111" memory_mb="8192.0" cpu_count="2"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0"/> + </nodes> + <storages name="disk0" label="disk0" size_gb="40"/> + <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/29" connectedIfaces="//@infrastructure/@nodes.1/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@nodes.1"> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small-centos"/> + </vms> + <networks name="concrete_net" preexisting="true" maps="//@infrastructure/@networks.0"/> + <storages name="concrete_disk" maps="//@infrastructure/@storages.0"/> + </providers> + </concretizations> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@infrastructure/@nodes.0" node="//@infrastructure/@nodes.1"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/CaseStudies/nio3_test_exec_env.doml b/tests/doml/CaseStudies/nio3_test_exec_env.doml new file mode 100644 index 0000000000000000000000000000000000000000..6c7bf3716a8435d31ad37dc3b375be0e00459cee --- /dev/null +++ b/tests/doml/CaseStudies/nio3_test_exec_env.doml @@ -0,0 +1,144 @@ +doml nio3_test_exec_env + +application app { + + software_component nio3 { + properties {} + } +} + +infrastructure infra { + + net net1 { + cidr "/24" + protocol "tcp/ip" + gateway g1 { + address "10.83.18.65" + } + } + + user_pass ssh_pass { + user "root" + pass "pa$$w0rd" + } + + key_pair ssh_key { + keyfile "/home/rmandal/.ssh/id_rsa.pub" + } + + vm_image img { + generates vm1, vm2 + } + + vm vm1 { + os "centos7_64Guest" + cpu_count 2 + mem_mb 1024.0 + iface i1 { + address "10.83.18.92" + belongs_to net1 + } + credentials ssh_pass + } + + vm vm2 { + os "centos7_64Guest" + cpu_count 2 + mem_mb 1024.0 + iface i1 { + address "10.83.18.88" + belongs_to net1 + } + credentials ssh_pass + } + + sto disk0 { + label "disk0" + size_gb 100 + } +} + +deployment conf { + nio3 -> vm1, nio3 -> vm2 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider vsphere { + properties { + username = "vc_username"; + password = "vc_password"; + vsphere_server = "psvc10000002.cd.sigov.si"; + allow_unverified_ssl = true; + } + + generic_resource dc { + preexisting true + type 'vsphere_datacenter' + gname 'MB' + } + + generic_resource cl { + preexisting true + refs_to dc + type 'vsphere_compute_cluster' + gname 'MB-PIAC-NIC-1' + } + + generic_resource pool { + preexisting true + refs_to dc + type 'vsphere_resource_pool' + gname 'PIAC' + } + + vm_image template { + preexisting true + refs_to dc + properties { + vsphere_virtual_machine_name = "Centos7_PIAC"; + } + maps img + } + + storage datastore { + preexisting true + refs_to dc + properties { + vsphere_datastore_name = 'VNX01-0200-NIC-TA-PIAC-DRO-VMW-P'; + } + maps disk0 + } + + net network { + preexisting true + refs_to dc + properties { + vsphere_network_name = "DRO-MB-P-BG001-2098"; + } + maps net1 + } + + vm con_vm1 { + refs_to pool, datastore + properties { + host_name = "piac-0"; + domain = "ad.sigov.si"; + } + maps vm1 + } + + vm con_vm2 { + refs_to pool, datastore + properties { + host_name = "piac-1"; + domain = "ad.sigov.si"; + } + maps vm2 + } + } + } + active con_infra +} diff --git a/tests/doml/CaseStudies/nio3_test_exec_env.domlx b/tests/doml/CaseStudies/nio3_test_exec_env.domlx new file mode 100644 index 0000000000000000000000000000000000000000..99050ef905dfb1bb4bfe4d7daa55ca1c6e66e910 --- /dev/null +++ b/tests/doml/CaseStudies/nio3_test_exec_env.domlx @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="nio3_test_exec_env" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nio3"/> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1" os="centos7_64Guest" memory_mb="1024.0" cpu_count="2" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.83.18.92" belongsTo="//@infrastructure/@networks.0"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm2" os="centos7_64Guest" memory_mb="1024.0" cpu_count="2" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.83.18.88" belongsTo="//@infrastructure/@networks.0"/> + </nodes> + <generators xsi:type="infra:VMImage" name="img" generatedVMs="//@infrastructure/@nodes.0 //@infrastructure/@nodes.1"/> + <storages name="disk0" label="disk0" size_gb="100"/> + <credentials xsi:type="commons:UserPass" name="ssh_pass" username="root" password="pa$$w0rd"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" keyfile="/home/rmandal/.ssh/id_rsa.pub"/> + <networks name="net1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0"> + <gateways name="g1" address="10.83.18.65"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="vsphere"> + <annotations xsi:type="commons:SProperty" key="username" value="vc_username"/> + <annotations xsi:type="commons:SProperty" key="password" value="vc_password"/> + <annotations xsi:type="commons:SProperty" key="vsphere_server" value="psvc10000002.cd.sigov.si"/> + <annotations xsi:type="commons:BProperty" key="allow_unverified_ssl" value="true"/> + <resources name="dc" preexisting="true" type="vsphere_datacenter" gname="MB"/> + <resources name="cl" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" type="vsphere_compute_cluster" gname="MB-PIAC-NIC-1"/> + <resources name="pool" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" type="vsphere_resource_pool" gname="PIAC"/> + <vms name="con_vm1" refs="//@concretizations.0/@providers.0/@resources.2 //@concretizations.0/@providers.0/@storages.0" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="host_name" value="piac-0"/> + <annotations xsi:type="commons:SProperty" key="domain" value="ad.sigov.si"/> + </vms> + <vms name="con_vm2" refs="//@concretizations.0/@providers.0/@resources.2 //@concretizations.0/@providers.0/@storages.0" maps="//@infrastructure/@nodes.1"> + <annotations xsi:type="commons:SProperty" key="host_name" value="piac-1"/> + <annotations xsi:type="commons:SProperty" key="domain" value="ad.sigov.si"/> + </vms> + <vmImages name="template" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="vsphere_virtual_machine_name" value="Centos7_PIAC"/> + </vmImages> + <networks name="network" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vsphere_network_name" value="DRO-MB-P-BG001-2098"/> + </networks> + <storages name="datastore" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@storages.0"> + <annotations xsi:type="commons:SProperty" key="vsphere_datastore_name" value="VNX01-0200-NIC-TA-PIAC-DRO-VMW-P"/> + </storages> + </providers> + </concretizations> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.1"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/CaseStudies/posidonia.doml b/tests/doml/CaseStudies/posidonia.doml new file mode 100644 index 0000000000000000000000000000000000000000..82ba8c453ec2914d198850e91922055af4b68a65 --- /dev/null +++ b/tests/doml/CaseStudies/posidonia.doml @@ -0,0 +1,258 @@ +doml posidonia +properties { + entorno="pre"; + proyecto="baleares"; +} + +// Application Definition +application posidonia { + software_component Gestaut { + provides { http https } + consumes { dbAccess, search } + } + software_component ElasticSearch { + provides { search } + consumes { dbAccess } + } + software_component Edi { + provides { edi } + consumes { dbAccess } + } + dbms Database { + provides { + dbAccess + } + } +} + +infrastructure abstractInfra { + // Networks + net vpc { + cidr "/16" + protocol "tcp/ip" + subnet subnet1 { + cidr "/24" + protocol "tcp/ip" + } + subnet subnet2 { + cidr "/24" + protocol "tcp/ip" + } + subnet subnet3 { + cidr "/24" + protocol "tcp/ip" + } + } + // Credentials + // TODO: key file? + key_pair GestautKeyName { + algorithm "RSA" + bits 4096 + } + key_pair ESKeyName { + algorithm "RSA" + bits 4096 + } + key_pair EdiKeyName { + algorithm "RSA" + bits 4096 + } + user_pass dbCredentials { + user "***" + pass "***" + } + + // Nodes + vm OracleDB { + iface db1 { + belongs_to subnet1 + } + iface db2 { + belongs_to subnet2 + } + iface db3 { + belongs_to subnet3 + } + sto "20" + credentials dbCredentials + } + + vm_image posidonia_image { + generates gestaut_vm, elasticsearch_vm, edi_vm + image "ami-02a6bfdcf8224bd77" + } + + autoscale_group gestaut_asg { + // TODO: Shouldn't vm live outside the group leaving a reference here? vm might also be referenced by other components. + // It also applies to the following vms in other groups. + vm gestaut_vm { + credentials GestautKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + } + + autoscale_group elasticsearch_asg { + // TODO + vm elasticsearch_vm { + credentials ESKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + } + + autoscale_group edi_asg { + // TODO + vm edi_vm { + credentials EdiKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + } + + security_group sg { + // TODO: the following vms should have the associated interfaces (ifaces) in the security group? + //nodes gestaut_vm, elasticsearch_vm, edi_vm + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress lb { + protocol "tcp" + from_port 80 + to_port 80 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + ingress es { + protocol "tcp" + from_port 9200 + to_port 9200 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + ingress monitor { + protocol "tcp" + from_port 6556 + to_port 6556 + cidr ["54.217.119.81/32"] + } + + // TODO: ftp (20/21) or ssh (22)? + ingress ftp { + protocol "tcp" + from_port 22 + to_port 22 + cidr ["213.96.27.139/32", "37.187.173.88/32", "51.89.40.59/32", "195.53.242.200/32"] + } + } + + security_group dbsg { + // TODO: the associated vms and ifaces? + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress ora { + protocol "tcp" + from_port 1521 + to_port 1521 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24", "84.124.78.66/32"] + } + } + + security_group elbsg { + // TODO: the associated vms and ifaces? + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress http { + protocol "tcp" + from_port 80 + to_port 80 + cidr ["0.0.0.0/0", "::/0"] + } + ingress https { + protocol "tcp" + from_port 443 + to_port 443 + cidr ["0.0.0.0/0", "::/0"] + } + ingress es { + protocol "tcp" + from_port 9200 + to_port 9200 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + } + + security_group checkmk { + // TODO: the associated vms and ifaces? + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress http { + protocol "tcp" + from_port 80 + to_port 80 + cidr ["84.124.78.66/32"] + } + ingress https { + protocol "tcp" + from_port 443 + to_port 443 + cidr ["84.124.78.66/32"] + } + + // TODO: ftp (20/21) or ssh (22)? + ingress ftp { + protocol "tcp" + from_port 22 + to_port 22 + cidr ["84.124.78.66/32"] + } + } + +} +deployment dep { + Gestaut -> gestaut_vm, + ElasticSearch -> elasticsearch_vm, + Edi -> edi_vm, + Database -> OracleDB + +} +active deployment dep + +// Concretization to AWS +concretizations { + concrete_infrastructure dev { + provider aws { + autoscale_group asg1 { + maps elasticsearch_asg + } + autoscale_group asg2 { + maps edi_asg + } + autoscale_group asg3 { + maps gestaut_asg + } + } + } + +// concrete_infrastructure pro { +// provider aws { +// +// } +// } + + active dev +} + diff --git a/tests/doml/CaseStudies/posidonia.domlx b/tests/doml/CaseStudies/posidonia.domlx new file mode 100644 index 0000000000000000000000000000000000000000..151646f5ebddfe27c508f59e55a7879ad0b9b1f5 --- /dev/null +++ b/tests/doml/CaseStudies/posidonia.domlx @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="posidonia" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <annotations xsi:type="commons:SProperty" key="entorno" value="pre"/> + <annotations xsi:type="commons:SProperty" key="proyecto" value="baleares"/> + <application name="posidonia"> + <components xsi:type="app:SoftwareComponent" name="Gestaut" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.0"> + <exposedInterfaces name="http"/> + <exposedInterfaces name="https"/> + </components> + <components xsi:type="app:SoftwareComponent" name="ElasticSearch" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="search"/> + </components> + <components xsi:type="app:SoftwareComponent" name="Edi" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="edi"/> + </components> + <components xsi:type="app:DBMS" name="Database"> + <exposedInterfaces name="dbAccess"/> + </components> + </application> + <infrastructure name="abstractInfra"> + <nodes xsi:type="infra:VirtualMachine" name="OracleDB" storage="20" credentials="//@infrastructure/@credentials.3"> + <ifaces name="db1" belongsTo="//@infrastructure/@networks.0/@subnets.0"/> + <ifaces name="db2" belongsTo="//@infrastructure/@networks.0/@subnets.1"/> + <ifaces name="db3" belongsTo="//@infrastructure/@networks.0/@subnets.2"/> + </nodes> + <generators xsi:type="infra:VMImage" name="posidonia_image" uri="ami-02a6bfdcf8224bd77" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition //@infrastructure/@groups.1/@machineDefinition //@infrastructure/@groups.2/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="GestautKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:KeyPair" name="ESKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:KeyPair" name="EdiKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:UserPass" name="dbCredentials" username="***" password="***"/> + <groups xsi:type="infra:AutoScalingGroup" name="gestaut_asg"> + <machineDefinition name="gestaut_vm" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="elasticsearch_asg"> + <machineDefinition name="elasticsearch_vm" credentials="//@infrastructure/@credentials.1" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="edi_asg"> + <machineDefinition name="edi_vm" credentials="//@infrastructure/@credentials.2" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <securityGroups name="sg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="lb" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + <rules name="monitor" kind="INGRESS" protocol="tcp" fromPort="6556" toPort="6556"> + <cidr>54.217.119.81/32</cidr> + </rules> + <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>213.96.27.139/32</cidr> + <cidr>37.187.173.88/32</cidr> + <cidr>51.89.40.59/32</cidr> + <cidr>195.53.242.200/32</cidr> + </rules> + </securityGroups> + <securityGroups name="dbsg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ora" kind="INGRESS" protocol="tcp" fromPort="1521" toPort="1521"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + <cidr>84.124.78.66/32</cidr> + </rules> + </securityGroups> + <securityGroups name="elbsg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + <cidr>::/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + <cidr>::/0</cidr> + </rules> + <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + </securityGroups> + <securityGroups name="checkmk"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>84.124.78.66/32</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>84.124.78.66/32</cidr> + </rules> + <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>84.124.78.66/32</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/16"> + <subnets name="subnet1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/> + <subnets name="subnet2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.1"/> + <subnets name="subnet3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.2"/> + </networks> + </infrastructure> + <concretizations name="dev"> + <providers name="aws"> + <group name="asg1" maps="//@infrastructure/@groups.1"/> + <group name="asg2" maps="//@infrastructure/@groups.2"/> + <group name="asg3" maps="//@infrastructure/@groups.0"/> + </providers> + </concretizations> + <configurations name="dep"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@groups.1/@machineDefinition"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/> + <deployments component="//@application/@components.3" node="//@infrastructure/@nodes.0"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/CaseStudies/posidonia_IOP.doml b/tests/doml/CaseStudies/posidonia_IOP.doml new file mode 100644 index 0000000000000000000000000000000000000000..e441982f154cd863612c9ba5b01c174d95498c3c --- /dev/null +++ b/tests/doml/CaseStudies/posidonia_IOP.doml @@ -0,0 +1,307 @@ +doml posidonia +properties { + entorno="pre"; + proyecto="baleares"; +} + +// Application Definition +application posidonia { + software_component Gestaut { + // Interfaces should be separated by commas, but the IDE needs to be fixed + provides { http https } + consumes { dbAccess, search } + } + software_component ElasticSearch { + provides { search } + consumes { dbAccess } + } + software_component Edi { + provides { edi } + consumes { dbAccess } + } + dbms Database { + provides { + dbAccess + } + } +} + +infrastructure abstractInfra { + // Networks + net vpc { + // In DOML 2.1, you can specify an address before the length of the subnet mask + // Actually it should also work in DOML 2.2 for ICG + cidr "/16" + protocol "TCP/IP" + subnet subnet1 { + // We have to check whether this address (which was copy-pasted from the + // security group rules cidr) actually was the one intended for the subnet + cidr "10.100.1.0/24" + protocol "TCP/IP" + } + subnet subnet2 { + cidr "/24" + protocol "TCP/IP" + } + subnet subnet3 { + cidr "/24" + protocol "TCP/IP" + } + } + // Credentials + // TODO: key file? + key_pair GestautKeyName { + // We're here specifying the key through the keyfile attribute instead of using it for specifying the keyfile path. + user "..." + keyfile "not the path, but currently the key itself" + algorithm "RSA" + bits 4096 + } + key_pair ESKeyName { + user "..." + keyfile "not the path, but currently the key itself" + algorithm "RSA" + bits 4096 + } + key_pair EdiKeyName { + user "..." + keyfile "not the path, but currently the key itself" + algorithm "RSA" + bits 4096 + } + user_pass dbCredentials { + user "***" + pass "***" + } + + // Nodes + vm OracleDB { + // It can be updated by specifying the VM characteristics through the usage of attributes + iface db1 { + belongs_to subnet1 + // We can define the security group associated to the interface either by using the + // security attribute here or specifying the name of the interface in the + // ifaces attribute of the security group itself + security dbsg + } + iface db2 { + belongs_to subnet2 + } + iface db3 { + belongs_to subnet3 + } + // We have to specify GB or ... + sto "20" + credentials dbCredentials + } + + /* + * We currently don't use images, but specify properties through VM attributes definition + vm_image posidonia_image { + generates gestaut_vm, elasticsearch_vm, edi_vm + image "ami-02a6bfdcf8224bd77" + } + */ + + + autoscale_group gestaut_asg { + // TODO: Shouldn't vm live outside the group leaving a reference here? vm might also be referenced by other components. + // It also applies to the following vms in other groups. + vm gestaut_vm { + credentials GestautKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + + /* + * In order to specify the sg for the three VMs defined for the AGs, we can + * use the security attribute of the autoscale_group class. + * We have to define a new security group inside the autoscale_group + * when using such attribute. + */ + } + + autoscale_group elasticsearch_asg { + // TODO + vm elasticsearch_vm { + credentials ESKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + } + + autoscale_group edi_asg { + // TODO + vm edi_vm { + credentials EdiKeyName + } + min 1 + max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error + } + + security_group sg { + // TODO: the following vms should have the associated interfaces (ifaces) in the security group? + //nodes gestaut_vm, elasticsearch_vm, edi_vm + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress lb { + protocol "TCP" + from_port 80 + to_port 80 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + ingress es { + protocol "TCP" + from_port 9200 + to_port 9200 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + ingress monitor { + protocol "TCP" + from_port 6556 + to_port 6556 + cidr ["54.217.119.81/32"] + } + + // TODO: ftp (20/21) or ssh (22)? + ingress ftp { + protocol "TCP" + from_port 22 + to_port 22 + cidr ["213.96.27.139/32", "37.187.173.88/32", "51.89.40.59/32", "195.53.242.200/32"] + } + } + + /* + * TODO: We have to define interfaces or check which interfaces/AGs belong to each sg + */ + security_group dbsg { + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress ora { + protocol "TCP" + from_port 1521 + to_port 1521 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24", "84.124.78.66/32"] + } + + // As discussed above, here is provided the other way to specify the sg + // associated to interfaces + ifaces db1, db2, db3 + } + + security_group elbsg { + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress http { + protocol "TCP" + from_port 80 + to_port 80 + cidr ["0.0.0.0/0", "::/0"] + } + ingress https { + protocol "TCP" + from_port 443 + to_port 443 + cidr ["0.0.0.0/0", "::/0"] + } + ingress es { + protocol "TCP" + from_port 9200 + to_port 9200 + cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"] + } + } + + security_group checkmk { + egress salida { + protocol "-1" + from_port 0 + to_port 0 + cidr ["0.0.0.0/0"] + } + ingress http { + protocol "TCP" + from_port 80 + to_port 80 + cidr ["84.124.78.66/32"] + } + ingress https { + protocol "TCP" + from_port 443 + to_port 443 + cidr ["84.124.78.66/32"] + } + + // TODO: ftp (20/21) or ssh (22)? + ingress ftp { + protocol "TCP" + from_port 22 + to_port 22 + cidr ["84.124.78.66/32"] + } + } + +} +deployment dep { + Gestaut -> gestaut_vm, + ElasticSearch -> elasticsearch_vm, + Edi -> edi_vm, + Database -> OracleDB + +} +active deployment dep + +// Concretization to AWS +concretizations { + concrete_infrastructure dev { + provider aws { + net concrete_vpc { + maps vpc + } + vm concrete_oracleDB { + maps OracleDB + } + autoscale_group asg1 { + maps elasticsearch_asg + } + autoscale_group asg2 { + maps edi_asg + } + autoscale_group asg3 { + maps gestaut_asg + } + } + } + +// concrete_infrastructure pro { +// provider aws { +// +// } +// } + + active dev +} + +optimization opt { + objectives { + "cost" => min + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 70.0" max 70.0 => "cost"; + req2 "Availability >= 66.5%" min 66.5 => "availability"; + } +} diff --git a/tests/doml/CaseStudies/posidonia_IOP.domlx b/tests/doml/CaseStudies/posidonia_IOP.domlx new file mode 100644 index 0000000000000000000000000000000000000000..e1bd8a0d55a7915a9f9f4a2deff579127894e452 --- /dev/null +++ b/tests/doml/CaseStudies/posidonia_IOP.domlx @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="posidonia" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <annotations xsi:type="commons:SProperty" key="entorno" value="pre"/> + <annotations xsi:type="commons:SProperty" key="proyecto" value="baleares"/> + <application name="posidonia"> + <components xsi:type="app:SoftwareComponent" name="Gestaut" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.0"> + <exposedInterfaces name="http"/> + <exposedInterfaces name="https"/> + </components> + <components xsi:type="app:SoftwareComponent" name="ElasticSearch" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="search"/> + </components> + <components xsi:type="app:SoftwareComponent" name="Edi" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="edi"/> + </components> + <components xsi:type="app:DBMS" name="Database"> + <exposedInterfaces name="dbAccess"/> + </components> + </application> + <infrastructure name="abstractInfra"> + <nodes xsi:type="infra:VirtualMachine" name="OracleDB" storage="20" credentials="//@infrastructure/@credentials.3"> + <ifaces name="db1" belongsTo="//@infrastructure/@networks.0/@subnets.0"/> + <ifaces name="db2" belongsTo="//@infrastructure/@networks.0/@subnets.1"/> + <ifaces name="db3" belongsTo="//@infrastructure/@networks.0/@subnets.2"/> + </nodes> + <generators xsi:type="infra:VMImage" name="posidonia_image" uri="ami-02a6bfdcf8224bd77" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition //@infrastructure/@groups.1/@machineDefinition //@infrastructure/@groups.2/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="GestautKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:KeyPair" name="ESKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:KeyPair" name="EdiKeyName" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:UserPass" name="dbCredentials" username="***" password="***"/> + <groups xsi:type="infra:AutoScalingGroup" name="gestaut_asg"> + <machineDefinition name="gestaut_vm" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="elasticsearch_asg"> + <machineDefinition name="elasticsearch_vm" credentials="//@infrastructure/@credentials.1" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="edi_asg"> + <machineDefinition name="edi_vm" credentials="//@infrastructure/@credentials.2" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <securityGroups name="sg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="lb" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + <rules name="monitor" kind="INGRESS" protocol="tcp" fromPort="6556" toPort="6556"> + <cidr>54.217.119.81/32</cidr> + </rules> + <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>213.96.27.139/32</cidr> + <cidr>37.187.173.88/32</cidr> + <cidr>51.89.40.59/32</cidr> + <cidr>195.53.242.200/32</cidr> + </rules> + </securityGroups> + <securityGroups name="dbsg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ora" kind="INGRESS" protocol="tcp" fromPort="1521" toPort="1521"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + <cidr>84.124.78.66/32</cidr> + </rules> + </securityGroups> + <securityGroups name="elbsg"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + <cidr>::/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + <cidr>::/0</cidr> + </rules> + <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200"> + <cidr>10.100.1.0/24</cidr> + <cidr>10.100.2.0/24</cidr> + <cidr>10.100.3.0/24</cidr> + </rules> + </securityGroups> + <securityGroups name="checkmk"> + <rules name="salida" protocol="-1" fromPort="0" toPort="0"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>84.124.78.66/32</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>84.124.78.66/32</cidr> + </rules> + <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>84.124.78.66/32</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/16"> + <subnets name="subnet1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/> + <subnets name="subnet2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.1"/> + <subnets name="subnet3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.2"/> + </networks> + </infrastructure> + <concretizations name="dev"> + <providers name="aws"> + <group name="asg1" maps="//@infrastructure/@groups.1"/> + <group name="asg2" maps="//@infrastructure/@groups.2"/> + <group name="asg3" maps="//@infrastructure/@groups.0"/> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="dep"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@groups.1/@machineDefinition"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/> + <deployments component="//@application/@components.3" node="//@infrastructure/@nodes.0"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/CaseStudies/uc3-openstack_v2.doml b/tests/doml/CaseStudies/uc3-openstack_v2.doml new file mode 100644 index 0000000000000000000000000000000000000000..f4feede7555e3fa203cb8269391481cc23ec39bb --- /dev/null +++ b/tests/doml/CaseStudies/uc3-openstack_v2.doml @@ -0,0 +1,246 @@ +doml uc3_openstack + +application app { + +// need to define all sw components of the project this is a placeholder +// need to understand what is really needed in this spec +// need to specify all provides/consumes + software_component iwg { + provides { net_info } + } + software_component osint { + provides { osint_info } + consumes { net_info, get_twitter, ewcf_rest_interface } + } + software_component ewcf { + provides { ewcf_rest_interface } + // ??? consumes { get_firebase } + } + saas external_twitter { + provides { get_twitter @ "https://twitter_api/get" } + } + +} + + +infrastructure infra { + + vm_image v_img1 { + generates osint_vm + } + + container c { + host osint_vm { + container_port 80 + vm_port 8080 + iface osint_igw_port + properties { + env_var1 = "value1"; + } + } + } + + cont_image c_img { + generates c + image "web-app:0.1.0" // needs to be replaced and other containers added + } + + + vm_image v_img2 { + generates igw_vm + } + + vm_image v_img3 { + generates ewcf_vm + } + + net net1 { + cidr "/24" + protocol "tcp/ip" + } + net net2 { + cidr "/24" + protocol "tcp/ip" + } + net net3 { + cidr "/24" + protocol "tcp/ip" + } + net oam { + cidr "/24" + protocol "tcp/ip" + } + + +// security group is left as originally defined needs to be updated + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + autoscale_group osint_ag { + vm osint_vm { + os "ubuntu-20.04.3" + credentials ssh_key + iface osint_vm_net1 { + belongs_to net1 + } + iface osint_vm_oam { + belongs_to oam + } + + iface osint_igw_port{ + belongs_to net1 + } + } + } + + autoscale_group igw_ag { + vm igw_vm { + os "ubuntu-20.04.3" + credentials ssh_key + iface igw_vm_net2 { + belongs_to net2 + } + iface igw_vm_oam { + belongs_to oam + } + } + } + autoscale_group ewcf_ag { + vm ewcf_vm { + os "ubuntu-20.04.3" + credentials ssh_key + iface ewcf_vm_net3 { + belongs_to net3 + } + iface ewcf_vm_oam { + belongs_to oam + } + } + } +} + +deployment conf { + osint -> osint_vm, + iwg -> igw_vm, + ewcf -> ewcf_vm +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_osint_vm { + properties { + vm_name = "osint"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps osint_vm + } + vm concrete_igw_vm { + properties { + vm_name = "igw"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps igw_vm + } + vm concrete_ewcf_vm { + properties { + vm_name = "ewcf"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps ewcf_vm + } + + vm_image concrete_vm_image1 { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img1 + } + + vm_image concrete_vm_image2{ + properties { + name = "ubuntu-20.04.3"; + } + maps v_img2 + } + + vm_image concrete_vm_image3 { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img3 + } + + net concrete_net1 { + properties { + name = "uc3_net1"; + } + maps net1 + } + net concrete_net2 { + properties { + name = "uc3_net2"; + } + maps net2 + } + net concrete_net3 { + properties { + name = "uc3_net3"; + } + maps net3 + } + net concrete_net4 { + properties { + name = "uc3_net4"; + } + maps oam + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/CaseStudies/uc3-openstack_v2.domlx b/tests/doml/CaseStudies/uc3-openstack_v2.domlx new file mode 100644 index 0000000000000000000000000000000000000000..c5c4b51099d8b6e1cfb883b9ceba253c58ddbae7 --- /dev/null +++ b/tests/doml/CaseStudies/uc3-openstack_v2.domlx @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="uc3_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="iwg"> + <exposedInterfaces name="net_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="osint" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.0"> + <exposedInterfaces name="osint_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="ewcf"> + <exposedInterfaces name="ewcf_rest_interface"/> + </components> + <components xsi:type="app:SaaS" name="external_twitter"> + <exposedInterfaces name="get_twitter" endPoint="https://twitter_api/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1"> + <configs container_port="80" vm_port="8080" host="//@infrastructure/@groups.0/@machineDefinition" iface="//@infrastructure/@groups.0/@machineDefinition/@ifaces.2"> + <annotations xsi:type="commons:SProperty" key="env_var1" value="value1"/> + </configs> + </nodes> + <generators xsi:type="infra:VMImage" name="v_img1" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.0"/> + <generators xsi:type="infra:VMImage" name="v_img2" generatedVMs="//@infrastructure/@groups.1/@machineDefinition"/> + <generators xsi:type="infra:VMImage" name="v_img3" generatedVMs="//@infrastructure/@groups.2/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="osint_ag"> + <machineDefinition name="osint_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="osint_vm_net1" belongsTo="//@infrastructure/@networks.0"/> + <ifaces name="osint_vm_oam" belongsTo="//@infrastructure/@networks.3"/> + <ifaces name="osint_igw_port" belongsTo="//@infrastructure/@networks.0"/> + </machineDefinition> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="igw_ag"> + <machineDefinition name="igw_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.2"> + <ifaces name="igw_vm_net2" belongsTo="//@infrastructure/@networks.1"/> + <ifaces name="igw_vm_oam" belongsTo="//@infrastructure/@networks.3"/> + </machineDefinition> + </groups> + <groups xsi:type="infra:AutoScalingGroup" name="ewcf_ag"> + <machineDefinition name="ewcf_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.3"> + <ifaces name="ewcf_vm_net3" belongsTo="//@infrastructure/@networks.2"/> + <ifaces name="ewcf_vm_oam" belongsTo="//@infrastructure/@networks.3"/> + </machineDefinition> + </groups> + <securityGroups name="sg"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.2"/> + <networks name="net2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.1/@machineDefinition/@ifaces.0"/> + <networks name="net3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.2/@machineDefinition/@ifaces.0"/> + <networks name="oam" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.1 //@infrastructure/@groups.1/@machineDefinition/@ifaces.1 //@infrastructure/@groups.2/@machineDefinition/@ifaces.1"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_osint_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="osint"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vms name="concrete_igw_vm" maps="//@infrastructure/@groups.1/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="igw"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vms name="concrete_ewcf_vm" maps="//@infrastructure/@groups.2/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="ewcf"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image1" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <vmImages name="concrete_vm_image2" maps="//@infrastructure/@generators.2"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <vmImages name="concrete_vm_image3" maps="//@infrastructure/@generators.3"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net1" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="uc3_net1"/> + </networks> + <networks name="concrete_net2" maps="//@infrastructure/@networks.1"> + <annotations xsi:type="commons:SProperty" key="name" value="uc3_net2"/> + </networks> + <networks name="concrete_net3" maps="//@infrastructure/@networks.2"> + <annotations xsi:type="commons:SProperty" key="name" value="uc3_net3"/> + </networks> + <networks name="concrete_net4" maps="//@infrastructure/@networks.3"> + <annotations xsi:type="commons:SProperty" key="name" value="uc3_net4"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.1" node="//@infrastructure/@groups.0/@machineDefinition"/> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.1/@machineDefinition"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/faas.domlx b/tests/doml/v2.0/faas.domlx similarity index 93% rename from tests/doml/faas.domlx rename to tests/doml/v2.0/faas.domlx index 50fafa4299dd28908012940b90411b7c45f032f5..762211b480b4c11552bc30c093fd458419d63465 100644 --- a/tests/doml/faas.domlx +++ b/tests/doml/v2.0/faas.domlx @@ -19,21 +19,18 @@ </components> </application> <infrastructure name="infra"> - <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0"> - <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@groups.0"/> + <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> <location region="eu-central-1"/> </nodes> <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1" hosts="//@infrastructure/@nodes.0"/> - <networks name="vpc" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"> - <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="10.0.0.0/24"/> - </networks> <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/> <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/> <storages name="st1"/> <storages name="st2"/> <faas name="f"/> <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> - <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0" ifaces="//@infrastructure/@nodes.0/@ifaces.0"> + <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0"> <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> <cidr>0.0.0.0/0</cidr> </rules> @@ -46,7 +43,10 @@ <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> <cidr>0.0.0.0/0</cidr> </rules> - </groups> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="10.0.0.0/24"/> + </networks> </infrastructure> <concretizations name="con_infra"> <providers name="aws"> diff --git a/tests/doml/nginx-openstack_v2.domlx b/tests/doml/v2.0/nginx-openstack_v2.0.domlx similarity index 80% rename from tests/doml/nginx-openstack_v2.domlx rename to tests/doml/v2.0/nginx-openstack_v2.0.domlx index e10fe0e6891f622a91b3b530fe9f82aa4e7e6d03..dbce61fd3084fc01aef2d6d9faefa59222867824 100644 --- a/tests/doml/nginx-openstack_v2.domlx +++ b/tests/doml/v2.0/nginx-openstack_v2.0.domlx @@ -6,15 +6,14 @@ </components> </application> <infrastructure name="infra"> - <nodes xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> - <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0"> - <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@groups.0"/> - </machineDefinition> - </nodes> - <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@machineDefinition/@ifaces.0"/> - <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@nodes.0/@machineDefinition"/> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> - <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition" ifaces="//@infrastructure/@nodes.0/@machineDefinition/@ifaces.0"> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> <cidr>0.0.0.0/0</cidr> </rules> @@ -27,11 +26,12 @@ <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> <cidr>0.0.0.0/0</cidr> </rules> - </groups> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> </infrastructure> <concretizations name="con_infra"> <providers name="openstack"> - <vms name="concrete_vm" maps="//@infrastructure/@nodes.0/@machineDefinition"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> @@ -52,6 +52,6 @@ </nonfunctionalRequirements> </optimization> <configurations name="config"> - <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0/@machineDefinition"/> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> </configurations> </commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx new file mode 100644 index 0000000000000000000000000000000000000000..79ba8b959d36aa642f1b3515e830e80af943e4aa --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" memory_mb="512.0" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml new file mode 100644 index 0000000000000000000000000000000000000000..9e8898179af5adc749f9e926ef31bc37cd1fa1c7 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml @@ -0,0 +1,116 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } + network net1 + } +} + +deployment config { + nginx -> vm1 +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } +// maps v_img + } + + net concrete_net { + properties { + name = "ostack2"; + } + maps net1 + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx new file mode 100644 index 0000000000000000000000000000000000000000..1aa558215b46ed384d83fc238e6965a1ca8e4915 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml new file mode 100644 index 0000000000000000000000000000000000000000..a5b2c726487f97700696ed9b9b2d0f5a2eac3611 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml @@ -0,0 +1,109 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } + network net1 + } +} + +deployment config { + nginx -> vm1 +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx new file mode 100644 index 0000000000000000000000000000000000000000..fdcdb0aaf97924d9cad2e601d85b55bf64db8e28 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml new file mode 100644 index 0000000000000000000000000000000000000000..5a904e851e1adbd9574b6901877eae93c31cab36 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml @@ -0,0 +1,115 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } + network net1 + } +} + +deployment config { +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img + } + + net concrete_net { + properties { + name = "ostack2"; + } + maps net1 + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx new file mode 100644 index 0000000000000000000000000000000000000000..4aef2e31e11bd523bc5c7afd94aa0f8d4ffeaea0 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml new file mode 100644 index 0000000000000000000000000000000000000000..669563db1b6d2b52750af12312c973938f968d6a --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml @@ -0,0 +1,135 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } + network net1 + } + + vm vm2 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } +} + +deployment config { + nginx -> vm1 +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm concrete_vm2 { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm2 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img + } + + net concrete_net { + properties { + name = "ostack2"; + } + maps net1 + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx new file mode 100644 index 0000000000000000000000000000000000000000..4d081ae996497723513f7fe380b4ebf1cc6fe652 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm2" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx new file mode 100644 index 0000000000000000000000000000000000000000..455b90f55300e3a4d61b4c5d726a1224fa9d81dc --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"/> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml new file mode 100644 index 0000000000000000000000000000000000000000..916648c526658e199be3fb448bbf69ebdf5ec49e --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml @@ -0,0 +1,157 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + consumes { + database + } + } + + software_component db { + provides { + database + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + net net2 { + address "17.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + iface i1 { + address "16.0.0.1" + belongs_to net1 + security sg + } + credentials ssh_key + } + network net1 + } + + vm vm2 { + os "ubuntu-20.04.3" + iface i2 { + address "17.0.0.1" + belongs_to net2 + security sg + } + credentials ssh_key + } +} + +deployment config { + nginx -> vm1, + db -> vm2 +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm concrete_vm2 { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm2 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img + } + + net concrete_net { + properties { + name = "ostack2"; + } + maps net1 + } + + net concrete_net2 { + properties { + name = "ostack2"; + } + maps net2 + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx new file mode 100644 index 0000000000000000000000000000000000000000..26cd394b6527fb9a4f8c71b8b2c51f9c340c6199 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + <components xsi:type="app:SoftwareComponent" name="db"> + <exposedInterfaces name="database"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm2" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0"> + <ifaces name="i2" endPoint="17.0.0.1" belongsTo="//@infrastructure/@networks.1" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0 //@infrastructure/@nodes.0/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/> + <networks name="net2" protocol="tcp/ip" addressRange="17.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/> + </vmImages> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + <networks name="concrete_net2" maps="//@infrastructure/@networks.1"> + <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.0"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml new file mode 100644 index 0000000000000000000000000000000000000000..bee1b4b2227817294296440aae24675ca076c687 --- /dev/null +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml @@ -0,0 +1,110 @@ +doml nginx_openstack + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image v_img { + generates vm1 + } + + net net1 { + address "16.0.0.0/24" + protocol "tcp/ip" + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + } + + key_pair ssh_key { + user "ubuntu" + keyfile "/home/user1/.ssh/openstack.key" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + os "ubuntu-20.04.3" + credentials ssh_key + } + network net1 + } +} + +deployment config { + nginx -> vm1 +} + +active deployment config + +concretizations { + concrete_infrastructure con_infra { + provider openstack { + vm concrete_vm { + properties { + vm_name = "nginx-host"; + vm_flavor = "small"; + vm_key_name = "user1"; + } + maps vm1 + } + + vm_image concrete_vm_image { + properties { + name = "ubuntu-20.04.3"; + } + maps v_img + } + + net concrete_net { + properties { + name = "ostack2"; + } + maps net1 + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + } + nonfunctional_requirements { + req1 "Cost <= 200" max 200.0 => "cost"; + req2 "Provider" values "AMAZ" => "provider"; + } +} diff --git a/tests/doml/nginx-openstack_v2_wrong.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx similarity index 83% rename from tests/doml/nginx-openstack_v2_wrong.domlx rename to tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx index 433c9f83dcc5d07d1b1ddd148bd4b42860c4d3f2..05401324bdba29fec01d5c144cb71df93225e492 100644 --- a/tests/doml/nginx-openstack_v2_wrong.domlx +++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx @@ -6,13 +6,12 @@ </components> </application> <infrastructure name="infra"> - <nodes xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> - <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0"/> - </nodes> - <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24"/> - <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@nodes.0/@machineDefinition"/> + <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> - <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition"> + <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0"> + <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/> + </groups> + <securityGroups name="sg"> <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> <cidr>0.0.0.0/0</cidr> </rules> @@ -25,11 +24,12 @@ <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> <cidr>0.0.0.0/0</cidr> </rules> - </groups> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24"/> </infrastructure> <concretizations name="con_infra"> <providers name="openstack"> - <vms name="concrete_vm" maps="//@infrastructure/@nodes.0/@machineDefinition"> + <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> @@ -46,10 +46,10 @@ <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> - <values>OPEN</values> + <values>AMAZ</values> </nonfunctionalRequirements> </optimization> <configurations name="config"> - <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0/@machineDefinition"/> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> </configurations> </commons:DOMLModel> diff --git a/tests/doml/v2.0/openstack_template.domlx b/tests/doml/v2.0/openstack_template.domlx new file mode 100644 index 0000000000000000000000000000000000000000..514308a5a88e83ed0173b8af5b5d698bc00744ff --- /dev/null +++ b/tests/doml/v2.0/openstack_template.domlx @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1" os="ubuntu-20.04.3"/> + </infrastructure> + <concretizations name="con_infra"> + <providers name="openstack"> + <vms name="concrete_vm" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/> + <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/> + </vms> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/saas.domlx b/tests/doml/v2.0/saas.domlx new file mode 100644 index 0000000000000000000000000000000000000000..bdfa1f32b00544dc4215557ea74c98884e61e693 --- /dev/null +++ b/tests/doml/v2.0/saas.domlx @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="iot_simple_app"> + <components xsi:type="app:DBMS" name="oracle"> + <exposedInterfaces name="sql_interface"/> + </components> + <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="sensor_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/> + <components xsi:type="app:SaaS" name="external_meteo"> + <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1"> + <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm2"> + <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"> + <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"> + <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra1"> + <providers name="aws"> + <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/> + <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/saas_https_no_attrs.domlx b/tests/doml/v2.0/saas_https_no_attrs.domlx new file mode 100644 index 0000000000000000000000000000000000000000..38cf851c241d1de8d8d970c58117e7e5c9f026e3 --- /dev/null +++ b/tests/doml/v2.0/saas_https_no_attrs.domlx @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="iot_simple_app"> + <components xsi:type="app:DBMS" name="oracle"> + <exposedInterfaces name="sql_interface"/> + </components> + <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="sensor_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/> + <components xsi:type="app:SaaS" name="external_meteo"> + <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1"> + <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm2"> + <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"> + <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"> + <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS"/> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra1"> + <providers name="aws"> + <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/> + <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/saas_no_https_rule.domlx b/tests/doml/v2.0/saas_no_https_rule.domlx new file mode 100644 index 0000000000000000000000000000000000000000..8d824c6679283729984ceec8bc4ff0c4a313729f --- /dev/null +++ b/tests/doml/v2.0/saas_no_https_rule.domlx @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="iot_simple_app"> + <components xsi:type="app:DBMS" name="oracle"> + <exposedInterfaces name="sql_interface"/> + </components> + <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="sensor_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/> + <components xsi:type="app:SaaS" name="external_meteo"> + <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1"> + <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm2"> + <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"> + <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"> + <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra1"> + <providers name="aws"> + <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/> + <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx b/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx new file mode 100644 index 0000000000000000000000000000000000000000..be6aaffdf2eda69c3eef4d1ebbf936ae2b5afdbe --- /dev/null +++ b/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="iot_simple_app"> + <components xsi:type="app:DBMS" name="oracle"> + <exposedInterfaces name="sql_interface"/> + </components> + <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="sensor_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/> + <components xsi:type="app:SaaS" name="external_meteo"> + <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1"> + <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0"/> + </nodes> + <nodes xsi:type="infra:VirtualMachine" name="vm2"> + <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"> + <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"> + <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + </nodes> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/> + <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/> + </infrastructure> + <concretizations name="con_infra1"> + <providers name="aws"> + <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/> + <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 200" property="cost" max="200.0"/> + <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider"> + <values>AMAZ</values> + </nonfunctionalRequirements> + </optimization> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.1/faas.domlx b/tests/doml/v2.1/faas.domlx new file mode 100644 index 0000000000000000000000000000000000000000..51dc9826cba0430f1fa4cb1da3ba4cc94b9515fc --- /dev/null +++ b/tests/doml/v2.1/faas.domlx @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="faas_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0" version="v2.1"> + <application name="ImageResizeApp"> + <components xsi:type="app:SoftwareComponent" name="image_resize" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1 //@application/@components.2/@exposedInterfaces.1"> + <annotations xsi:type="commons:SProperty" key="source_code" value="path/lambda/function/image_resize.py"/> + <exposedInterfaces name="handle_image"/> + </components> + <components xsi:type="app:SaaS" name="s1"> + <exposedInterfaces name="storage_interface"/> + <exposedInterfaces name="bucket_in"/> + </components> + <components xsi:type="app:SaaS" name="s2"> + <exposedInterfaces name="storage_interface"/> + <exposedInterfaces name="bucket_out"/> + </components> + <components xsi:type="app:SoftwareComponent" name="notification" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1"/> + <components xsi:type="app:SoftwareComponent" name="web" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.1"> + <annotations xsi:type="commons:SProperty" key="source_code" value="path/web_app"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </nodes> + <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1"> + <configs host="//@infrastructure/@nodes.0"/> + </nodes> + <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/> + <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/> + <storages name="st1"/> + <storages name="st2"/> + <faas name="f"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="concrete_vm" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"/> + <storages name="s3_bucket_in" maps="//@infrastructure/@storages.0"> + <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_in"/> + </storages> + <storages name="s3_bucket_out" maps="//@infrastructure/@storages.1"> + <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_out"/> + </storages> + <faas name="concrete_f" maps="//@infrastructure/@faas.0"> + <annotations xsi:type="commons:SProperty" key="lambda_role_name" value="DemoLambdaRole"/> + <annotations xsi:type="commons:SProperty" key="lambda_runtime" value="python3.8"/> + <annotations xsi:type="commons:SProperty" key="lambda_handler" value="image_resize.lambda_handler"/> + <annotations xsi:type="commons:IProperty" key="lambda_timeout" value="5"/> + <annotations xsi:type="commons:IProperty" key="lambda_memory" value="128"/> + </faas> + </providers> + </concretizations> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@faas.0"/> + <deployments component="//@application/@components.4" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@storages.0"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@storages.1"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.1/nginx-aws-ec2.domlx b/tests/doml/v2.1/nginx-aws-ec2.domlx new file mode 100644 index 0000000000000000000000000000000000000000..67ae86db7c8893d91437bd11fe715b7dfd857b4b --- /dev/null +++ b/tests/doml/v2.1/nginx-aws-ec2.domlx @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0" version="v2.1"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="0.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="0.0.0.0/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="config"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/.project b/tests/doml/v2.2/.project new file mode 100644 index 0000000000000000000000000000000000000000..96bcdb7a1076c114a39e5046f8f7d8a1b7c96daa --- /dev/null +++ b/tests/doml/v2.2/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>domlTests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.xtext.ui.shared.xtextBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> + </natures> +</projectDescription> diff --git a/tests/doml/v2.2/faas.doml b/tests/doml/v2.2/faas.doml new file mode 100644 index 0000000000000000000000000000000000000000..9345cc7d776cafd80d1a0af2553202e6f8ea112d --- /dev/null +++ b/tests/doml/v2.2/faas.doml @@ -0,0 +1,177 @@ +doml faas_app + +application ImageResizeApp { + + software_component image_resize { + provides { + handle_image + } + consumes { + storage_interface, + bucket_in, + bucket_out + } + properties { + source_code = "path/lambda/function/image_resize.py"; + } + } + + saas s1 { + provides { + storage_interface + bucket_in + } + } + + saas s2 { + provides { + storage_interface + bucket_out + } + } + + software_component notification { + consumes { + handle_image, + bucket_in + } + } + + software_component web { + consumes { + storage_interface, + bucket_out + } + properties { + source_code = "path/web_app"; + } + } +} + +infrastructure infra { + vm vm1 { + iface i1 { + address "10.0.0.1" + belongs_to vpc + security sg + } + credentials ssh_key + loc { + region "eu-central-1" + } + } + + vm_image v_img { + generates vm1 + image "ami-xxxxxxxxxxxxxxxxx" + } + + container c { + host vm1 + } + + cont_image c_img { + generates c + image "web-app:0.1.0" + } + + faas f { } + + sto st1 { } + + sto st2 { } + + net vpc { + cidr "/24" + protocol "tcp/ip" + subnet vpc_subnet { + cidr "/24" + protocol "tcp/ip" + } + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ec2-user" + keyfile "/tmp/ssh_key_file" + algorithm "RSA" + bits 4096 + } +} + +deployment config1 { + image_resize -> f, + web -> c, + s1 -> st1, + s2 -> st2 +} + +active deployment config1 + +concretizations { + concrete_infrastructure con_infra { + provider aws { + vm concrete_vm { + properties { + instance_type = "t2.micro"; + ssh_key_name = "demo-key"; + ec2_role_name = "demo-ec2-role"; + } + maps vm1 + } + faas concrete_f { + properties { + lambda_role_name = "DemoLambdaRole"; + lambda_runtime = "python3.8"; + lambda_handler = "image_resize.lambda_handler"; + lambda_timeout = 5; + lambda_memory = 128; + } + maps f + } + storage s3_bucket_in { + properties { + bucket_name = "bucket_in"; + } + maps st1 + } + storage s3_bucket_out { + properties { + bucket_name = "bucket_out"; + } + maps st2 + } + net concrete_net { + maps vpc + } + } + } + active con_infra +} \ No newline at end of file diff --git a/tests/doml/v2.2/faas.domlx b/tests/doml/v2.2/faas.domlx new file mode 100644 index 0000000000000000000000000000000000000000..dc83d7135253786f5e7d1fbb9180c0ab1da9e2ca --- /dev/null +++ b/tests/doml/v2.2/faas.domlx @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="faas_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="ImageResizeApp"> + <components xsi:type="app:SoftwareComponent" name="image_resize" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1 //@application/@components.2/@exposedInterfaces.1"> + <annotations xsi:type="commons:SProperty" key="source_code" value="path/lambda/function/image_resize.py"/> + <exposedInterfaces name="handle_image"/> + </components> + <components xsi:type="app:SaaS" name="s1"> + <exposedInterfaces name="storage_interface"/> + <exposedInterfaces name="bucket_in"/> + </components> + <components xsi:type="app:SaaS" name="s2"> + <exposedInterfaces name="storage_interface"/> + <exposedInterfaces name="bucket_out"/> + </components> + <components xsi:type="app:SoftwareComponent" name="notification" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1"/> + <components xsi:type="app:SoftwareComponent" name="web" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.1"> + <annotations xsi:type="commons:SProperty" key="source_code" value="path/web_app"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </nodes> + <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1"> + <configs host="//@infrastructure/@nodes.0"/> + </nodes> + <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/> + <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/> + <storages name="st1"/> + <storages name="st2"/> + <faas name="f"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="concrete_vm" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"/> + <storages name="s3_bucket_in" maps="//@infrastructure/@storages.0"> + <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_in"/> + </storages> + <storages name="s3_bucket_out" maps="//@infrastructure/@storages.1"> + <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_out"/> + </storages> + <faas name="concrete_f" maps="//@infrastructure/@faas.0"> + <annotations xsi:type="commons:SProperty" key="lambda_role_name" value="DemoLambdaRole"/> + <annotations xsi:type="commons:SProperty" key="lambda_runtime" value="python3.8"/> + <annotations xsi:type="commons:SProperty" key="lambda_handler" value="image_resize.lambda_handler"/> + <annotations xsi:type="commons:IProperty" key="lambda_timeout" value="5"/> + <annotations xsi:type="commons:IProperty" key="lambda_memory" value="128"/> + </faas> + </providers> + </concretizations> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@faas.0"/> + <deployments component="//@application/@components.4" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@storages.0"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@storages.1"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/iot_simple_app.doml b/tests/doml/v2.2/iot_simple_app.doml new file mode 100644 index 0000000000000000000000000000000000000000..4dca09ac6ec52afa070731e6942535354b8eb5b4 --- /dev/null +++ b/tests/doml/v2.2/iot_simple_app.doml @@ -0,0 +1,52 @@ +doml iot_simple_app + +application iot_simple_app { + dbms oracle { + provides { sql_interface } + } + + software_component web_server { + provides { sensor_info } + consumes { sql_interface, get_weather } + } + + software_component iot_provider { + consumes { sensor_info } + } + + saas external_meteo { + provides { get_weather @ "https://api.mymeteo.com/get" } + } +} + +infrastructure infra { + vm vm1 {} + vm vm2 {} + node iot_device1 {} + node iot_device2 {} +} + +deployment config1 { + oracle -> vm1, + web_server -> vm2, + iot_provider -> iot_device1, + iot_provider -> iot_device2 +} + +active deployment config1 + +concretizations { + concrete_infrastructure con_infra1 { + provider aws { + vm concrete_vm1 { + properties { instance_type = "t2.micro"; } + maps vm1 + } + vm concrete_vm2 { + properties {} + maps vm2 + } + } + } + active con_infra1 +} \ No newline at end of file diff --git a/tests/doml/v2.2/iot_simple_app.domlx b/tests/doml/v2.2/iot_simple_app.domlx new file mode 100644 index 0000000000000000000000000000000000000000..d750eee5e1487c0b0097e48b3a92453dc3da95d2 --- /dev/null +++ b/tests/doml/v2.2/iot_simple_app.domlx @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="iot_simple_app"> + <components xsi:type="app:DBMS" name="oracle"> + <exposedInterfaces name="sql_interface"/> + </components> + <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0"> + <exposedInterfaces name="sensor_info"/> + </components> + <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/> + <components xsi:type="app:SaaS" name="external_meteo"> + <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/> + </components> + </application> + <infrastructure name="infra"> + <nodes xsi:type="infra:VirtualMachine" name="vm1"/> + <nodes xsi:type="infra:VirtualMachine" name="vm2"/> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"/> + <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"/> + </infrastructure> + <concretizations name="con_infra1"> + <providers name="aws"> + <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0"> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + </vms> + <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/> + </providers> + </concretizations> + <configurations name="config1"> + <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/> + <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/> + <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx-aws-ec2.doml b/tests/doml/v2.2/nginx-aws-ec2.doml new file mode 100644 index 0000000000000000000000000000000000000000..8b1f7635abe55981f613ee869c490d364fd236a0 --- /dev/null +++ b/tests/doml/v2.2/nginx-aws-ec2.doml @@ -0,0 +1,121 @@ +doml nginx_aws_ec2 + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image vm_img { + generates vm1 + image "ami-xxxxxxxxxxxxxxxxx" + } + + net vpc { + cidr "/24" + protocol "tcp/ip" + subnet vpc_subnet { + cidr "/24" + protocol "tcp/ip" + } + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ec2-user" + keyfile "/tmp/ssh_key_file" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + iface i1 { + address "10.0.0.1" + belongs_to vpc + security sg + } + credentials ssh_key + loc { + region "eu-central-1" + } + } + } +} + +deployment conf { + nginx -> vm1 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider aws { + vm ec2_vm { + properties { + vm_name = "nginx-host"; + instance_type = "t2.micro"; + ssh_key_name = "demo-key"; + ec2_role_name = "demo-ec2-role"; + } + maps vm1 + } + + vm_image concrete_vm_image { + maps vm_img + } + + net concrete_net { + properties { + vm_name = "nginx-host"; + } + maps vpc + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 70.0" max 70.0 => "cost"; + req2 "Availability >= 66.5%" min 66.5 => "availability"; + } +} diff --git a/tests/doml/v2.2/nginx-aws-ec2.domlx b/tests/doml/v2.2/nginx-aws-ec2.domlx new file mode 100644 index 0000000000000000000000000000000000000000..14660f0286d3bb24560cccada553c121e06cd4e9 --- /dev/null +++ b/tests/doml/v2.2/nginx-aws-ec2.domlx @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx-csp-compatibility-test.doml b/tests/doml/v2.2/nginx-csp-compatibility-test.doml new file mode 100644 index 0000000000000000000000000000000000000000..5b6d95639a02c7114a1f245150105b38d21579a2 --- /dev/null +++ b/tests/doml/v2.2/nginx-csp-compatibility-test.doml @@ -0,0 +1,132 @@ +doml nginx_aws_ec2 + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image vm_img { + generates vm1 + image "ami-xxxxxxxxxxxxxxxxx" + } + + net vpc { + cidr "/24" + protocol "tcp/ip" + subnet vpc_subnet { + cidr "/24" + protocol "tcp/ip" + } + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ec2-user" + keyfile "/tmp/ssh_key_file" + algorithm "RSA" + bits 4096 + } + + key_pair ed_key { + user "ec2-user" + keyfile "/tmp/ED25519_key_file" + algorithm "ED25519" + } + + autoscale_group ag { + vm vm1 { + arch "x86" + os "RHEL" + cpu_count 128 + mem_mb 512000.0 + + iface i1 { + address "10.0.0.1" + belongs_to vpc + security sg + } + credentials ssh_key + loc { + region "eu-central-1" + } + } + } +} + +deployment conf { + nginx -> vm1 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider aws { + vm ec2_vm { + properties { + vm_name = "nginx-host"; + instance_type = "t2.micro"; + ssh_key_name = "demo-key"; + ec2_role_name = "demo-ec2-role"; + } + maps vm1 + } + + vm_image concrete_vm_image { + maps vm_img + } + + net concrete_net { + properties { + vm_name = "nginx-host"; + } + maps vpc + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 70.0" max 70.0 => "cost"; + req2 "Availability >= 66.5%" min 66.5 => "availability"; + } +} diff --git a/tests/doml/v2.2/nginx-csp-compatibility-test.domlx b/tests/doml/v2.2/nginx-csp-compatibility-test.domlx new file mode 100644 index 0000000000000000000000000000000000000000..a53d27a95dba6e5220fe26fe71d8f72fbe4f5374 --- /dev/null +++ b/tests/doml/v2.2/nginx-csp-compatibility-test.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <credentials xsi:type="commons:KeyPair" name="ed_key" user="ec2-user" keyfile="/tmp/ED25519_key_file" algorithm="ED25519"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" architecture="x86" os="RHEL" memory_mb="512000.0" cpu_count="128" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx_flags.doml b/tests/doml/v2.2/nginx_flags.doml new file mode 100644 index 0000000000000000000000000000000000000000..0434ccafbde78f2ab03c62ff6048cd1d512a8f5e --- /dev/null +++ b/tests/doml/v2.2/nginx_flags.doml @@ -0,0 +1,140 @@ +doml nginx_func_req +version "v2.2" + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image vm_img { + generates vm1 + image "ami-xxxxxxxxxxxxxxxxx" + } + + net vpc { + cidr "/24" + protocol "tcp/ip" + subnet vpc_subnet { + cidr "/24" + protocol "tcp/ip" + } + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ec2-user" + keyfile "/tmp/ssh_key_file" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + iface i1 { + address "10.0.0.1" + belongs_to vpc + security sg + } + credentials ssh_key + loc { + region "eu-central-1" + } + } + } +} + +deployment conf { + nginx -> vm1 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider aws { + vm ec2_vm { + properties { + vm_name = "nginx-host"; + instance_type = "t2.micro"; + ssh_key_name = "demo-key"; + ec2_role_name = "demo-ec2-role"; + } + maps vm1 + } + + vm_image concrete_vm_image { + maps vm_img + } + + net concrete_net { + properties { + vm_name = "nginx-host"; + } + maps vpc + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 70.0" max 70.0 => "cost"; + req2 "Availability >= 66.5%" min 66.5 => "availability"; + } +} + +functional_requirements { +req_ext ``` +%IGNORE vm_has_iface +%CHECK enforce_os_on_vm +%CSP +- "VM must have iface and iface is connected to network" + vm is class abstract.VirtualMachine + and + not exists iface, net ( + vm has abstract.ComputingNode.ifaces iface + and + iface has abstract.NetworkInterface.belongsTo net + + ) + error: "TEST ERROR" + + ```;} diff --git a/tests/doml/v2.2/nginx_flags.domlx b/tests/doml/v2.2/nginx_flags.domlx new file mode 100644 index 0000000000000000000000000000000000000000..740cac9ced98989998d29b322f5ac446612042f4 --- /dev/null +++ b/tests/doml/v2.2/nginx_flags.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" version="v2.2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> + <functionalRequirements name="req_ext" description="```
%IGNORE vm_has_iface
%CHECK enforce_os_on_vm
%CSP
- "VM must have iface and iface is connected to network"
	vm is class abstract.VirtualMachine
	and
	not exists iface, net (
 	vm has abstract.ComputingNode.ifaces iface
 	and
 	iface has abstract.NetworkInterface.belongsTo net
 
 )
 error: "TEST ERROR"
 
 ```"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx_func_req.doml b/tests/doml/v2.2/nginx_func_req.doml new file mode 100644 index 0000000000000000000000000000000000000000..3595366211af53d66fead9a293e9a38c69622bbb --- /dev/null +++ b/tests/doml/v2.2/nginx_func_req.doml @@ -0,0 +1,150 @@ +doml nginx_func_req +version "v2.2" + +application app { + + software_component nginx { + properties { + source_code="/usr/share/nginx/html/index.html"; + } + } +} + +infrastructure infra { + + vm_image vm_img { + generates vm1 + image "ami-xxxxxxxxxxxxxxxxx" + } + + net vpc { + cidr "/24" + protocol "tcp/ip" + subnet vpc_subnet { + cidr "/24" + protocol "tcp/ip" + } + } + + security_group sg { + egress icmp { + from_port -1 + to_port -1 + protocol "icmp" + cidr ["0.0.0.0/0"] + } + ingress http { + from_port 80 + to_port 80 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress https { + from_port 443 + to_port 443 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ingress ssh { + from_port 22 + to_port 22 + protocol "tcp" + cidr ["0.0.0.0/0"] + } + ifaces i1 + } + + key_pair ssh_key { + user "ec2-user" + keyfile "/tmp/ssh_key_file" + algorithm "RSA" + bits 4096 + } + + autoscale_group ag { + vm vm1 { + iface i1 { + address "10.0.0.1" + belongs_to vpc + security sg + } + credentials ssh_key + loc { + region "eu-central-1" + } + } + } +} + +deployment conf { + nginx -> vm1 +} + +active deployment conf + +concretizations { + concrete_infrastructure con_infra { + provider aws { + vm ec2_vm { + properties { + vm_name = "nginx-host"; + instance_type = "t2.micro"; + ssh_key_name = "demo-key"; + ec2_role_name = "demo-ec2-role"; + } + maps vm1 + } + + vm_image concrete_vm_image { + maps vm_img + } + + net concrete_net { + properties { + vm_name = "nginx-host"; + } + maps vpc + } + } + } + active con_infra +} + +optimization opt { + objectives { + "cost" => min + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 70.0" max 70.0 => "cost"; + req2 "Availability >= 66.5%" min 66.5 => "availability"; + } +} + +functional_requirements { +req_ext ``` + +# + "VM must have iface and iface is connected to network" +# forall vm ( +# vm is class abstract.VirtualMachine +# implies +# ( +# vm has abstract.ComputingNode.ifaces iface +# and +# iface has abstract.NetworkInterface.belongsTo net +# ) +# ) +# error: "TEST ERROR" + +- "VM must have iface and iface is connected to network" + vm is class abstract.VirtualMachine + and + not exists iface, net ( + vm has abstract.ComputingNode.ifaces iface + and + iface has abstract.NetworkInterface.belongsTo net + + ) + error: "TEST ERROR" + + ```;} diff --git a/tests/doml/v2.2/nginx_func_req.domlx b/tests/doml/v2.2/nginx_func_req.domlx new file mode 100644 index 0000000000000000000000000000000000000000..aff808cd870eb85a17785aceb7aa0052c58a2cf2 --- /dev/null +++ b/tests/doml/v2.2/nginx_func_req.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" version="v2.2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> + <functionalRequirements name="req_ext" description="```

# + "VM must have iface and iface is connected to network"
# 	forall vm (
# 		vm is class abstract.VirtualMachine
# 	implies
# (
# 	vm has abstract.ComputingNode.ifaces iface
# 	and
# 	iface has abstract.NetworkInterface.belongsTo net
# )
# )
# error: "TEST ERROR"

- "VM must have iface and iface is connected to network"
	vm is class abstract.VirtualMachine
	and
	not exists iface, net (
 	vm has abstract.ComputingNode.ifaces iface
 	and
 	iface has abstract.NetworkInterface.belongsTo net
 
 )
 error: "TEST ERROR"
 
 ```"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx_func_req2_unsat.domlx b/tests/doml/v2.2/nginx_func_req2_unsat.domlx new file mode 100644 index 0000000000000000000000000000000000000000..b05aa09b6d9ade8bc2a8a7c3a240c2296b6d76e4 --- /dev/null +++ b/tests/doml/v2.2/nginx_func_req2_unsat.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> + <functionalRequirements name="req_ext" description="```

 + "VM must have iface and iface is connected to network"
 	forall vm (
 		vm is class abstract.VirtualMachine
 	implies
 (
 	vm has abstract.ComputingNode.ifaces iface
 	and
 	iface has abstract.NetworkInterface.belongsTo net
 )
 )
 error: "TEST ERROR {vm}"
 
 ```"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx b/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx new file mode 100644 index 0000000000000000000000000000000000000000..e577a79eccc03adce5be21f56ce4495894f39b2d --- /dev/null +++ b/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> + <functionalRequirements name="req_ext" description="```

# + "VM must have iface and iface is connected to network"
# 	forall vm (
# 		vm is class abstract.VirtualMachine
# 	implies
# (
# 	vm has abstract.ComputingNode.ifaces iface
# 	and
# 	iface has abstract.NetworkInterface.belongsTo net
# )
# )
# error: "TEST ERROR"

- "VM must have iface and iface is connected to network"
	vm is class abstract.VirtualMachine
	and
	not exists iface, net (
 	vm has abstract.ComputingNode.ifaces iface
 	and
 	iface has abstract.NetworkInterface.belongsTo net
 
 )
 error: "TEST ERROR"
 
 ```"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.2/nginx_func_req_neg.domlx b/tests/doml/v2.2/nginx_func_req_neg.domlx new file mode 100644 index 0000000000000000000000000000000000000000..206a82af3d96c2f2a393981599b26adf6cfd5b94 --- /dev/null +++ b/tests/doml/v2.2/nginx_func_req_neg.domlx @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="ASCII"?> +<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"> + <application name="app"> + <components xsi:type="app:SoftwareComponent" name="nginx"> + <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/> + </components> + </application> + <infrastructure name="infra"> + <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/> + <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/> + <groups xsi:type="infra:AutoScalingGroup" name="ag"> + <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"> + <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/> + <location region="eu-central-1"/> + </machineDefinition> + </groups> + <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443"> + <cidr>0.0.0.0/0</cidr> + </rules> + <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22"> + <cidr>0.0.0.0/0</cidr> + </rules> + </securityGroups> + <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"> + <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/> + </networks> + </infrastructure> + <concretizations name="con_infra"> + <providers name="aws"> + <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/> + <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/> + <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/> + </vms> + <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/> + <networks name="concrete_net" maps="//@infrastructure/@networks.0"> + <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/> + </networks> + </providers> + </concretizations> + <optimization name="opt"> + <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/> + <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost <= 70.0" property="cost" max="70.0"/> + <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/> + </optimization> + <configurations name="conf"> + <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/> + </configurations> + <functionalRequirements name="req_ext" description="```

# + "VM must have iface and iface is connected to network"
# 	forall vm (
# 		vm is class abstract.VirtualMachine
# 	implies
# (
# 	vm has abstract.ComputingNode.ifaces iface
# 	and
# 	iface has abstract.NetworkInterface.belongsTo net
# )
# )
# error: "TEST ERROR"

- "VM must have iface and iface is connected to network"
	vm is class abstract.VirtualMachine
	and
	not exists iface, net (
 	vm has abstract.ComputingNode.ifaces iface
 	and
 	iface has abstract.NetworkInterface.belongsTo net
 
 )
 error: "TEST ERROR"
 
 ```"/> +</commons:DOMLModel> diff --git a/tests/doml/v2.3/UC3_Simplified.doml b/tests/doml/v2.3/UC3_Simplified.doml new file mode 100644 index 0000000000000000000000000000000000000000..93e3e5b0fce02f66bed954c8bb73132d8c779544 --- /dev/null +++ b/tests/doml/v2.3/UC3_Simplified.doml @@ -0,0 +1,294 @@ +doml uc3_openstack + +application app { + + // need to define all sw components of the project this is a placeholder + // need to understand what is really needed in this spec + // need to specify all provides/consumes + + software_component iwg { + provides { net_info } + } + software_component osint { + provides { osint_info } + consumes { net_info, get_twitter, ewcf_rest_interface } + } + software_component ewcf { + provides { ewcf_rest_interface } + consumes { get_firebase } + } + saas external_twitter { + provides { get_twitter @ "https://twitter_api/get" } + } + saas external_firebase { + provides { get_firebase @ "https://firebase_api/get" } + } + +} + +infrastructure infra { + // Giuseppe - tutti devono collegarsi a oam + // Giuseppe - igw deve avere reti oam la net1 verso osint e net2 verso network 5G + + // VMs region + vm igw_vm { + os "Ubuntu-Focal-20.04-Daily-2022-04-19" + size "small" + + iface igw_vm_oam { + belongs_to subnet_oam_igw + } + + iface igw_vm_net1 { + belongs_to subnet_net1_igw + } + + iface igw_vm_net2 { + belongs_to subnet_net2_igw + } + + credentials ssh_key + } + + // Giuseppe - osint deve avere reti oam la net1 verso igw e net3 verso network internet + vm osint_vm { + os "Ubuntu-Focal-20.04-Daily-2022-04-19" + size "small" + + iface osint_vm_oam { + belongs_to subnet_oam_osint + } + + iface osint_vm_net1 { + belongs_to subnet_net1_osint + } + + iface osint_vm_net3 { + belongs_to subnet_net3_osint + } + + credentials ssh_key + } + + // Giuseppe - ewcf deve avere reti oam la net1 verso osint e net3 verso network internet + vm ewcf_vm { + os "Ubuntu-Focal-20.04-Daily-2022-04-19" + size "small" + + iface ewcf_vm_oam { + belongs_to subnet_oam_ewcf + } + + iface ewcf_vm_net1 { + belongs_to subnet_net1_ewcf + } + + iface ewcf_vm_net3 { + belongs_to subnet_net3_ewcf + } + + credentials ssh_key + } + + // Network region + + // Internal Network + net oam { + protocol "TCP/IP" + cidr "16.0.0.0/24" + + subnet subnet_oam_igw { + protocol "TCP/IP" + cidr "16.0.1.0/26" + } + + subnet subnet_oam_osint { + protocol "TCP/IP" + cidr "16.0.1.64/26" + } + + subnet subnet_oam_ewcf { + protocol "TCP/IP" + cidr "16.0.1.128/26" + } + } + + // Internal network + net net1 { + protocol "TCP/IP" + cidr "16.0.1.0/24" + + // Subnets definition + subnet subnet_net1_igw { + connections { + subnet_net1_osint + } + protocol "TCP/IP" + cidr "16.0.1.0/25" + } + + subnet subnet_net1_osint { + connections { + subnet_net1_igw + subnet_net1_ewcf + } + protocol "TCP/IP" + cidr "16.0.1.64/26" + } + + subnet subnet_net1_ewcf { + connections { + subnet_net1_osint + } + protocol "TCP/IP" + cidr "16.0.1.128/26" + } + } + + // Network connecting igw to 5G + net net2 { + protocol "TCP/IP" + cidr "16.0.2.0/24" + + subnet subnet_net2_igw { + protocol "TCP/IP" + cidr "16.0.2.0/25" + } + + gateway net2_igw { + // TODO: Define address + address "16.0.2.22" + } + + } + + // Network connecting osint and ewcf to Internet + net net3 { + protocol "TCP/IP" + cidr "16.0.3.0/24" + + subnet subnet_net3_osint { + protocol "TCP/IP" + cidr "16.0.3.0/25" + } + + subnet subnet_net3_ewcf { + protocol "TCP/IP" + cidr "16.0.3.128/25" + } + + gateway net3_igw { + // TODO: Define address + address "16.0.3.22" + } + } + + // credentials region + key_pair ssh_key { + user "ubuntu" + keyfile "AAAAB3NzaC1yc2EAAAADAQABAAABAQC63ZvocMhX1LsdUlhzqLNSsh/Wotk/EMfDfa9pBHC52NXv05uENTjd/LBj8PS5JXEr7rKG9Zpj2Kj/PA7Gu0X1BZMwAiNR2dKjw9K0HO6Ozj3elCA7WjjotiQcO+OLWefE1PUW8/BJjtjFD/qf6wJd8CwInH8cjpkccQQfA55IXXegQMm5qv2a/S2XBvMMzv1dzsCy5UPO7tiOz4RBfi56JK8o2mDR327yY7+goA0HQz5tSN1X98+vxLpTPD5qINEFfVk1yNmf/ls3C7EBZQFJ6tsHgl070ymdBLHccmDMEYktzBnc/IhNWMq7K4IxwgFfQ7YSzAAqMr1n04+3oUeB" + algorithm "RSA" + bits 4096 + } + + // Security region + + // security group is left as originally defined needs to be updated + security_group sg { + egress icmp { + protocol "ICMP" + from_port -1 + to_port -1 + cidr ["0.0.0.0/0"] + } + ingress http { + protocol "TCP" + from_port 80 + to_port 80 + cidr ["0.0.0.0/0"] + } + ingress https { + protocol "TCP" + from_port 443 + to_port 443 + cidr ["0.0.0.0/0"] + } + ingress ssh { + protocol "TCP" + from_port 22 + to_port 22 + cidr ["0.0.0.0/0"] + } + + ifaces igw_vm_oam, igw_vm_net1, igw_vm_net2, osint_vm_oam, osint_vm_net1, osint_vm_net3, ewcf_vm_oam, ewcf_vm_net1, ewcf_vm_net3 + } +} + +deployment config1 { + osint -> osint_vm, + iwg -> igw_vm, + ewcf -> ewcf_vm +} + +active deployment config1 + +concretizations { + concrete_infrastructure con_infra { + + provider openstack { + + // Concrete computing nodes region + + vm concrete_osint_vm { + maps osint_vm + } + + vm concrete_igw_vm { + maps igw_vm + } + + vm concrete_ewcf_vm { + maps ewcf_vm + } + + // Concrete Network region + net concrete_oam { + maps oam + } + + net concrete_net1 { + maps net1 + } + + net concrete_net2 { + maps net2 + } + + net concrete_net3 { + maps net3 + } + + } + } + active con_infra +} + +// It's currently not possible to provide "storage" for OPEN provider (IOP) +// req4 "elements" => "VM, storage"; +// Required performance was too much (70%), modified after talking with Eneko + +optimization opt { + + objectives { + "cost" => min + "performance" => max + "availability" => max + } + nonfunctional_requirements { + req1 "Cost <= 300" max 300.0 => "cost"; + req2 "Performance >= 7%" min 7.0 => "performance"; + req3 "Provider" values "OPEN" => "provider"; + req4 "elements" => "VM, VM, VM"; + } + +} \ No newline at end of file diff --git a/tests/domlr/example_multiple_reqs.domlr b/tests/domlr/example_multiple_reqs.domlr new file mode 100644 index 0000000000000000000000000000000000000000..451857494997fd31bd458e29b6c09d8c19021338 --- /dev/null +++ b/tests/domlr/example_multiple_reqs.domlr @@ -0,0 +1,52 @@ +- "VM must have iface" + vm is class infrastructure.VirtualMachine + and + not exists iface ( + vm has infrastructure.ComputingNode.ifaces iface + ) + + error: "VM {vm} must have iface {iface}" + +# + "VM must have iface" +# forall vm ( +# vm is class infrastructure.VirtualMachine +# implies +# exists iface ( +# vm has infrastructure.ComputingNode.ifaces iface +# ) +# ) + +# error: "VM {vm} must have iface {iface}" + ++ "VM must have cpu_count >= 4" + forall vm ( + vm is class infrastructure.VirtualMachine + implies + vm has infrastructure.ComputingNode.cpu_count >= 4 + ) + + error: "VM {vm} must have cpu_count >= 4 {iface}" + ++ "VM must have os == 'rhel8'" + forall vm ( + vm is class infrastructure.VirtualMachine + implies + vm has infrastructure.ComputingNode.os == "rhel8" + ) + + error: "VM {vm} must have os == 'rhel'" + +# OLD SYNTAX: +# - "Iface must be unique" +# ni1 has infrastructure.NetworkInterface.endPoint Value +# and +# ni1 is not ni2 +# and +# ni2 has infrastructure.NetworkInterface.endPoint Value + +- "Iface must be unique" + ni1 has infrastructure.NetworkInterface.endPoint == ni2 infrastructure.NetworkInterface.endPoint + and + ni1 is not ni2 + + error: "Iface {ni1} and {ni2} must have different values" diff --git a/tests/domlr/example_single_req.domlr b/tests/domlr/example_single_req.domlr new file mode 100644 index 0000000000000000000000000000000000000000..a3e87f406f7802d20ad1964591d49b2b7cad0210 --- /dev/null +++ b/tests/domlr/example_single_req.domlr @@ -0,0 +1,18 @@ +# vm, iface = get_consts(smtsorts, ["vm", "iface"]) +# return And( +# smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], +# Not( +# Exists( +# [iface], +# ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) +# ) +# ) +# ) + +- "All VMs have at least one interface 1" + vm is class infrastructure.VirtualMachine + and + not exists iface ( + vm has abstract.ComputingNode.ifaces iface + ) + error: "VM {vm} has no associated interface." diff --git a/tests/domlr/example_single_req_bad_syntax.domlr b/tests/domlr/example_single_req_bad_syntax.domlr new file mode 100644 index 0000000000000000000000000000000000000000..195f5b49205d9368e0245a3d17334cda7a765ef9 --- /dev/null +++ b/tests/domlr/example_single_req_bad_syntax.domlr @@ -0,0 +1,21 @@ +# vm, iface = get_consts(smtsorts, ["vm", "iface"]) +# return And( +# smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], +# Not( +# Exists( +# [iface], +# ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) +# ) +# ) +# ) + ++ "All VMs have at least one interface 1" + vm is class infrastructure.VirtualMachine + and + not exists iface ( + vm has infrastructure.ComputingNode.ifaces iface + and + vm has infrastructure.ComputingNode.ifaces X + ) + --- + "VM {vm} has no associated interface." diff --git a/tests/domlr/example_single_req_qty_comparison.domlr b/tests/domlr/example_single_req_qty_comparison.domlr new file mode 100644 index 0000000000000000000000000000000000000000..9d7029dcc1b145e2d62a8885e81f3fc1aa564de7 --- /dev/null +++ b/tests/domlr/example_single_req_qty_comparison.domlr @@ -0,0 +1,35 @@ +# vm, iface = get_consts(smtsorts, ["vm", "iface"]) +# return And( +# smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], +# Not( +# Exists( +# [iface], +# ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) +# ) +# ) +# ) + +# OLD SYNTAX +# + "All VMs have at least 512 MB of memory" +# forall vm ( +# vm is class infrastructure.VirtualMachine +# implies +# ( +# vm has abstract.ComputingNode.memory_mb Mem +# and +# Mem < 512 +# ) +# ) + +# --- +# "All VMs have at least 256 MB of memory" + ++ "All VMs have at least 512 MB of memory" + forall vm ( + vm is class infrastructure.VirtualMachine + implies + vm has abstract.ComputingNode.memory_mb >= 512 + + ) + + error: "All VMs have at least 256 MB of memory" \ No newline at end of file diff --git a/tests/domlr/example_single_req_v3.0.domlr b/tests/domlr/example_single_req_v3.0.domlr new file mode 100644 index 0000000000000000000000000000000000000000..8adb15392a464475797d6f33a5b05781b3c7f044 --- /dev/null +++ b/tests/domlr/example_single_req_v3.0.domlr @@ -0,0 +1,18 @@ +# vm, iface = get_consts(smtsorts, ["vm", "iface"]) +# return And( +# smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"], +# Not( +# Exists( +# [iface], +# ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface) +# ) +# ) +# ) + +- "All VMs have at least one interface 1" + vm is class infrastructure.VirtualMachine + and + not exists iface ( + vm has abstract.Node.ifaces iface + ) + error: "VM {vm} has no associated interface." diff --git a/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr b/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr new file mode 100644 index 0000000000000000000000000000000000000000..c48e812e1f15ed1a38e473fb56baf6e970b38fab --- /dev/null +++ b/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr @@ -0,0 +1,9 @@ ++ "VM has size description and cpu_count >= 4" + forall vm ( + vm is class infrastructure.VirtualMachine + implies + vm has infrastructure.VirtualMachine.sizeDescription == "EXAMPLE" + and + vm has infrastructure.ComputingNode.cpu_count >= 4 + ) + error: "Model is wrong..." \ No newline at end of file diff --git a/tests/test_mc_openapi.py b/tests/test_mc_openapi.py index 66c7a77e5f86170fd2c4ac1c6cd3321e0dd6d7fb..7fd2ca595b95d1ffd82243a2f879d891eaa7388d 100644 --- a/tests/test_mc_openapi.py +++ b/tests/test_mc_openapi.py @@ -1,39 +1,104 @@ from mc_openapi import __version__ +from mc_openapi.doml_mc.common_reqs import CommonRequirements +from mc_openapi.doml_mc import DOMLVersion import requests +# V2_0 tests +def test_post_nginx_sat_V2_0(): + with open("tests/doml/v2.0/nginx-openstack_v2.0.domlx", "r") as f: + doml = f.read() -def test_version(): - assert __version__ == '0.2.0' + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) + payload = r.json() + assert r.status_code == requests.codes.ok + assert payload["result"] is not None + assert payload["result"] == "sat" -def test_post_nginx_sat(): - with open("tests/doml/nginx-openstack_v2.domlx", "r") as f: +def test_post_faas_unsat_V2_0(): + with open("tests/doml/v2.0/faas.domlx", "r") as f: doml = f.read() - r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml) + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) payload = r.json() assert r.status_code == requests.codes.ok assert payload["result"] is not None - assert payload["result"] == "sat" + assert payload["result"] == "unsat" + +def test_post_common_reqs_V2_0(): + check_strings = [ + "is not connected to any network interface.", + "but they are deployed to nodes that cannot communicate through a common network.", + "share the same IP address.", + "is not deployed to any abstract infrastructure node.", + "is not mapped to any element in the active concretization.", + "is not mapped to any abstract infrastructure element." + ] -def test_post_nginx_unsat(): - with open("tests/doml/nginx-openstack_v2_wrong.domlx", "r") as f: + for req, err_desc in zip(CommonRequirements[DOMLVersion.V2_0].get_all_requirements(), check_strings): + with open(f"tests/doml/v2.0/nginx-openstack_v2.0_wrong_{req.assert_name}.domlx", "r") as f: + doml = f.read() + + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) + payload = r.json() + assert r.status_code == requests.codes.ok + assert payload["result"] is not None + assert payload["result"] == "unsat" + assert err_desc in payload["description"] + + +# V2_1 tests +def test_post_nginx_sat_V2_1(): + with open("tests/doml/v2.1/nginx-aws-ec2.domlx", "r") as f: doml = f.read() - r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml) + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) + payload = r.json() + assert r.status_code == requests.codes.ok + assert payload["result"] is not None + assert payload["result"] == "unsat" # it was sat before req change + + +def test_post_faas_unsat_V2_1(): + with open("tests/doml/v2.1/faas.domlx", "r") as f: + doml = f.read() + + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) payload = r.json() assert r.status_code == requests.codes.ok assert payload["result"] is not None assert payload["result"] == "unsat" +# V2_2 tests +def test_post_nginx_sat_V2_1(): + with open("tests/doml/v2.2/nginx-aws-ec2.domlx", "r") as f: + doml = f.read() + + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) + payload = r.json() + assert r.status_code == requests.codes.ok + assert payload["result"] is not None + assert payload["result"] == "unsat" # it was sat before req change + -def test_post_faas_sat(): - with open("tests/doml/faas.domlx", "r") as f: +def test_post_faas_unsat_V2_2(): + with open("tests/doml/v2.2/faas.domlx", "r") as f: doml = f.read() - r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml) + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) payload = r.json() assert r.status_code == requests.codes.ok assert payload["result"] is not None assert payload["result"] == "unsat" + + +def test_post_nginx_with_func_reqs_unsat_V2_2(): + with open("tests/doml/v2.2/nginx_func_req.domlx", "r") as f: + doml = f.read() + + r = requests.post("http://0.0.0.0:80/modelcheck", data=doml) + payload = r.json() + assert r.status_code == requests.codes.ok + assert payload["result"] is not None + assert payload["result"] == "unsat" # it was sat before req change \ No newline at end of file diff --git a/tests/test_modelchecker.py b/tests/test_modelchecker.py new file mode 100644 index 0000000000000000000000000000000000000000..f62315b1d524f54fae13e10a9ba0f03250c505d9 --- /dev/null +++ b/tests/test_modelchecker.py @@ -0,0 +1,70 @@ +from importlib.resources import files +from mc_openapi.doml_mc import init_model, verify_model +from pathlib import Path + +from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion + +doml_test_dir = files(package='tests') / 'doml' + +def run(src, ver): + dmc = init_model(src, ver) + return verify_model(dmc) + +def test_domlx_models_by_version(subtests): + i = 0 + for doml_ver_dir in [ver for ver in doml_test_dir.iterdir() if ver.name != 'CaseStudies']: + doml_ver = doml_ver_dir.name + domlx_files = [f for f in doml_ver_dir.iterdir() if f.is_file() and f.name.endswith('.domlx')] + for domlx in domlx_files: + with open(domlx, "rb") as f: + domlx_file = f.read() + assert_ver = DOMLVersion.get(doml_ver) + assert_result = None + try: + assert_result = OUTPUT[doml_ver][domlx.name] + i += 1 + except: + pass + if assert_result: + with subtests.test(msg=f"{doml_ver}/{domlx.name}", i=i): + res = run(domlx_file, assert_ver) + assert assert_result == res['result'] + assert assert_ver.name == res['doml_version'] + +OUTPUT = { + 'v2.0': { + 'faas.domlx': 'unsat', + 'nginx-openstack_v2.0.domlx': 'sat', + 'nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx': 'unsat', + 'nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx': 'unsat', + 'nginx-openstack_v2.0_wrong_iface_uniq.domlx': 'unsat', + 'nginx-openstack_v2.0_wrong_software_package_iface_net.domlx': 'unsat', + 'nginx-openstack_v2.0_valid_mem_req.domlx': 'sat', + 'nginx-openstack_v2.0_wrong_nginx_source_code.domlx': 'sat', + 'openstack_template.domlx': 'unsat', + 'saas.domlx': 'sat', + 'saas_https_no_attrs.domlx': 'sat', + 'saas_no_https_rule.domlx': 'sat', + 'saas_wrong_no_iface_sg.domlx': 'sat', + 'nginx-openstack_v2.0_wrong_vm_has_iface.domlx': 'unsat', + 'nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx': 'unsat' + }, + 'v2.1': { + 'faas.domlx': 'unsat', + 'nginx-aws-ec2.domlx': 'sat' + }, + 'v2.2': { + 'faas.domlx': 'unsat', + 'iot_simple_app.domlx': 'unsat', + 'nginx-aws-ec2.domlx': 'unsat', # was sat before concrete_asg_no_vm req + 'nginx_func_req2_unsat.domlx': 'unsat', + 'nginx_func_req2_unsat_neg.domlx': 'unsat', + 'nginx_func_req_neg.domlx': 'unsat', # ditto + 'nginx-csp-compatibility-test.domlx': 'unsat', # ditto + 'nginx_func_req.domlx': 'unsat', # ditto + 'nginx_flags.domlx': 'unsat' # ditto + }, + 'v2.3': { + + }, +} \ No newline at end of file diff --git a/uwsgi_config.yaml b/uwsgi_config.yaml deleted file mode 100644 index 7870e5aba1235d6c08655f8c4230465faa7d1813..0000000000000000000000000000000000000000 --- a/uwsgi_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -uwsgi: - strict: true - master: true - workers: 4 - http-timeout: 120 - module: mc_openapi.app_config - enable-threads: true - threads: 2 - single-interpreter: true - need-app: true - thunder-lock: true