From 3df4f6d28c1660231d9fc2039b9d9e41d3ab6c85 Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov <onegreyonewhite@mail.ru> Date: Tue, 6 Dec 2022 14:23:07 +1000 Subject: [PATCH 1/8] Feature(git): Provide to setup config params for git operations + werf build images. --- .gitlab-ci.yml | 18 +++++++++++------- docker-compose.yml | 2 +- polemarch/main/repo/vcs.py | 12 ++++++++++-- polemarch/main/settings.py | 7 ++++++- requirements.txt | 2 +- setup.py | 4 ++++ tests.py | 5 +++++ werf-giterminism.yaml | 4 ++++ werf.yaml | 17 +++++++++++++++++ 9 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 werf-giterminism.yaml create mode 100644 werf.yaml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 418969fc..b0a541de 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -157,15 +157,19 @@ release_pypi: publish_docker: stage: publish - image: vstconsulting/images:ubuntu - services: - - name: 'docker:19.03-dind' - alias: 'docker_service_host' + image: registry.werf.io/werf/werf + before_script: + - type werf && source $(werf ci-env gitlab --as-file) + - werf version script: - - pip install tox - - tox -e release-docker + - werf cr login -u $POLEMARCH_DOCKER_USER -p $POLEMARCH_DOCKER_PASSWORD index.docker.io + - werf export --repo=$WERF_REPO/storage --tag=$WERF_REPO:$CI_COMMIT_TAG --tag=index.docker.io/$POLEMARCH_DOCKER_IMAGE_NAME:$CI_COMMIT_TAG + - werf export --repo=$WERF_REPO/storage --tag=$WERF_REPO:latest --tag=index.docker.io/$POLEMARCH_DOCKER_IMAGE_NAME:latest + after_script: + - werf cr login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${CI_REGISTRY} + - werf cleanup --repo=$WERF_REPO/storage rules: - - if: '$CI_COMMIT_TAG && $POLEMARCH_DOCKER_USER && $POLEMARCH_DOCKER_PASSWORD && $POLEMARCH_DOCKER_IMAGE_NAME' + - if: '$CI_COMMIT_TAG && $POLEMARCH_DOCKER_USER && $POLEMARCH_DOCKER_PASSWORD && $POLEMARCH_DOCKER_IMAGE_NAME && $WERF_IMAGES_CLEANUP_PASSWORD' when: on_success - when: never diff --git a/docker-compose.yml b/docker-compose.yml index 65e0b232..bcdec15c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,7 @@ services: - "8080:80" polemarch: - image: polemarch + image: ${WERF_MAIN_DOCKER_IMAGE_NAME:-polemarch} build: . restart: unless-stopped depends_on: diff --git a/polemarch/main/repo/vcs.py b/polemarch/main/repo/vcs.py index a09e2c22..06fffa9c 100644 --- a/polemarch/main/repo/vcs.py +++ b/polemarch/main/repo/vcs.py @@ -14,6 +14,8 @@ class _VCS(_Base): # nocv + __slots__ = () + def vcs_clone(self, *args, **kwargs): raise NotImplementedError() @@ -25,7 +27,7 @@ def get_repo(self, *args, **kwargs): class Git(_VCS): - __slots__ = ('env', '_fetch_map',) + __slots__ = ('env', '_fetch_map', 'target_branch', 'persistent_config_options') _fetch_statuses = [ "NEW_TAG", "NEW_HEAD", "HEAD_UPTODATE", @@ -43,13 +45,17 @@ class Git(_VCS): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.env = self.options.get("GIT_ENV", {}) + self.persistent_config_options = self.options.get("CONFIG_LIST", ()) self._fetch_map = { 1 << x: self._fetch_statuses[x] for x in range(8) } self.target_branch = self.proj.vars.get('repo_branch', None) def get_repo(self) -> git.Repo: - return git.Repo(self.path) + repo = git.Repo(self.path) + if self.persistent_config_options: + repo.git.set_persistent_git_options(c=self.persistent_config_options) + return repo def vcs_clone(self, source: str, destination, **kwargs) -> git.Repo: os.makedirs(destination) @@ -60,6 +66,8 @@ def vcs_clone(self, source: str, destination, **kwargs) -> git.Repo: **kwargs ) repo = git.Repo(destination) + if self.persistent_config_options: + repo.git.set_persistent_git_options(c=self.persistent_config_options) with repo.git.custom_environment(**kwargs.get('env', {})): self._update_submodules(repo, kill_after_timeout=kwargs.get('kill_after_timeout')) except git.GitCommandError as error: diff --git a/polemarch/main/settings.py b/polemarch/main/settings.py index a8c717fd..3cdd29f0 100644 --- a/polemarch/main/settings.py +++ b/polemarch/main/settings.py @@ -176,9 +176,10 @@ class ArchiveSection(BaseAppendSection): git_fetch = {} git_clone = {} +git_config_list = () if TESTS_RUN: - config['git'] = dict(fetch=dict(), clone=dict()) + config['git'] = dict(fetch={}, clone={}, config={'protocol.file.allow': 'always'}) if 'git' in config: git = config['git'] @@ -189,6 +190,9 @@ class ArchiveSection(BaseAppendSection): if 'clone' in git: git_clone = GitCloneSection('git.clone', config, git['clone']).all() + if 'config' in git: + git_config_list = tuple(f'{k}={v}' for k, v in git['config'].items()) + archive_section = ArchiveSection('archive', config, config['archive']).all() @@ -230,6 +234,7 @@ class PluginOptionsSection(PluginSection): "OPTIONS": { "CLONE_KWARGS": git_clone, "FETCH_KWARGS": git_fetch, + "CONFIG_LIST": git_config_list, "GIT_ENV": { "GLOBAL": { "GIT_SSL_NO_VERIFY": "true" diff --git a/requirements.txt b/requirements.txt index 906635b4..77bc5f0d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Main -vstutils[rpc,ldap,doc,prod]~=5.1.11 +vstutils[rpc,doc,prod]~=5.1.11 docutils~=0.16.0 markdown2~=2.4.0 diff --git a/setup.py b/setup.py index b1c5165f..d56faca3 100644 --- a/setup.py +++ b/setup.py @@ -388,6 +388,10 @@ def make_setup(**opts): ext_list = [] install_requirements = load_requirements('requirements.txt', os.getcwd()) +install_requirements = [ + i.replace('prod', 'prod,ldap') if isinstance(i, str) and i.strip().startswith('vstutils') else i + for i in install_requirements +] kwargs = dict( name='polemarch', diff --git a/tests.py b/tests.py index 318ad032..11e9253e 100644 --- a/tests.py +++ b/tests.py @@ -906,6 +906,7 @@ def test_sync_git(self, temp_dir): submodule = git.Repo.init(submodule_dir) submodule.git.add('test_module.py') submodule.index.commit('Add module') + repo.git.set_persistent_git_options(c='protocol.file.allow=always') repo.git.submodule('add', '../submodule/.git', 'lib') repo.git.submodule('add', f'{submodule_dir}/.git', 'lib2') repo.git.add(all=True) @@ -1746,6 +1747,8 @@ def test_repo_sync_on_run_for_git_project(self, temp_dir): submodule = git.Repo.init(submodule_dir) submodule.git.add('test_module.py') submodule.index.commit('Add module') + submodule.git.set_persistent_git_options(c='protocol.file.allow=always') + repo.git.set_persistent_git_options(c='protocol.file.allow=always') repo.git.submodule('add', '../submodule/.git', 'lib') repo.git.submodule('add', f'{submodule_dir}/.git', 'lib2') @@ -1888,6 +1891,8 @@ def do_GET(self, *args, **kwargs): submodule = git.Repo.init(submodule_dir) submodule.git.add('test_module.py') submodule.index.commit('Add module') + submodule.git.set_persistent_git_options(c='protocol.file.allow=always') + repo.git.set_persistent_git_options(c='protocol.file.allow=always') repo.git.submodule('add', '../submodule/.git', 'lib') repo.git.submodule('add', f'{submodule_dir}/.git', 'lib2') diff --git a/werf-giterminism.yaml b/werf-giterminism.yaml new file mode 100644 index 00000000..87129a5e --- /dev/null +++ b/werf-giterminism.yaml @@ -0,0 +1,4 @@ +giterminismConfigVersion: 1 +helm: + allowUncommittedFiles: + - ../**/* diff --git a/werf.yaml b/werf.yaml new file mode 100644 index 00000000..bbc1d26b --- /dev/null +++ b/werf.yaml @@ -0,0 +1,17 @@ +configVersion: 1 +project: polemarch +cleanup: + disableKubernetesBasedPolicy: true + disableGitHistoryBasedPolicy: true + disableBuiltWithinLastNHoursPolicy: true + keepImagesBuiltWithinLastNHours: 1 + keepPolicies: + - references: + branch: /.*/ + limit: + last: 1 + +--- +image: main +dockerfile: Dockerfile +context: . From 989acd09fc2e44cef18cabc66aac683e511ffc77 Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov <onegreyonewhite@mail.ru> Date: Wed, 7 Dec 2022 14:38:50 +1000 Subject: [PATCH 2/8] Chore: Use schema field inspection for inventory field. --- .gitlab-ci.yml | 18 ++++++++++++++---- doc/api_schema.yaml | 19 +++++++++++-------- polemarch/__init__.py | 2 +- polemarch/api/schema.py | 29 +++++++++++++++++++++++++++++ polemarch/api/v2/serializers.py | 12 ++++++++++++ polemarch/main/openapi.py | 2 -- polemarch/main/settings.py | 1 + tox.ini | 2 +- 8 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 polemarch/api/schema.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b0a541de..d9ceb130 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,6 +51,16 @@ stages: when: on_success - when: never + +.js_tests_template: &branch_js_tests + <<: *branch_tests + image: vstconsulting/images:node + before_script: + - yarn install + script: + - yarn test + + # Branch tests ########################################### code_style: @@ -60,12 +70,12 @@ code_style: TOX_ENVS: "flake,pylint" js_style: - <<: *branch_tests + <<: *branch_js_tests stage: code_standarts - variables: - TOX_ENVS: "js_style" + script: + - yarn lint -py38-coverage: +py311-coverage: <<: *branch_tests variables: TOX_ENVS: "$CI_BUILD_NAME" diff --git a/doc/api_schema.yaml b/doc/api_schema.yaml index 3f7b4454..9628f948 100644 --- a/doc/api_schema.yaml +++ b/doc/api_schema.yaml @@ -24,9 +24,9 @@ info: url: https://gitlab.com/vstconsulting/polemarch.git Request: - name: Question - url: https://gitlab.com/vstconsulting/polemarch/issues/new?issuable_template%5D=Ask&issue%5Btitle%5D=Ask%20about%20version%202.1.2 + url: https://gitlab.com/vstconsulting/polemarch/issues/new?issuable_template%5D=Ask&issue%5Btitle%5D=Ask%20about%20version%202.3.0 - name: Bug report - url: https://gitlab.com/vstconsulting/polemarch/issues/new?issuable_template%5D=Bug&issue%5Btitle%5D=Bug%20in%20version%202.1.2 + url: https://gitlab.com/vstconsulting/polemarch/issues/new?issuable_template%5D=Bug&issue%5Btitle%5D=Bug%20in%20version%202.3.0 - name: Feature request url: https://gitlab.com/vstconsulting/polemarch/issues/new?issuable_template%5D=Feature%20request&issue%5Btitle%5D= x-menu: @@ -67,9 +67,9 @@ info: login_url: /account/login/ x-subscriptions-prefix: polemarch.update x-versions: - application: 2.1.2 - library: 2.1.2 - vstutils: 5.1.10 + application: 2.3.0 + library: 2.3.0 + vstutils: 5.1.11 django: 3.2.16 djangorestframework: 3.14.0 drf_yasg: 1.21.4 @@ -10879,8 +10879,9 @@ definitions: inventory: title: Inventory type: integer - x-nullable: true format: inventory + readOnly: true + x-nullable: true kind: title: Kind type: string @@ -10996,8 +10997,9 @@ definitions: inventory: title: Inventory type: integer - x-nullable: true format: inventory + readOnly: true + x-nullable: true kind: title: Kind type: string @@ -13333,8 +13335,9 @@ definitions: inventory: title: Inventory type: integer - x-nullable: true format: inventory + readOnly: true + x-nullable: true kind: title: Kind type: string diff --git a/polemarch/__init__.py b/polemarch/__init__.py index 62ff2623..0946948f 100644 --- a/polemarch/__init__.py +++ b/polemarch/__init__.py @@ -31,6 +31,6 @@ "VST_ROOT_URLCONF": os.getenv("VST_ROOT_URLCONF", 'vstutils.urls'), } -__version__ = "2.2.0" +__version__ = "2.3.0" prepare_environment(**default_settings) diff --git a/polemarch/api/schema.py b/polemarch/api/schema.py new file mode 100644 index 00000000..72a5887d --- /dev/null +++ b/polemarch/api/schema.py @@ -0,0 +1,29 @@ +from drf_yasg.inspectors.base import FieldInspector, NotHandled +from drf_yasg import openapi +from vstutils.api.schema.schema import VSTAutoSchema +from vstutils.api.schema.inspectors import field_extra_handler + +from .v2.serializers import InventoryAutoCompletionField + + +class InventoryFieldInspector(FieldInspector): + def field_to_swagger_object(self, field, swagger_object_type, use_references, **kw): + # pylint: disable=invalid-name + if not isinstance(field, InventoryAutoCompletionField): + return NotHandled + + SwaggerType, _ = self._get_partial_types( + field, swagger_object_type, use_references, **kw + ) + kwargs = { + 'type': openapi.TYPE_INTEGER if field.real_type == int else openapi.TYPE_STRING, + 'format': 'inventory' + } + + return SwaggerType(**field_extra_handler(field, **kwargs)) + + +class PolemarchAutoSchema(VSTAutoSchema): + field_inspectors = [ + InventoryFieldInspector, + ] + VSTAutoSchema.field_inspectors diff --git a/polemarch/api/v2/serializers.py b/polemarch/api/v2/serializers.py index a8da8a20..f53315aa 100644 --- a/polemarch/api/v2/serializers.py +++ b/polemarch/api/v2/serializers.py @@ -68,6 +68,9 @@ def to_representation(self, value): class InventoryAutoCompletionField(vst_fields.VSTCharField): + def __init__(self, **kwargs): + self.real_type = kwargs.pop('real_type', str) + super().__init__(**kwargs) def to_internal_value(self, data): inventory = super().to_internal_value(data) @@ -83,6 +86,14 @@ def to_internal_value(self, data): path_validator(inventory) return inventory + def to_representation(self, value): + if self.real_type == int: + if isinstance(value, models.Inventory): + return value.id + elif isinstance(value, int): # nocv + return value + return super().to_representation(value) + # Serializers class FactsSerializer(DataSerializer): @@ -209,6 +220,7 @@ class Meta: class HistorySerializer(_SignalSerializer): + inventory = InventoryAutoCompletionField(allow_null=True, read_only=True, real_type=int) status = serializers.ChoiceField(choices=models.History.statuses, required=False) executor = vst_fields.DependEnumField(field='initiator_type', types={ 'project': vst_fields.FkModelField(select=UserSerializer, diff --git a/polemarch/main/openapi.py b/polemarch/main/openapi.py index 7fab0664..bbcb68c6 100644 --- a/polemarch/main/openapi.py +++ b/polemarch/main/openapi.py @@ -71,8 +71,6 @@ def set_inventory(model): for type_field in field['x-options']['types'].values(): if isinstance(type_field, dict): type_field['format'] = 'inventory' - else: - field['format'] = 'inventory' elif field.get('format') == 'dynamic': for type_field in field['x-options']['types'].values(): diff --git a/polemarch/main/settings.py b/polemarch/main/settings.py index 3cdd29f0..bc14e2ba 100644 --- a/polemarch/main/settings.py +++ b/polemarch/main/settings.py @@ -77,6 +77,7 @@ ] SWAGGER_SETTINGS['DEFAULT_INFO'] = '{}.api.v2.swagger.api_info'.format(VST_PROJECT_LIB_NAME) +SWAGGER_SETTINGS['DEFAULT_AUTO_SCHEMA_CLASS'] = '{}.api.schema.PolemarchAutoSchema'.format(VST_PROJECT_LIB_NAME) OPENAPI_EXTRA_LINKS = dict() OPENAPI_EXTRA_LINKS['Request'] = [ diff --git a/tox.ini b/tox.ini index 8b2db20d..7a19f557 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = flake,pylint,py36-coverage,py38-install +envlist = flake,pylint,py311-coverage,py36-install skipsdist = True setenv = PIP_CONFIG_FILE=.pip.conf whitelist_externals = From 74055f1540d89bd95f71d78973a2219904706829 Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov <onegreyonewhite@mail.ru> Date: Fri, 9 Dec 2022 18:24:44 +0400 Subject: [PATCH 3/8] Fix(CI): Migrate to new images. --- .gitlab-ci.yml | 16 ++++++++-------- tox.ini | 22 +++++++++++----------- tox_build.ini | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9ceb130..c830fe1c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ # set to local images because too long execution default: - image: vstconsulting/images:build + image: registry.gitlab.com/vstconsulting/images:build variables: GET_SOURCES_ATTEMPTS: 3 @@ -34,7 +34,7 @@ stages: ########################################### .branch_tests_template: &branch_tests stage: test - image: vstconsulting/images:tox + image: registry.gitlab.com/vstconsulting/images:tox coverage: '/\d+\%\s*$/' variables: TOX_ENVS: "" @@ -54,7 +54,7 @@ stages: .js_tests_template: &branch_js_tests <<: *branch_tests - image: vstconsulting/images:node + image: registry.gitlab.com/vstconsulting/images:node-tests before_script: - yarn install script: @@ -89,7 +89,7 @@ py36-install: ########################################### #deploy_environment: # stage: release -# image: vstconsulting/images:tox +# image: registry.gitlab.com/vstconsulting/images:tox # services: # - name: "docker:19.03-dind" # alias: "docker_service_host" @@ -107,7 +107,7 @@ py36-install: # #delete_environment: # stage: release -# image: vstconsulting/images:tox +# image: registry.gitlab.com/vstconsulting/images:tox # script: # - tox -e destroy_env # environment: @@ -121,7 +121,7 @@ py36-install: release: stage: release - image: vstconsulting/images:tox + image: registry.gitlab.com/vstconsulting/images:tox rules: - if: '$CI_COMMIT_BRANCH == "master" && $GIT_ACCESS_USER && $GIT_ACCESS_PASSWORD' when: on_success @@ -149,7 +149,7 @@ pages: release_pypi: stage: release - image: vstconsulting/images:build + image: registry.gitlab.com/vstconsulting/images:build rules: - if: '$CI_COMMIT_TAG && $PYPI_UPLOAD_PASSWORD && $PYPI_UPLOAD_NAME' when: on_success @@ -185,7 +185,7 @@ publish_docker: publish_release: stage: publish - image: vstconsulting/images:tox + image: registry.gitlab.com/vstconsulting/images:tox allow_failure: true needs: ["release_pypi"] rules: diff --git a/tox.ini b/tox.ini index 7a19f557..16490e08 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = flake,pylint,py311-coverage,py36-install skipsdist = True setenv = PIP_CONFIG_FILE=.pip.conf -whitelist_externals = +allowlist_externals = rm bash @@ -17,7 +17,7 @@ passenv = DJANGO_LOG_LEVEL CC BUILD_COMPILE -whitelist_externals = +allowlist_externals = rm ls ln @@ -73,7 +73,7 @@ commands = [testenv:js_style] changedir = ./ deps = -whitelist_externals = yarn +allowlist_externals = yarn commands = yarn install yarn lint @@ -85,7 +85,7 @@ setenv = LANG = en_US.UTF-8 passenv = * changedir = . -whitelist_externals = +allowlist_externals = tox rm commands = @@ -98,7 +98,7 @@ changedir = ./doc/ setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 -whitelist_externals = +allowlist_externals = cp make commands = @@ -115,7 +115,7 @@ setenv = BUILD_OPTIMIZATION = true BUILD_COMPILE = true passenv = * -whitelist_externals = * +allowlist_externals = * commands = rm -frv {envdir}/dist python setup.py compile_docs @@ -134,7 +134,7 @@ passenv = * setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 -whitelist_externals = +allowlist_externals = mkdir ls commands = @@ -154,7 +154,7 @@ setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 passenv = * -whitelist_externals = * +allowlist_externals = * commands = python setup.py install_egg_info pip install -U -e .[test] @@ -169,7 +169,7 @@ passenv = * setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 -whitelist_externals = +allowlist_externals = /bin/sh commands = ansible-playbook -i localhost, --connection local k8s_env_deploy.yaml -vvvv @@ -185,7 +185,7 @@ passenv = * setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 -whitelist_externals = +allowlist_externals = /bin/sh commands = ansible-playbook -i localhost, --connection local k8s_env_destroy.yaml -vvvv @@ -201,7 +201,7 @@ passenv = * setenv = LC_ALL = en_US.UTF-8 LANG = en_US.UTF-8 -whitelist_externals = +allowlist_externals = /usr/bin/bash docker git diff --git a/tox_build.ini b/tox_build.ini index 342370e2..d31bae86 100644 --- a/tox_build.ini +++ b/tox_build.ini @@ -5,7 +5,7 @@ skipsdist = True [testenv] passenv = * setenv = CCACHE_DIR = {envdir}/.ccache -whitelist_externals = +allowlist_externals = ls rm bash From 38177888b09d0e3a62f541684e92a055483f0b9c Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov <onegreyonewhite@mail.ru> Date: Tue, 13 Dec 2022 14:28:30 +1000 Subject: [PATCH 4/8] Feature(backend): Add project and execution metrics. --- doc/api_schema.yaml | 49 +++++++++++++++++++++++++++++++++++++- doc/config.rst | 1 + polemarch/__init__.py | 2 +- polemarch/main/settings.py | 2 ++ polemarch/metrics.py | 31 ++++++++++++++++++++++++ requirements.txt | 2 +- test_data/metrics.txt | 9 +++++++ tests.py | 33 +++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 polemarch/metrics.py create mode 100644 test_data/metrics.txt diff --git a/doc/api_schema.yaml b/doc/api_schema.yaml index 9628f948..813b8bb0 100644 --- a/doc/api_schema.yaml +++ b/doc/api_schema.yaml @@ -69,7 +69,7 @@ info: x-versions: application: 2.3.0 library: 2.3.0 - vstutils: 5.1.11 + vstutils: 5.2.1 django: 3.2.16 djangorestframework: 3.14.0 drf_yasg: 1.21.4 @@ -104,6 +104,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - name - -name @@ -256,6 +257,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -467,6 +469,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -692,6 +695,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -955,6 +959,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -1191,6 +1196,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -1399,6 +1405,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -1642,6 +1649,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -1863,6 +1871,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -2076,6 +2085,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -2290,6 +2300,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -2482,6 +2493,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -2704,6 +2716,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -2897,6 +2910,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -3099,6 +3113,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -3239,6 +3254,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -3400,6 +3416,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -3627,6 +3644,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -3834,6 +3852,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -4097,6 +4116,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -4333,6 +4353,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -4541,6 +4562,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -4784,6 +4806,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -5005,6 +5028,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -5218,6 +5242,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -5478,6 +5503,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -5702,6 +5728,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - name - -name @@ -5923,6 +5950,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -6166,6 +6194,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -6408,6 +6437,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -6560,6 +6590,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -6739,6 +6770,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -6982,6 +7014,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -7199,6 +7232,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -7482,6 +7516,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -7733,6 +7768,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -7951,6 +7987,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -8218,6 +8255,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -8457,6 +8495,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -8640,6 +8679,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -8786,6 +8826,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -9019,6 +9060,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -9234,6 +9276,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -9412,6 +9455,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -9600,6 +9644,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -9840,6 +9885,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id @@ -10189,6 +10235,7 @@ paths: type: array items: type: string + format: ordering_choices enum: - id - -id diff --git a/doc/config.rst b/doc/config.rst index c3a99405..40bb1481 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -335,6 +335,7 @@ session_timeout, static_files_url or pagination limit. * **session_timeout** - Session life-cycle time. ``Default: 2w`` (two weeks). * **rest_page_limit** - Default limit of objects in API list. ``Default: 1000``. * **public_openapi** - Allow to have access to OpenAPI schema from public. ``Default: false``. +* **history_metrics_window** - Timeframe in seconds of collecting execution history statuses. ``Default: 1min``. .. note:: You can find more Web options in :ref:`vstutils:web`. diff --git a/polemarch/__init__.py b/polemarch/__init__.py index 20da731f..0946948f 100644 --- a/polemarch/__init__.py +++ b/polemarch/__init__.py @@ -31,6 +31,6 @@ "VST_ROOT_URLCONF": os.getenv("VST_ROOT_URLCONF", 'vstutils.urls'), } -__version__ = "2.3.1" +__version__ = "2.3.0" prepare_environment(**default_settings) diff --git a/polemarch/main/settings.py b/polemarch/main/settings.py index bc14e2ba..fadd378d 100644 --- a/polemarch/main/settings.py +++ b/polemarch/main/settings.py @@ -301,6 +301,8 @@ class PluginOptionsSection(PluginSection): PROJECT_REPOSYNC_WAIT_SECONDS = main.getseconds('repo_sync_on_run_timeout', fallback='1:00') PROJECT_CI_HANDLER_CLASS = "{}.main.ci.DefaultHandler".format(VST_PROJECT_LIB_NAME) +METRICS_BACKEND_CLASS = "{}.metrics.PolemarchBackend".format(VST_PROJECT_LIB_NAME) +HISTORY_METRICS_WINDOW = web.getseconds('history_metrics_window', fallback=600) __PWA_ICONS_SIZES = [ diff --git a/polemarch/metrics.py b/polemarch/metrics.py new file mode 100644 index 00000000..864acb64 --- /dev/null +++ b/polemarch/metrics.py @@ -0,0 +1,31 @@ +from datetime import timedelta +from django.conf import settings +from django.utils.timezone import now +from django.db.models import Count +from vstutils.api.metrics import DefaultBackend +from .main.models import History, Project + + +def get_polemarch_metrics(): + histories = History.objects.\ + filter(start_time__gte=now()-timedelta(seconds=settings.HISTORY_METRICS_WINDOW)).\ + values('status').\ + annotate(total=Count('status')).\ + values('status', 'total').\ + order_by('status') + + projects = Project.objects.\ + values('status'). \ + annotate(total=Count('status')). \ + values('status', 'total'). \ + order_by('status') + + for qs in (histories, projects): + for obj in qs: + yield '{prefix}_' + qs.model.__name__.lower() + '_total', ({'status': obj['status']}, obj['total']) + + +class PolemarchBackend(DefaultBackend): + metrics_list = ( + (None, get_polemarch_metrics), + ) diff --git a/requirements.txt b/requirements.txt index 77bc5f0d..8cf258ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Main -vstutils[rpc,doc,prod]~=5.1.11 +vstutils[rpc,doc,prod]~=5.2.2 docutils~=0.16.0 markdown2~=2.4.0 diff --git a/test_data/metrics.txt b/test_data/metrics.txt new file mode 100644 index 00000000..4ed8787d --- /dev/null +++ b/test_data/metrics.txt @@ -0,0 +1,9 @@ +python_info{version="$VERSION"} 1 +polemarch_database_connections 1 +polemarch_cache_connections 4 +polemarch_history_total{status="ERROR"} 310 +polemarch_history_total{status="OFFLINE"} 110 +polemarch_history_total{status="OK"} 10 +polemarch_project_total{status="ERROR"} 4 +polemarch_project_total{status="NEW"} 1 +polemarch_project_total{status="OK"} 3 diff --git a/tests.py b/tests.py index ed546f23..da39dfbc 100644 --- a/tests.py +++ b/tests.py @@ -2,6 +2,7 @@ import io import os import re +import sys import time import shutil from threading import Thread @@ -4278,6 +4279,38 @@ def test_menu(self): self.assertEqual(reg_schema['info']['x-menu'], PROJECT_MENU + [system_tab_user]) +class MetricsTestCase(VSTBaseTestCase): + def setUp(self): + super().setUp() + History = self.get_model_class('main.History') + Project = self.get_model_class('main.Project') + + self.history_status_count_map = { + "OK": 10, + 'OFFLINE': 110, + 'ERROR': 310, + } + + for status, count in self.history_status_count_map.items(): + for i in range(count): + History.objects.create(status=status) + + Project.objects.create(name=f'test_metrics_{i}') + for i in range(3): + Project.objects.create(name=f'test_metrics_{i}', status='OK') + for i in range(4): + Project.objects.create(name=f'test_metrics_{i}', status='ERROR') + + def test_metrics(self): + result = self.get_result('get', '/api/metrics/') + expected = (Path(Path(__file__).parent) / 'test_data' / 'metrics.txt').read_text('utf-8') + expected = expected.replace( + '$VERSION', + f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}' + ) + self.assertEqual(result, expected) + + class BaseExecutionPluginUnitTestCase(VSTBaseTestCase): plugin_class = None From 503ded3f32d450d0a86583a17561aef561aa3408 Mon Sep 17 00:00:00 2001 From: Vladislav Korenkov <vladnfs3@gmail.com> Date: Tue, 13 Dec 2022 17:41:19 +1000 Subject: [PATCH 5/8] Chore: Process override field in execute action --- doc/api_schema.yaml | 30 ++++--- polemarch/api/v2/serializers.py | 11 +-- polemarch/api/v3/serializers.py | 17 ++-- polemarch/main/constants.py | 1 + polemarch/main/models/tasks.py | 2 + polemarch/main/openapi.py | 12 +++ polemarch/main/settings.py | 1 + tests.py | 141 +++++++++++++++++++++++++++++++- 8 files changed, 181 insertions(+), 34 deletions(-) diff --git a/doc/api_schema.yaml b/doc/api_schema.yaml index 813b8bb0..959c6fa7 100644 --- a/doc/api_schema.yaml +++ b/doc/api_schema.yaml @@ -69,7 +69,7 @@ info: x-versions: application: 2.3.0 library: 2.3.0 - vstutils: 5.2.1 + vstutils: 5.2.2 django: 3.2.16 djangorestframework: 3.14.0 drf_yasg: 1.21.4 @@ -195,8 +195,8 @@ paths: $ref: '#/definitions/ProjectTemplateCreate' tags: - community_template - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -2203,8 +2203,8 @@ paths: $ref: '#/definitions/ActionResponse' tags: - history - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -2221,8 +2221,8 @@ paths: description: NO CONTENT tags: - history - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -5415,8 +5415,8 @@ paths: $ref: '#/definitions/ExecuteResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -5440,8 +5440,8 @@ paths: $ref: '#/definitions/ExecuteResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -5670,8 +5670,8 @@ paths: $ref: '#/definitions/ExecuteResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: execution_templates_id in: path @@ -6082,8 +6082,8 @@ paths: $ref: '#/definitions/ActionResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: history_id in: path @@ -6105,8 +6105,8 @@ paths: description: NO CONTENT tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: history_id in: path @@ -9002,8 +9002,8 @@ paths: $ref: '#/definitions/ExecuteResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -9403,8 +9403,8 @@ paths: $ref: '#/definitions/ActionResponse' tags: - project - x-multiaction: false x-require-confirmation: false + x-multiaction: false parameters: - name: id in: path @@ -12605,13 +12605,13 @@ definitions: - data x-view-field-name: name TemplateExec: - required: - - option type: object properties: option: title: Option - type: integer + type: string + minLength: 1 + x-nullable: true format: fk x-options: dependence: null @@ -12619,10 +12619,8 @@ definitions: makeLink: true model: $ref: '#/definitions/TemplateOption' - usePrefetch: true value_field: name view_field: name - x-nullable: true x-properties-groups: '': - option diff --git a/polemarch/api/v2/serializers.py b/polemarch/api/v2/serializers.py index f53315aa..02c69901 100644 --- a/polemarch/api/v2/serializers.py +++ b/polemarch/api/v2/serializers.py @@ -14,7 +14,7 @@ from vstutils.api import auth as vst_auth from vstutils.api import serializers as vst_serializers, fields as vst_fields -from vstutils.api.serializers import DataSerializer, EmptySerializer +from vstutils.api.serializers import DataSerializer, EmptySerializer, BaseSerializer from .base_serializers import with_signals, UserSerializer, _WithPermissionsSerializer, _SignalSerializer from ...main import models @@ -522,13 +522,8 @@ class Meta: ) -class TemplateExecSerializer(DataSerializer): - option = vst_fields.FkField( - select='TemplateOption', - autocomplete_property='name', - autocomplete_represent='name', - allow_null=True, - ) +class TemplateExecSerializer(BaseSerializer): + option = serializers.CharField(allow_null=True, required=False) ################################### diff --git a/polemarch/api/v3/serializers.py b/polemarch/api/v3/serializers.py index 01a70533..b3370c91 100644 --- a/polemarch/api/v3/serializers.py +++ b/polemarch/api/v3/serializers.py @@ -13,6 +13,7 @@ OneProjectSerializer as V2OneProjectSerializer, ) from ...main.executions import PLUGIN_HANDLERS +from ...main.constants import TEMPLATE_KINDS_MAP class TaskTemplateParameters(BaseSerializer): @@ -39,12 +40,12 @@ class ModuleTemplateParameters(BaseSerializer): )(required=False) -template_kinds = ( - ('Task', 'Task'), - ('Module', 'Module'), -) + tuple( - (plugin, plugin) for plugin in PLUGIN_HANDLERS.keys() - if plugin not in {'PLAYBOOK', 'MODULE'} +template_kinds = tuple( + ( + TEMPLATE_KINDS_MAP.get(plugin, plugin), + TEMPLATE_KINDS_MAP.get(plugin, plugin), + ) + for plugin in PLUGIN_HANDLERS.keys() ) template_data_types = { @@ -54,7 +55,7 @@ class ModuleTemplateParameters(BaseSerializer): template_data_types.update({ plugin: backend.get_serializer_class(exclude_fields=('inventory',))(required=False) for plugin, backend in PLUGIN_HANDLERS.items() - if plugin not in ('PLAYBOOK, MODULE') + if plugin not in TEMPLATE_KINDS_MAP }) @@ -78,7 +79,7 @@ class Meta: template_inventory_types.update({ plugin: InventoryAutoCompletionField(allow_blank=True, required=False) if backend.supports_inventory else 'hidden' for plugin, backend in PLUGIN_HANDLERS.items() - if plugin not in ('PLAYBOOK', 'MODULE') + if plugin not in TEMPLATE_KINDS_MAP }) diff --git a/polemarch/main/constants.py b/polemarch/main/constants.py index d09a8195..ff5f9834 100644 --- a/polemarch/main/constants.py +++ b/polemarch/main/constants.py @@ -6,6 +6,7 @@ CYPHER = '[~~ENCRYPTED~~]' ANSIBLE_REFERENCE = AnsibleArgumentsReference() +TEMPLATE_KINDS_MAP = {'PLAYBOOK': 'Task', 'MODULE': 'Module'} class BaseVariablesEnum(BaseEnum): diff --git a/polemarch/main/models/tasks.py b/polemarch/main/models/tasks.py index 2ae76f75..794db313 100644 --- a/polemarch/main/models/tasks.py +++ b/polemarch/main/models/tasks.py @@ -93,7 +93,9 @@ def get_data_with_options(self, option: Optional[str], **extra) -> Dict[str, Any vars.update(option_vars) data.update(option_data) data.update(vars) + override = extra.pop('override', {}) data.update(extra) + data.update(override) return data def get_plugin(self): diff --git a/polemarch/main/openapi.py b/polemarch/main/openapi.py index bbcb68c6..624467be 100644 --- a/polemarch/main/openapi.py +++ b/polemarch/main/openapi.py @@ -150,3 +150,15 @@ def set_periodic_task_variable_value_field(request, schema): # pylint: disable= 'readOnly': True, 'x-hidden': True, } + + +def set_template_option_field_to_fk(request, schema): + schema['definitions']['TemplateExec']['properties']['option']['format'] = 'fk' + schema['definitions']['TemplateExec']['properties']['option']['x-options'] = { + 'model': {'$ref': '#/definitions/TemplateOption'}, + 'value_field': 'name', + 'view_field': 'name', + 'makeLink': True, + 'dependence': None, + 'filters': None, + } diff --git a/polemarch/main/settings.py b/polemarch/main/settings.py index fadd378d..79445db7 100644 --- a/polemarch/main/settings.py +++ b/polemarch/main/settings.py @@ -74,6 +74,7 @@ 'polemarch.main.openapi.set_gui_menu_ce', 'polemarch.main.openapi.set_inventory_field', 'polemarch.main.openapi.set_periodic_task_variable_value_field', + 'polemarch.main.openapi.set_template_option_field_to_fk', ] SWAGGER_SETTINGS['DEFAULT_INFO'] = '{}.api.v2.swagger.api_info'.format(VST_PROJECT_LIB_NAME) diff --git a/tests.py b/tests.py index da39dfbc..d7befd91 100644 --- a/tests.py +++ b/tests.py @@ -30,12 +30,12 @@ from polemarch.main.openapi import PROJECT_MENU from polemarch.main.constants import CYPHER from polemarch.main.models.utils import ProjectProxy - from polemarch.plugins.ansible import BaseAnsiblePlugin, BasePlugin, Module + from polemarch.plugins.ansible import BaseAnsiblePlugin, BasePlugin, Module, Playbook except ImportError: from pmlib.main.tasks import ScheduledTask from pmlib.main.models.utils import ProjectProxy from pmlib.main.constants import CYPHER - from pmlib.plugins.ansible import BaseAnsiblePlugin, BasePlugin, Module + from pmlib.plugins.ansible import BaseAnsiblePlugin, BasePlugin, Module, Playbook TEST_DATA_DIR = Path(__file__).parent.absolute() @@ -4249,6 +4249,8 @@ def test_schema(self): with raise_context(): endpoint_schema['definitions']['PeriodicTaskVariable']['properties']['key']['x-options']['types'] = \ yml_schema['definitions']['PeriodicTaskVariable']['properties']['key']['x-options']['types'] + endpoint_schema['definitions']['TemplateExec']['properties']['override']['x-options']['types'] = \ + yml_schema['definitions']['TemplateExec']['properties']['override']['x-options']['types'] del yml_schema['definitions']['_MainSettings'] del endpoint_schema['definitions']['_MainSettings'] @@ -4342,3 +4344,138 @@ def test_put_into_tmpfile(self): test_value = 'test_value' filepath = instance._put_into_tmpfile(test_value) self.assertEqual(Path(filepath).read_text(), test_value) + self.assertEqual(Path(filepath).stat().st_mode, 0o100600) + + +class AnsiblePlaybookExecutionPluginUnitTestCase(BaseExecutionPluginUnitTestCase): + plugin_class = Playbook + + boolean_args = ( + 'force_handlers', + 'flush_cache', + 'become', + 'check', + 'syntax_check', + 'diff', + 'list_hosts', + 'list_tasks', + 'list_tags', + ) + string_args = ( + 'user', + 'connection', + 'ssh_common_args', + 'sftp_extra_args', + 'scp_extra_args', + 'ssh_extra_args', + 'become_method', + 'become_user', + 'tags', + 'skip_tags', + 'inventory', + 'limit', + 'extra_vars', + 'vault_id', + 'start_at_task', + 'args', + ) + int_args = ( + 'timeout', + 'forks', + ) + file_args = ( + 'private_key', + 'vault_password_file', + 'module_path', + ) + + def test_process_arg(self): + instance = self.get_plugin_instance() + + self.assertIsNone(instance._process_arg('unknown', 'unknown')) + self.assertEqual(instance._process_arg('verbose', 2), '-vv') + self.assertIsNone(instance._process_arg('verbose', 0)) + + for arg in self.boolean_args: + self.assertIsNone(instance._process_arg(arg, False)) + self.assertEqual(instance._process_arg(arg, True), f'--{arg.replace("_", "-")}') + + for arg in self.string_args: + self.assertIsNone(instance._process_arg(arg, '')) + self.assertEqual(instance._process_arg(arg, 'test-value'), f'--{arg.replace("_", "-")}=test-value') + + for arg in self.int_args: + self.assertIsNone(instance._process_arg(arg, 0)) + self.assertEqual(instance._process_arg(arg, 2), f'--{arg.replace("_", "-")}=2') + + for arg in self.file_args: + self.assertIsNone(instance._process_arg(arg, '')) + processed_arg = instance._process_arg(arg, 'test-value') + filepath = processed_arg[processed_arg.index('=') + 1:] + self.assertEqual(Path(filepath).read_text(), 'test-value') + + +class AnsibleModuleExecutionPluginUnitTestCase(BaseExecutionPluginUnitTestCase): + plugin_class = Module + + boolean_args = ( + 'become', + 'list_hosts', + 'one_line', + 'check', + 'syntax_check', + 'diff', + ) + string_args = ( + 'become_method', + 'become_user', + 'inventory', + 'limit', + 'tree', + 'user', + 'connection', + 'ssh_common_args', + 'sftp_extra_args', + 'scp_extra_args', + 'ssh_extra_args', + 'extra_vars', + 'vault_id', + 'playbook_dir', + 'args', + 'group', + ) + int_args = ( + 'poll', + 'background', + 'timeout', + 'forks', + ) + file_args = ( + 'private_key', + 'vault_password_file' + ) + + def test_process_arg(self): + instance = self.get_plugin_instance() + + self.assertIsNone(instance._process_arg('unknown', 'unknown')) + self.assertEqual(instance._process_arg('verbose', 3), '-vvv') + self.assertIsNone(instance._process_arg('verbose', 0)) + + for arg in self.boolean_args: + self.assertIsNone(instance._process_arg(arg, False)) + self.assertEqual(instance._process_arg(arg, True), f'--{arg.replace("_", "-")}') + + for arg in self.string_args: + self.assertIsNone(instance._process_arg(arg, '')) + self.assertEqual(instance._process_arg(arg, 'test-value'), f'--{arg.replace("_", "-")}=test-value') + + for arg in self.int_args: + self.assertIsNone(instance._process_arg(arg, 0)) + self.assertEqual(instance._process_arg(arg, 2), f'--{arg.replace("_", "-")}=2') + + for arg in self.file_args: + self.assertIsNone(instance._process_arg(arg, '')) + processed_arg = instance._process_arg(arg, 'test-value') + filepath = processed_arg[processed_arg.index('=') + 1:] + self.assertEqual(Path(filepath).read_text(), 'test-value') From b7086a2dd47947dd46f8be8d206fb980e633b2be Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov <onegreyonewhite@mail.ru> Date: Fri, 16 Dec 2022 13:01:41 +1000 Subject: [PATCH 6/8] Feature(service): Deploy Polemarch to k8s via werf --- .dockerignore | 289 ++++++++++++++++++++++++++++- .gitignore | 3 + .helm/Chart.lock | 15 ++ .helm/Chart.yaml | 20 ++ .helm/values.yaml | 111 ++++++++++++ Dockerfile | 1 + Makefile | 210 --------------------- deb.mk | 131 -------------- environment/all.yml | 34 ---- environment/deployment_pm.yml.j2 | 302 ------------------------------- k8s_env_deploy.yaml | 43 ----- k8s_env_destroy.yaml | 15 -- rpm.mk | 80 -------- werf.yaml | 2 +- 14 files changed, 439 insertions(+), 817 deletions(-) mode change 120000 => 100644 .dockerignore create mode 100644 .helm/Chart.lock create mode 100644 .helm/Chart.yaml create mode 100644 .helm/values.yaml delete mode 100644 Makefile delete mode 100644 deb.mk delete mode 100644 environment/all.yml delete mode 100644 environment/deployment_pm.yml.j2 delete mode 100644 k8s_env_deploy.yaml delete mode 100644 k8s_env_destroy.yaml delete mode 100755 rpm.mk diff --git a/.dockerignore b/.dockerignore deleted file mode 120000 index 3e4e48b0..00000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.gitignore \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..f0bfbf08 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,288 @@ +### C++ template +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### C template +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### Python template +# 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 +*.sqlite3 + +# 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 + +.helm +.gitlab +.github +.coveragerc +.pep8 +.pylintrc +ansible.cfg +docker-compose.yml +settings.ini +.gitlab-ci.yml +autobuild.sh +autorelease.sh +traefik_dynamic.yml +test_fixtures.json +test_settings.ini +tox_build.ini +initbin +test_data +test_data_ce +tests.py +tests_ce.py + +!Dockerfile +!.dockerignore +!ce/Dockerfile +ce +!ce/polemarch +!ce/setup.py +!ce/doc +!ce/package.json +!ce/frontend_src +!ce/webpack.config.js +!ce/.dockerignore +!ce/requirements.txt +!ce/requirements-doc.txt +!ce/requirements-git.txt +!ce/requirements-test.txt diff --git a/.gitignore b/.gitignore index d43e533e..59f5eeb8 100644 --- a/.gitignore +++ b/.gitignore @@ -137,3 +137,6 @@ venv.bak/ node_modules polemarch/static/polemarch yarn-error.log + +# werf and helm +.helm/charts diff --git a/.helm/Chart.lock b/.helm/Chart.lock new file mode 100644 index 00000000..5ed43231 --- /dev/null +++ b/.helm/Chart.lock @@ -0,0 +1,15 @@ +dependencies: +- name: centrifugo + repository: https://centrifugal.github.io/helm-charts + version: 7.4.0 +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 12.1.3 +- name: redis + repository: https://charts.bitnami.com/bitnami + version: 17.3.6 +- name: YAUHC + repository: https://gitlab.com/api/v4/projects/40345586/packages/helm/stable + version: 0.1.9 +digest: sha256:aa4610033f88728d8ad9e120dd2f84ceffa03525f7767e8a2e0e6b932386765e +generated: "2022-12-14T19:53:00.009050764+04:00" diff --git a/.helm/Chart.yaml b/.helm/Chart.yaml new file mode 100644 index 00000000..edcbee08 --- /dev/null +++ b/.helm/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: polemarch-deployment +version: 0.1.0 +dependencies: +- name: centrifugo + repository: https://centrifugal.github.io/helm-charts + version: 7.4.0 +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 12.1.3 +- name: redis + repository: https://charts.bitnami.com/bitnami + version: 17.3.6 +- name: YAUHC + alias: polemarch + repository: https://gitlab.com/api/v4/projects/40345586/packages/helm/stable + version: 0.1.9 + export-values: + - parent: werf.image.main + child: deployments.polemarch.image diff --git a/.helm/values.yaml b/.helm/values.yaml new file mode 100644 index 00000000..b0da2103 --- /dev/null +++ b/.helm/values.yaml @@ -0,0 +1,111 @@ +postgresql: + commonAnnotations: + werf.io/weight: "-10" + fullnameOverride: database-server + auth: + postgresPassword: p@$$w0rD + username: polemarch + password: polemarch + database: polemarch +redis: + commonAnnotations: + werf.io/weight: "-10" + fullnameOverride: redis-server + architecture: standalone + auth: + enabled: false +centrifugo: + config: + admin: false + allowed_origins: + - '*' + engine: redis + health: true + history_size: 10 + history_ttl: 300s + namespaces: [] + fullnameOverride: centrifugo + image: + tag: v3.2 + ingress: + enabled: false + secrets: + redisAddress: redis-server-master:6379 + adminPassword: 01a18ca9-9328-4ee7-a8de-7e5b231d1df4 + adminSecret: 7e91c9c1-6303-42b1-9f28-1cdfbf58dcf9 + apiKey: a08caef0-f1ad-40de-9e59-dd2cec07e2eb + tokenHmacSecretKey: d4074fd2-607c-41b0-ab83-f2bc55fae0ec + service: + port: 9000 + useSeparateInternalService: true + annotations: + werf.io/weight: "-9" + podAnnotations: + werf.io/weight: "-9" +polemarch: + multi_endpoint: + domain: polemarch.example.com + deployments: + centrifugo: + port: 9000 + endpointPath: /connection/ + external: true + polemarch: + port: 8080 + endpointPath: / + env: + DATABASE_URL: 'postgres://polemarch:polemarch@database-server:5432/polemarch' + RPC_ENGINE: 'redis://redis-server-master:6379/0' + CACHE_URL: 'redis://redis-server-master:6379/1' + LOCK_CACHE_URL: 'redis://redis-server-master:6379/2' + SESSION_CACHE_URL: 'redis://redis-server-master:6379/3' + ETAG_CACHE_URL: 'redis://redis-server-master:6379/4' + RPC_CONCURRENCY: 32 + volumes: + storage: '/storage' + volumeSpec: + resources: + requests: + storage: 5Gi + livenessProbe: + exec: + command: + - /bin/sh + - -c + - "ps -A | grep uwsgi" + initialDelaySeconds: 10 + periodSeconds: 20 + timeoutSeconds: 15 + readinessProbe: + httpGet: + httpHeaders: + - name: Connection + value: keep-alive + path: /api/health/ + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 20 + configPath: '/etc/polemarch' + configs: + settings.ini: | + [docker] + override_uwsgi = false + migrate_lock_id = polemarch + + [main] + auth-cache-user = True + log_level = warning + debug = false + projects_dir = /storage/projects + hooks_dir = /storage/hooks + + [uwsgi] + daemon = false + pidfile = /tmp/web.pid + addrport = 0.0.0.0:8080 + + [centrifugo] + address = http://centrifugo:9000/api + public_address = / + token_hmac_secret_key = d4074fd2-607c-41b0-ab83-f2bc55fae0ec + api_key = a08caef0-f1ad-40de-9e59-dd2cec07e2eb diff --git a/Dockerfile b/Dockerfile index 05612ccc..2193aff6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,6 +57,7 @@ RUN --mount=type=cache,target=/var/cache/apt \ sudo \ sshpass \ libmysqlclient21 \ + libpq5 \ libpcre3 \ libldap-2.4-2 \ libsasl2-2 \ diff --git a/Makefile b/Makefile deleted file mode 100644 index e27430a8..00000000 --- a/Makefile +++ /dev/null @@ -1,210 +0,0 @@ -PY = python -PIP = $(PY) -m pip -PY_VERSION = $(shell $(PY) --version 2>&1 | tail -c +8) -PYTHON_BIN = $(shell $(PY) -c 'import sys, os; print(os.path.dirname(sys.executable))') -RELOCATE_BIN = $(PYTHON_BIN)/venvctrl-relocate -LOC_TEST_ENVS = py27-install,py36-install,flake,pylint -ENVS = $(LOC_TEST_ENVS) -ifndef TOX_ARGS - TOX_ARGS = -endif -TESTS = -NAMEBASE = polemarch -USER = $(NAMEBASE) -NAME = $(NAMEBASE) -VER = $(shell $(PY) setup.py --version | tr -d '\n') -PROJECT_CTL = $(NAME)ctl -MAIN_APP = main -VSTUTILS_REQ = $(shell cat requirements-doc.txt | grep vstutils | sed 's/\[.*\]/[doc]/') -VSTUTILS = $(VSTUTILS_REQ) -PIPARGS = $(shell echo -n "--cache-dir=$$(pwd)/.pip-cache") -ARCHIVE = $(NAME)-$(VER).tar.gz -LICENSE = AGPL-3+ -define DESCRIPTION - Polemarch is service for orchestration infrastructure by ansible. - Simply WEB gui for orchestration infrastructure by ansible playbooks. -endef -export DESCRIPTION -SUMMARY = Infrastructure Heat Service for orchestration infrastructure by ansible. -VENDOR = VST Consulting <sergey.k@vstconsulting.net> -RELEASE = 0 -DEFAULT_PREFIX = /opt -INSTALL_PREFIX = $(shell if [[ ! -z "${prefix}" ]]; then echo -n $(prefix); else echo -n $(DEFAULT_PREFIX); fi) -INSTALL_DIR = $(INSTALL_PREFIX)/${NAME} -INSTALL_BINDIR = $(INSTALL_DIR)/bin -INSTALL_PY = $(PY) -REQUIREMENTS = -r requirements.txt -r requirements-doc.txt -TMPDIR := $(shell mktemp -d) -RPM_BUILD = /tmp/rpmbuild_$(NAME)_$(VER)_$(RELEASE) -BUILD_DIR= $(TMPDIR) -PREBUILD_DIR = $(BUILD_DIR)/$(INSTALL_DIR) -PREBUILD_BINDIR = $(BUILD_DIR)/$(INSTALL_BINDIR) -SOURCE_DIR = $(shell pwd) -COMPILE_DIR = $(shell echo -n "$$(pwd)/dist") -define VARS_STR -PY=$(PY) -PY_VERSION=$(PY_VERSION) -PIP=$(PIP) -PYTHON_BIN=$(PYTHON_BIN) -RELOCATE_BIN=$(RELOCATE_BIN) -NAMEBASE=$(NAMEBASE) -USER=$(USER) -NAME=$(NAME) -VER=$(VER) -RELEASE=$(RELEASE) -PROJECT_CTL=$(PROJECT_CTL) -MAIN_APP=$(MAIN_APP) -VSTUTILS=$(VSTUTILS) -BUILD_DIR=$(BUILD_DIR) -RPM_BUILD=$(RPM_BUILD) -INSTALL_DIR=$(INSTALL_DIR) -endef -export VARS_STR - -include rpm.mk -include deb.mk - -all: compile clean_prebuild prebuild - - -print_vars: - echo "$$VARS_STR" - which $(PY) - -docs: print_vars - -rm -rf doc/_build - mkdir -p doc/_static - $(PY) setup.py build_sphinx --build-dir doc/_build -W - -test: - tox $(TOX_ARGS) -e $(ENVS) $(TESTS) - -flake: - tox -e flake - -pylint: - tox -e pylint - -build: build-clean print_vars - # -rm -rf dist - $(PY) setup.py sdist -v - -pre_compile: build-clean print_vars - find ./$(NAME) -name "*.c" -print0 | xargs -0 rm -rf - -rm -rf polemarch/doc/* - $(PIP) install -U $(VSTUTILS) - -compile: pre_compile - # -rm -rf dist - $(PY) setup.py compile -v - -wheel: pre_compile - $(PY) setup.py compile_docs -v - $(PY) setup.py bdist_wheel -v --dist-dir $(COMPILE_DIR) --bdist-dir /tmp/build_$(NAME)/$(PY_VERSION)/ - -prebuild: print_vars - # Create virtualenv - $(PY) -m virtualenv -p $(INSTALL_PY) --download --no-site-packages $(PREBUILD_DIR) - # Install required packages - $(PREBUILD_BINDIR)/pip install -U pip - $(PREBUILD_BINDIR)/pip install -U dist/$(NAME)-$(VER).tar.gz $(REQUIREMENTS) - $(PREBUILD_BINDIR)/pip install -U -r requirements-git.txt - # RECORD files are used by wheels for checksum. They contain path names which - # match the buildroot and must be removed or the package will fail to build. - # find $(PREBUILD_DIR) -name "RECORD" -exec rm -rf {} \; - # Change the virtualenv path to the target installation direcotry. - $(RELOCATE_BIN) --source=$(PREBUILD_DIR) --destination=$(INSTALL_DIR) - # Remove sources for Clang - find $(PREBUILD_DIR)/lib -type f -name "*.c" -print0 | xargs -0 rm -rf - # Remove broken link - -rm -rf $(PREBUILD_DIR)/local - # Install settings - -install -Dm 755 $(NAME)/$(MAIN_APP)/settings.ini $(BUILD_DIR)/etc/$(USER)/settings.ini.template - # Install systemd services - -install -Dm 755 initbin/$(NAME).service $(BUILD_DIR)/etc/systemd/system/$(NAME).service - # Install tmpdirs config - -install -Dm 755 initbin/$(NAMEBASE).conf $(BUILD_DIR)/etc/tmpfiles.d/$(NAMEBASE).conf - # Create tmpdirs - -mkdir -p $(BUILD_DIR)/var/log/$(NAMEBASE) - -mkdir -p $(BUILD_DIR)/var/run/$(NAMEBASE) - -mkdir -p $(BUILD_DIR)/var/lock/$(NAMEBASE) - -localinstall: print_vars - $(PY) -m virtualenv --no-site-packages $(INSTALL_DIR) - $(INSTALL_BINDIR)/pip install -U pip - $(INSTALL_BINDIR)/pip install -U $(VSTUTILS) - $(INSTALL_BINDIR)/pip install -U dist/$(NAME)-$(VER).tar.gz $(REQUIREMENTS) - $(INSTALL_BINDIR)/pip install -U -r requirements-git.txt - find $(INSTALL_DIR)/lib -type f -name "*.c" -print0 | xargs -0 rm -rf - $(MAKE) prebuild_deps BUILD_DIR=$(INSTALL_DIR) - -install: - # Change owner for packages - -chown -R $(USER):$(USER) $(PREBUILD_DIR) $(BUILD_DIR)/var/{log,run,lock}/$(NAMEBASE) $(BUILD_DIR)/etc/$(USER) - # Copy build - cp -rf $(BUILD_DIR)/* / - $(MAKE) clean_prebuild - -uninstall: - -rm -rf $(INSTALL_DIR) - -clean_prebuild: - -rm -rf $(BUILD_DIR)/* - -clean: build-clean - -rm -rf htmlcov - -rm -rf .coverage - -rm -rf dist - -rm -rf build - -rm -rf *.egg-info - -build-clean: - -rm pylint_* || true - find ./$(NAME) -name '__pycache__' -print0 | xargs -0 rm -rf - find ./$(NAME) -name "*.pyc" -print0 | xargs -0 rm -rf - -rm -rf build - -rm -rf *.egg-info - -fclean: clean - find ./$(NAME) -name "*.c" -print0 | xargs -0 rm -rf - -rm -rf .tox - -rpm: print_vars - echo "$$RPM_SPEC" > $(NAME).spec - rm -rf $(RPM_BUILD) - mkdir -p $(RPM_BUILD)/SOURCES/ - ls -la - rpmbuild --verbose -bb $(NAME).spec --define "_rpmdir ${RPM_BUILD}" --define "_topdir ${RPM_BUILD}" - mkdir -p dist - cp -v $(RPM_BUILD)/x86_64/*.rpm dist/ - rm -rf $(NAME).spec $(RPM_BUILD) - -deb: print_vars - rm -rf debian - mkdir debian - # create needed files - echo 9 > debian/compat - echo "$$DEBIAN_CONTROL" > debian/control - echo "$$DEBIAN_COPYRIGHT" > debian/copyright - echo "$$DEBIAN_RULES" > debian/rules - echo "$$DEBIAN_PREINST" > debian/preinst - echo "$$DEBIAN_POSTINST" > debian/postinst - echo "$$DEBIAN_PRERM" > debian/prerm - echo "$$DEBIAN_POSTRM" > debian/postrm - echo "$$DEBIAN_CHANGELOG" > debian/changelog - chmod +x debian/rules - chmod +x debian/preinst - chmod +x debian/postinst - chmod +x debian/prerm - chmod +x debian/postrm - # build - dpkg-buildpackage -d -uc -us -j4 - mv -v ../$(NAME)_$(VER)*.deb dist/ - # cleanup - rm -rf debian - -# twine: -# for file in $(shell find dist/*.{tar.gz,whl} | grep ${NAME} | grep ${VER}); do \ -# echo $$file; \ -# twine upload -u $(PYPI_UPLOAD_NAME) -p $(PYPI_UPLOAD_PASSWORD) $$file || echo "Filed to upload ${file}"; \ -# done diff --git a/deb.mk b/deb.mk deleted file mode 100644 index 4c9f3464..00000000 --- a/deb.mk +++ /dev/null @@ -1,131 +0,0 @@ -define DEBIAN_CONTROL -Source: $(NAME) -Section: unknown -Priority: optional -Maintainer: $(VENDOR) -Build-Depends: debhelper (>= 9), python-virtualenv, python-pip, python-dev, gcc, libffi-dev, libssl-dev, libyaml-dev, libkrb5-dev, libssl-dev, libsasl2-dev, libldap2-dev -Standards-Version: 3.9.5 -Homepage: https://gitlab.com/vstconsulting/polemarch -Vcs-Git: git@gitlab.com:vstconsulting/polemarch.git -Vcs-Browser: https://gitlab.com/vstconsulting/polemarch.git - -Package: $(NAME) -Architecture: amd64 -Depends: $${shlibs:Depends}, $${misc:Depends}, python-virtualenv, libffi6, libssl-dev, sshpass, libpython2.7, git, libyaml-dev, libkrb5-dev, libssl-dev, libsasl2-dev, libldap2-dev, mime-support -Description: $(SUMMARY) -$(DESCRIPTION) -endef -export DEBIAN_CONTROL - -define DEBIAN_COPYRIGHT -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: $(NAME) -Source: <url://example.com> - -Files: * -Copyright: 2017 VST Consulting -License: ${LICENSE} - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero Public License for more details. - - You should have received a copy of the GNU Affero Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -endef -export DEBIAN_COPYRIGHT - -# paths and executables variables -BUILDROOT = debian/$(NAME) -define DEBIAN_RULES -#!/usr/bin/make -f -# maximum verbosity during deb build -DH_VERBOSE = 1 -export DH_OPTIONS=-v -# targets, that we want to override with no actions -override_dh_auto_build: - # don't need becouse all makes in 'override_dh_auto_install' target -override_dh_auto_test: - # don't want to test during package build -override_dh_strip: - # it is broken for some unknown reason -override_dh_link: - # it is replacing python in virtualenv with system python -override_dh_shlibdeps: - # it generates dependency which breaks compartibility with newer distros: - # libssl with exact version 1.0.0 -# real install -override_dh_auto_install: - # create taget directory and clear it in case of some files exist from - # previous build - mkdir -p $(BUILDROOT) - touch $(BUILDROOT)/dummy - rm -rf $(BUILDROOT)/* - make BUILD_DIR=$(BUILDROOT) -%: - dh $$@ -endef -export DEBIAN_RULES - -define DEBIAN_PREINST -#!/bin/bash -# making sure user created -id -u $(USER) &>/dev/null || useradd -m $(USER) -id -g $(USER) &>/dev/null || groupadd $(USER) -endef -export DEBIAN_PREINST - -define DEBIAN_POSTINST -#!/bin/bash -# change owner of all dirs -chown -R $(USER):$(USER) /opt/$(NAME) -chown -R $(USER):$(USER) /var/log/$(NAMEBASE) -chown -R $(USER):$(USER) /var/run/$(NAMEBASE) -chown -R $(USER):$(USER) /var/lock/$(NAMEBASE) -# making migration and activate services -# sudo -H -u $(USER) /opt/$(NAME)/bin/polemarchctl migrate -su - $(USER) -c "/opt/$(NAME)/bin/$(PROJECT_CTL) migrate" -systemctl daemon-reload || true -systemctl enable $(NAME).service || true -endef -export DEBIAN_POSTINST - -define DEBIAN_PRERM -#!/bin/bash -case "$$1" in - remove) - # deactivating services - systemctl disable $(NAME).service > /dev/null 2>&1 - service $(NAME) stop >/dev/null 2>&1 - ;; -esac -# cleaning after yourself -rm -r /opt/$(NAME)/lib/python2.7/site-packages/$(NAME)/projects/ -rm -rf /opt/$(NAME)/httpd/ -endef -export DEBIAN_PRERM - -define DEBIAN_POSTRM -#!/bin/bash -# remove whole /opt/polemarch (database included) if purge called -case "$$1" in - purge) - rm -rf /opt/$(NAME) - ;; -esac -endef -export DEBIAN_POSTRM - -define DEBIAN_CHANGELOG -$(NAME) ($(VER)-$(RELEASE)) unstable; urgency=low - - * this changelog is generated automatically. See official site for actual list of changes. - - -- Sergey K. <sergey.k@vstconsulting.net> Wed, 19 Jul 2017 6:41:48 +0000 -endef -export DEBIAN_CHANGELOG diff --git a/environment/all.yml b/environment/all.yml deleted file mode 100644 index e1b4a6c0..00000000 --- a/environment/all.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -##### VARS FOR REGISTRY / DOCKER / DOCKERHUB -k8s_path_deployment_template: "{{ lookup('env', 'PATH_DEPLOYMENT_TEMPLATE') or './environment/deployment_pm.yml.j2' }}" -k8s_registry_image_name: "{{ lookup('env', 'REGISTRY_IMAGE') }}" -k8s_registry_image_tag: "{{ lookup('env', 'REGISTRY_IMAGE_TAG') }}" -k8s_registry_user: "{{ lookup('env', 'REGISTRY_USER') }}" -k8s_registry_password: "{{ lookup('env', 'REGISTRY_PASSWORD') }}" -k8s_registry_url: "{{ lookup('env', 'REGISTRY_URL') or 'https://index.docker.io/v1/' }}" -k8s_docker_host: "{{ lookup ('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock' }}" -k8s_status_project: "{{ lookup ('env', 'K8S_STATUS_PROJECT') }}" - -##### VARS FOR KUBE -k8s_kubeconfig: "{{ lookup('env', 'KUBECONFIG') or '~/.kube/config' }}" -k8s_env_namespace: "{{ lookup('env', 'KUBE_NAMESPACE') }}" -k8s_kube_pm_ingress_domain: "{{ lookup('env', 'K8S_INGRESS_DOMAIN') }}" -k8s_pm_playbook_template: "{{ lookup('template', k8s_path_deployment_template) }}" - -###### if kubernetes in rancher -> "true" -k8s_kube_in_rancher: "{{ lookup('env', 'K8S_KUBE_IN_RANCHER') or 'true' }}" - -########## block SECRET for local registry --->>> -k8s_registry_dockerconfig_auth: "{{ k8s_registry_user }}:{{ k8s_registry_password }}" -k8s_registry_dockerconfig_base64: '{"auths":{"{{ k8s_registry_url }}":{"username":"{{ k8s_registry_user }}","password":"{{ k8s_registry_password }}","auth":"{{ k8s_registry_dockerconfig_auth | b64encode }}"}}}' - -########## ENV K8S POLEMARCH --->>> -kube_pm_replilica_vol: 1 -kube_pm_log_level: "{{ lookup('env', 'K8S_PM_LOG_LEVEL') or 'WARNING' }}" -kube_pm_debug: "{{ lookup('env', 'K8S_PM_DEBUG') or 'false' }}" -kube_pm_timezone: "{{ lookup('env', 'K8S_PM_TIMEZONE') or 'UTC' }}" -kube_pm_label: "{{ lookup('env', 'CI_COMMIT_SHORT_SHA') }}" - -########## TLS CRT AND KEY POLEMARCH --->>> -k8s_tls_crt: "{{ lookup('env', 'K8S_TLS_CRT') or 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZuVENDQTRXZ0F3SUJBZ0lJSXpNYmVpWUY5QkV3RFFZSktvWklodmNOQVFFTEJRQXdnZjR4Q3pBSkJnTlYKQkFZVEFsSlZNUmN3RlFZRFZRUUlFdzVRY21sdGIzSnphM2tnUzNKaGVURVVNQklHQTFVRUJ4TUxWbXhoWkdsMgpiM04wYjJzeEd6QVpCZ05WQkFvVEVrOVBUeUJXVTFRZ1EyOXVjM1ZzZEdsdVp6RUxNQWtHQTFVRUN4TUNTVlF4CkdqQVlCZ05WQkFNVEVWWlRWQ0JEYjI1emRXeDBhVzVuSUVOQk1Ta3dKd1lKS29aSWh2Y05BUWtCRmhwelpYSm4KWlhrdWEwQjJjM1JqYjI1emRXeDBhVzVuTG01bGRERVBNQTBHQTFVRUVSTUdOamt3TURBd01SQXdEZ1lEVlFRTQpFd2ROWVdsdUlFTkJNU3d3S2dZRFZRUU5FeU5OWVdsdUlFTkJJR1p2Y2lCaGRYUm9iM0pwZEhrZ1lXNTVJSE5sCmNuWnBZMlZ6TGpBZUZ3MHhPVEV5TVRZd056TXlNREJhRncweU5ERXlNVFl3TnpNeU1EQmFNSUd4TVFzd0NRWUQKVlFRR0V3SlNWVEVYTUJVR0ExVUVDQk1PVUhKcGJXOXljMnQ1SUV0eVlYa3hGREFTQmdOVkJBY1RDMVpzWVdScApkbTl6ZEc5ck1Sc3dHUVlEVlFRS0V4SlBUMDhnVmxOVUlFTnZibk4xYkhScGJtY3hHakFZQmdOVkJBc1RFVWxVCklFbHVabkpoYzNSeWRXTjBkWEpsTVNrd0p3WUpLb1pJaHZjTkFRa0JGaHB6WlhKblpYa3VhMEIyYzNSamIyNXoKZFd4MGFXNW5MbTVsZERFUE1BMEdBMVVFRVJNR05qa3dNREF3TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQwpBUThBTUlJQkNnS0NBUUVBMkZVVHZ5ZHl6TTY1RFBvTW9pb3hPSk5RbmIzK2RyVmtuU2gvMm03cWlNOW9GcFNECkVHUm5yZm5rS0RxSlh0cjNtMWZzcXIzZWpMTjhJQVdnOEF0N3FQVXNuOXYweTRTZkh2S1lQUUhwU2VtUGhCMnUKWUxtTTF2WXhWWVJIMXhOeEFXZmg2N3hOSUorLzN0dnc1ZUR5V0NCb2dOUUJubWEvSTdKa2dHOG1xYTRlektERwpPLzRvUHRRanBEL0lrdVpBRm5vRVpmQm5ZWThwTUwwQ1M2U0RHNTVob3h3TTJVeHVKUDVnbEpJS0JhdUhTZFNTCmlvQ1lkTi9UZzRIaVc2K21OWGtIdENmNjhUc0xkK0dIYi9tNm5JT1dySllhY3Fxb3hGSWpGdXNMUjdXd1hyTE0KbUxpYy95LzJZZ3RqeWhEMTJZbDEwRi9WN1N2a1R4cFczNitYOHdJREFRQUJvMm93YURBTUJnTlZIUk1CQWY4RQpBakFBTUIwR0ExVWREZ1FXQkJSa3BlOUpETSthS2JuQVBqZTkvQzBiUnd2M0pqQU9CZ05WSFE4QkFmOEVCQU1DCkJhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0V3RkFZRFZSMFJCQTB3QzRJSktpNTJjM1F1YkdGdU1BMEcKQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUURGMGFSeUdBSVNZQW8zSzRtNGw5Nzc5ZHkwWGNpeUl2WTh3ckZTaXFDSgpFdGhUSWRZZXJwK2JmTjBUbkd4eEtmRVJJZFRKb2xyZ2V4RUY3SEZsaTlMQXg2R0RuVjhQbU1CVThWU0I5cHlHCldVK05BNVVuaTNDa0xtSUFJRlFVOEtBbGlycHhWbkdVMy90VGxlaWZFR2pFNGptM2xLM1VRMDEwYnpYY2hSckwKNTZUeGRQK0hidjFQZHBLSlc1ajMwQ3ZCMHdMWEFNMlJaRXlub25ydUhsMnBSdmh3WEI2Uy9Oc1cyc05tYzd1awpWa0F3TUtEV3kzTE5QeHl1dTRna1hBSmp6Mnd2aGRQTG81LzVoWWRFNEtYMHkvWXhleTg5S2w4ZDArUDdhS2c2CitlWlZRNER5c0JBSG1Tcmh6Q3JTSDRWZE0xbmZvUzNGQmt4c0dYQkRhd3dXNmM4ZloxYnZMcmV4Vmh0OFhVMkMKQmNkYnAzZGpGM3RwdVF2dFYzZXUzUldJRGpNWjNwYUJwYTc1aWNQTFJRZ1BZY1NrMzdjUXhQbFFZL05VYStZUQpaT0JJVTF4Ny8wSG5XY1g1UURnSEpBZEdSdmZBSTRhNlNjQjQ2V2MyOEtYVit2aG0zYXF3MSt3RXlRaWR2djZBCk9HdU00Rnp1aTFHandjWkdhNU45c0hCcGtBYlp1ckxabWVJN21ESXl6cUp1aVlVd2JwUm9pMW9kMUd2MVZRZG0KdEJQTlhmUEhjcmt5NHZjdUhVUkZtVC9JN1I1bXRWd01mc3daSVR1S21CeU4ydHB0Y0l1Zy9pdW52eElKZWxWdwpsd2ozT1UzeFZGcVVUVEVTby9IQTUxdmYrb1A1N2xDUlBpMTByTmVRbk43WHRTNDhjUmw4V2I1RXhCRk1NT1JPCmRBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=' }}" -k8s_tls_key: "{{ lookup('env', 'K8S_TLS_KEY') or 'LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBMkZVVHZ5ZHl6TTY1RFBvTW9pb3hPSk5RbmIzK2RyVmtuU2gvMm03cWlNOW9GcFNECkVHUm5yZm5rS0RxSlh0cjNtMWZzcXIzZWpMTjhJQVdnOEF0N3FQVXNuOXYweTRTZkh2S1lQUUhwU2VtUGhCMnUKWUxtTTF2WXhWWVJIMXhOeEFXZmg2N3hOSUorLzN0dnc1ZUR5V0NCb2dOUUJubWEvSTdKa2dHOG1xYTRlektERwpPLzRvUHRRanBEL0lrdVpBRm5vRVpmQm5ZWThwTUwwQ1M2U0RHNTVob3h3TTJVeHVKUDVnbEpJS0JhdUhTZFNTCmlvQ1lkTi9UZzRIaVc2K21OWGtIdENmNjhUc0xkK0dIYi9tNm5JT1dySllhY3Fxb3hGSWpGdXNMUjdXd1hyTE0KbUxpYy95LzJZZ3RqeWhEMTJZbDEwRi9WN1N2a1R4cFczNitYOHdJREFRQUJBb0lCQUVTbU10NzlLTHYvZWMrNQpaZHJzSXJSK1l4MjdsZzJib0hNUzBBZkVITjhQV2t1WUUwTlhhV05YSW1UMXRuUUlibnk0V1IwUnBaYm11aVA3ClJVZ0hqTlZnQUNvMmhhY3p6YjduWXhJeEVoUG5ieWlRdHE1eEUxVi95TVlIZFRpMkxhMHhod3JrdFdEOThNaEsKNlZZNW5RNEVNc1YzQVpCL3NIWW1mU2dZblo5SVVVUC9KYXpjTWM1UVpzT3Q0YmZEQU5MZXpwQkd0aDVjU3U5SgpSc2VoTENMeWs1L1FqelIzU0VjdDBYaVlFVGNpbEJITFNLVnJ5dGtyYm4rYjg1enZYblR5S1liWGlHci8yK21kClF4Y0FObG1kRTFTeDAzNzlGSG8yMGFJYnc4ZllFUUFldHovcm8wRWZoY01qK01Va2FMNG1TNlhZRkZDR2ZDbHIKOG83Q1RvRUNnWUVBKzNGWGlGejd5VWYzQWQxMTNFQldGQ2Jta2VmRXhqNlRJYUJMSmhBL0JCYlZ2TkFvaFI3QQorU0pGOThxdlhjTkt4VExjeTZ3d2tUNVhrQ3NqbVlQbWhsS2FyRFdXTWVZR1ZmeHFQWCtGeHRDcFBid2RGYlRpCmwra3g0aU15WGhNb0ZkZEJ2cmcwVXo5cHZtajFYOUpnbk5jNzh5T2tSWXZRVFIxS2hrN0Z4VE1DZ1lFQTNFRFQKOWd1WWczNFgwcEJvN3BSY1YzQm1LdXl4bWMvSG5Ma21TcWxTRXgvdC92eHVrMHlkZmx3eVdlbm9kZTlqMjQydApFTFJJWGsyUFVnck5BV1p3dHBBQmhRMFdkMFB5K2ptUEZpL2hRWTZ1azF6bnAxYmhLK0pKVlJFTXlkM1Z0dU5HCkU4cEFGRVIxOWxyNVlvQzZXMUQ0M0ZqMU1lajJHbGMrVjNnWllrRUNnWUJ5ek9Mc0xaZi81RTJRbW01UGEwaGgKMXdqNm9Oa2tzamsyNXhxb2ZFNXBMWXZVc3kxczZnZXROOHErUWRvamN5RFdQRXkyNlIwYmsxMGpRNjd6VGxlWQpDR3I2S1ZVejN4UVJlamQvY0pQQm5FOUpFblF0RHZOTjdIaU1DUW5jRGQ4RmFjeG9xVzJxZkk5cEVqN0Z5eVcxCk5rZjIwTlVWczZvZEt6eDFhYzIrSlFLQmdRQ005Mnp4NkFBSUFMY01qR0tzZUFZVjdKbG5WYkJoeWt0dXNrMmcKc1hnWFIzTlNwSXU4K09kQURaQW9YZjNySlhsYTl2VlNZS0NFd3MwODdDN0RlNlllSWxMbXJqYTN4S1NKcERkQgpNd25QcEp0MU01d01UUjIyc1pEUHdpYldPSVhsRk5jd0tWMFQyN0ZJS0hlK3BMY2haTlN5YXJrYjVZZEYycHJLCjd0SUlRUUtCZ0Y3azdhS0ZZVFowc0NwRUUxQzYrSmp2WVBkMmZ4blVkTy9MWEFoUW1CZG1jYkhHK2J6dytReUcKWGhGTHVya3BsK01rU1U0elRGdEtsbDVCT1RwdzVaa01nNm1rTGhrck1ER1YrNlJFL2k4U21lMU5hcXlxK28xKwppeWtKYlV1WWlkOUpvZ3dHTmFlZWFNWUpCMHVSS3JOMjljajA1dnJxb2trM3hBaUorZjROCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==' }}" diff --git a/environment/deployment_pm.yml.j2 b/environment/deployment_pm.yml.j2 deleted file mode 100644 index 63aa2512..00000000 --- a/environment/deployment_pm.yml.j2 +++ /dev/null @@ -1,302 +0,0 @@ -##### FAQ -# 1. Namespace is indicated when the playbook starts -# 2. For stable work in Rancher, additional annotations and labels are used -# 3. The next step will need to deal with NFS and PV -##### MySQL ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mysql -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:mysql"]' - labels: - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-mysql -{% endif %} -spec: - selector: - matchLabels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-mysql -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - template: - metadata: - labels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-mysql -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - spec: - containers: - - image: mysql:5.7 - name: mysql - env: - - name: MYSQL_USER - value: 'polemarch-user' - - name: MYSQL_PASSWORD - value: 'polemarch-pas' - - name: MYSQL_DATABASE - value: 'polemarch-db' - - name: MYSQL_ROOT_PASSWORD - value: 'polemarch-root' - ports: - - containerPort: 3306 - tty: true - stdin: true - ---- -apiVersion: v1 -kind: Service -metadata: -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:mysql"]' -{% endif %} - name: mysql-svc -spec: - ports: - - name: mysql - port: 3306 - targetPort: 3306 - protocol: TCP -{% if k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - selector: - app: polemarch -{% endif %} - sessionAffinity: None - clusterIP: None - -###### Redis ---- -apiVersion: apps/v1 -kind: Deployment -metadata: -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:redis"]' - labels: - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-redis -{% endif %} - name: redis -spec: - selector: - matchLabels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-redis -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - template: - metadata: - labels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-redis -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - spec: - containers: - - image: redis:latest - name: redis - ports: - - containerPort: 6379 - name: redis - tty: true - stdin: true - ---- -apiVersion: v1 -kind: Service -metadata: -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:redis"]' -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - labels: - app: polemarch -{% endif %} - name: redis-svc -spec: - ports: - - name: redis - port: 6379 - targetPort: 6379 - protocol: TCP -{% if k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - selector: - app: polemarch -{% endif %} - sessionAffinity: None - clusterIP: None - -##### Polemarch ---- -apiVersion: v1 -data: - .dockerconfigjson: "{{ k8s_registry_dockerconfig_base64 | to_json | b64encode }}" -kind: Secret -metadata: - name: gitlab-registry - labels: - appselector: polemarch -type: kubernetes.io/dockerconfigjson - ---- -apiVersion: v1 -kind: Secret -metadata: - name: secretkeyvst -data: - tls.crt: "{{ k8s_tls_crt }}" - tls.key: "{{ k8s_tls_key }}" -type: kubernetes.io/tls - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: polemarch - labels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-polemarch -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - appselector: polemarch - comshort: "{{ kube_pm_label }}" -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:polemarch"]' -{% endif %} -spec: - replicas: {{ kube_pm_replilica_vol }} - selector: - matchLabels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-polemarch -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - template: - metadata: - labels: -{% if k8s_kube_in_rancher=="true" %} - workload.user.cattle.io/workloadselector: deployment-{{ k8s_env_namespace}}-polemarch -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - app: polemarch -{% endif %} - appselector: polemarch - comshort: "{{ kube_pm_label }}" - spec: -{% if (k8s_registry_user is defined) and (k8s_registry_password is defined) and (k8s_registry_url is defined) %} - imagePullSecrets: - - name: gitlab-registry -{% endif %} - containers: - - name: polemarch -{% if (k8s_registry_user is defined) and (k8s_registry_password is defined) and (k8s_registry_url is defined) %} - image: {{ k8s_registry_image_name }}:{{ k8s_registry_image_tag }} -{% endif %} - imagePullPolicy: Always - env: - - name: POLEMARCH_DB_TYPE - value: 'mysql' - - name: POLEMARCH_DB_NAME - value: 'polemarch-db' - - name: POLEMARCH_DB_USER - value: 'polemarch-user' - - name: POLEMARCH_DB_PASSWORD - value: 'polemarch-pas' - - name: POLEMARCH_DB_PORT - value: '3306' - - name: POLEMARCH_DB_HOST - value: 'mysql-svc' - - name: DB_INIT_CMD - value: "SET sql_mode='STRICT_TRANS_TABLES', default_storage_engine=INNODB, NAMES 'utf8', CHARACTER SET 'utf8', SESSION collation_connection = 'utf8_unicode_ci'" - - name: CACHE_LOCATION - value: 'redis://redis:6379/0' - - name: RPC_ENGINE - value: 'redis://redis:6379/1' - - name: RPC_CONCURRENCY - value: '15' - - name: POLEMARCH_LOG_LEVEL - value: '{{ kube_pm_log_level }}' - - name: POLEMARCH_DEBUG - value: '{{ kube_pm_debug }}' - - name: TIMEZONE - value: '{{ kube_pm_timezone }}' - ports: - - containerPort: 8080 - name: 8080tcp - protocol: TCP - tty: true - stdin: true - ---- -apiVersion: v1 -kind: Service -metadata: -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:polemarch"]' -{% endif %} - name: polemarch-svc -spec: - ports: - - name: 8080tcp - port: 8080 - targetPort: 8080 - protocol: TCP - selector: - appselector: polemarch - sessionAffinity: None - type: ClusterIP - -##### Ingress ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: -{% if k8s_kube_in_rancher=="true" %} - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:polemarch"]' -{% endif %} - name: polemarch-ingress -spec: - tls: - - hosts: - - {{ k8s_kube_pm_ingress_domain }} - secretName: secretkeyvst - rules: - - host: {{ k8s_kube_pm_ingress_domain }} - http: - paths: - - path: / - backend: -{% if k8s_kube_in_rancher=="true" %} - serviceName: polemarch-ingress-svc -{% elif k8s_kube_in_rancher=="false" or k8s_kube_in_rancher is not defined %} - serviceName: polemarch-svc -{% endif %} - servicePort: 8080 - -{% if k8s_kube_in_rancher=="true" %} ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - field.cattle.io/targetWorkloadIds: '["deployment:{{ k8s_env_namespace }}:polemarch"]' - name: polemarch-ingress-svc -spec: - ports: - - port: 8080 - targetPort: 8080 - protocol: TCP - type: ClusterIP - sessionAffinity: None -{% endif %} diff --git a/k8s_env_deploy.yaml b/k8s_env_deploy.yaml deleted file mode 100644 index d14bcb78..00000000 --- a/k8s_env_deploy.yaml +++ /dev/null @@ -1,43 +0,0 @@ -- hosts: all - become: yes - vars_files: - - ./environment/all.yml - - vars: - ansible_python_interpreter: "{{ ansible_playbook_python }}" - - tasks: - - - name: GitLab registry LoginIN - docker_login: - username: "{{ k8s_registry_user }}" - password: "{{ k8s_registry_password }}" - registry_url: "{{ k8s_registry_url }}" - docker_host: "{{ k8s_docker_host }}" - reauthorize: yes - - - name: Build Docker image to registry - docker_image: - build: - path: ./ - pull: yes - dockerfile: ./Dockerfile - source: build - docker_host: "{{ k8s_docker_host }}" - name: "{{ k8s_registry_image_name }}" - tag: "{{ k8s_registry_image_tag }}" - push: yes - - - name: Check docker image to registry - docker_image_info: - name: "{{ k8s_registry_image_name }}:{{ k8s_registry_image_tag }}" - docker_host: "{{ k8s_docker_host }}" - timeout: 300 - - - name: Create template YAML file - Polemarch - k8s: - kubeconfig: "{{ k8s_kubeconfig }}" - namespace: "{{ k8s_env_namespace }}" - state: present - definition: "{{ k8s_pm_playbook_template }}" - wait: yes diff --git a/k8s_env_destroy.yaml b/k8s_env_destroy.yaml deleted file mode 100644 index c2ac1a1e..00000000 --- a/k8s_env_destroy.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- hosts: all - become: yes - vars_files: - - ./environment/all.yml - vars: - ansible_python_interpreter: "{{ ansible_playbook_python }}" - - tasks: - - - name: Destroy template YAML file - Polemarch - k8s: - kubeconfig: "{{ k8s_kubeconfig }}" - namespace: "{{ k8s_env_namespace }}" - state: absent - definition: "{{ k8s_pm_playbook_template }}" diff --git a/rpm.mk b/rpm.mk deleted file mode 100755 index f1d9377c..00000000 --- a/rpm.mk +++ /dev/null @@ -1,80 +0,0 @@ -define RPM_SPEC -# Macros -%define name $(NAME) -%define shortname $(NAME) -%define namebase $(NAMEBASE) -%define user $(USER) -%define version $(VER) -%define release $(RELEASE) -%define __prelink_undo_cmd %{nil} -%define _binaries_in_noarch_packages_terminate_build 0 -%define unmangled_version %{version} -# Globals -%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$$!!g') - - -# Tags -Name: %{name} -Version: %{version} -Release: %{release} -Summary: $(SUMMARY) -Group: Application/System -Vendor: $(VENDOR) -License: ${LICENSE} -AutoReq: No -AutoProv: No -BuildRequires: python, openssl-devel, libyaml-devel -Requires: python, openssl-devel -Requires: python-virtualenv -Requires: git -Requires: libyaml-devel -Requires: krb5-devel, krb5-libs, openldap-devel -Requires: mailcap - - -%description -$(DESCRIPTION) - - - -# Blocks -%files -%defattr(-,%{user},%{user},-) -$(INSTALL_DIR) -/etc/%{namebase} -/var/log/%{namebase} -/var/run/%{namebase} -/var/lock/%{namebase} -%attr(755,root,root) /etc/systemd/system/%{shortname}.service -%attr(755,root,root) /etc/tmpfiles.d/%{namebase}.conf - -%pre -id -u %{user} || useradd %{user} -id -g %{user} || groupadd %{user} - -%install -make BUILD_DIR=%{buildroot} - -cd %{buildroot} -cd - - -%post -su - %{user} -c "/opt/%{name}/bin/%{shortname}ctl migrate" -/usr/bin/systemctl daemon-reload -/usr/bin/systemctl enable %{shortname}.service - -%preun -/usr/bin/systemctl disable %{shortname}.service > /dev/null 2>&1 -if [ "$$1" = "0" ]; then - service %{shortname} stop >/dev/null 2>&1 -fi - -%prep -rm -rf %{buildroot}/* -cd %{_topdir}/BUILD -cp -rf $(SOURCE_DIR)/* . - -%clean -rm -rf %{buildroot} -endef -export RPM_SPEC diff --git a/werf.yaml b/werf.yaml index bbc1d26b..b9a9504a 100644 --- a/werf.yaml +++ b/werf.yaml @@ -1,7 +1,7 @@ configVersion: 1 project: polemarch cleanup: - disableKubernetesBasedPolicy: true + disableKubernetesBasedPolicy: false disableGitHistoryBasedPolicy: true disableBuiltWithinLastNHoursPolicy: true keepImagesBuiltWithinLastNHours: 1 From da8e8bc2ae1a67588c930b9683916af235b0fcf1 Mon Sep 17 00:00:00 2001 From: Vladislav Korenkov <vladnfs3@gmail.com> Date: Tue, 20 Dec 2022 15:40:46 +1000 Subject: [PATCH 7/8] Refactoring: Remove ACL handlers --- .gitlab-ci.yml | 2 +- doc/api_schema.yaml | 1760 ++++++++++++++--------------- polemarch/api/v2/permissions.py | 20 +- polemarch/api/v2/serializers.py | 40 +- polemarch/api/v2/views.py | 88 +- polemarch/api/v3/views.py | 2 + polemarch/main/acl/__init__.py | 0 polemarch/main/acl/handlers.py | 39 - polemarch/main/constants.py | 5 + polemarch/main/models/__init__.py | 8 +- polemarch/main/models/base.py | 82 +- polemarch/main/models/hooks.py | 3 +- polemarch/main/models/projects.py | 4 +- polemarch/main/models/tasks.py | 9 +- polemarch/main/models/users.py | 56 +- polemarch/main/models/utils.py | 13 + polemarch/main/models/vars.py | 5 +- polemarch/main/settings.py | 12 +- polemarch/translations/en.py | 3 + polemarch/translations/ru.py | 2 + requirements.txt | 2 +- setup.py | 6 +- tests.py | 47 +- yarn.lock | 504 +++++---- 24 files changed, 1389 insertions(+), 1323 deletions(-) delete mode 100644 polemarch/main/acl/__init__.py delete mode 100644 polemarch/main/acl/handlers.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c830fe1c..ae46ffb1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -56,7 +56,7 @@ stages: <<: *branch_tests image: registry.gitlab.com/vstconsulting/images:node-tests before_script: - - yarn install + - yarn install --pure-lockfile --mutex network script: - yarn test diff --git a/doc/api_schema.yaml b/doc/api_schema.yaml index 959c6fa7..2389f1f8 100644 --- a/doc/api_schema.yaml +++ b/doc/api_schema.yaml @@ -69,7 +69,7 @@ info: x-versions: application: 2.3.0 library: 2.3.0 - vstutils: 5.2.2 + vstutils: 5.2.5 django: 3.2.16 djangorestframework: 3.14.0 drf_yasg: 1.21.4 @@ -11504,14 +11504,11 @@ definitions: usePrefetch: true value_field: name view_field: path - args: - title: Args - description: host pattern - type: string - background: - title: Background - description: run asynchronously, failing after X seconds (default=N/A) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection debugging) type: integer + maximum: 4 become: title: Become description: run operations with become (does not imply password prompting) @@ -11521,57 +11518,36 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string - check: - title: Check - description: don't make any changes; instead, try to predict some of the changes - that may occur - type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string - diff: - title: Diff - description: when changing (small) files and templates, show the differences - in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, if filename - prepend with @ - type: string - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer inventory: title: Inventory description: specify inventory host path or comma separated host list. --inventory-file is deprecated type: string format: inventory - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - one_line: - title: One line - description: condense output - type: boolean - playbook_dir: - title: Playbook dir - description: Since this tool does not use playbooks, use this as a substitute - playbook directory.This sets the relative path for many features including - roles/ group_vars/ etc. + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string poll: title: Poll description: set the poll interval if using -B (default=15) type: integer + background: + title: Background + description: run asynchronously, failing after X seconds (default=N/A) + type: integer + one_line: + title: One line + description: condense output + type: boolean + tree: + title: Tree + description: log output to this directory + type: string private_key: title: Private key description: use this file to authenticate the connection @@ -11580,37 +11556,52 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. -l) + user: + title: User + description: connect as this user (default=None) type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. -f, -l) + connection: + title: Connection + description: connection type to use (default=smart) type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string + check: + title: Check + description: don't make any changes; instead, try to predict some of the changes + that may occur + type: boolean syntax_check: title: Syntax check description: perform a syntax check on the playbook, but do not execute it type: boolean - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - tree: - title: Tree - description: log output to this directory - type: string - user: - title: User - description: connect as this user (default=None) + diff: + title: Diff + description: when changing (small) files and templates, show the differences + in those files; works great with --check + type: boolean + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, if filename + prepend with @ type: string vault_password_file: title: Vault password file @@ -11620,11 +11611,20 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + playbook_dir: + title: Playbook dir + description: Since this tool does not use playbooks, use this as a substitute + playbook directory.This sets the relative path for many features including + roles/ group_vars/ etc. + type: string + args: + title: Args + description: host pattern + type: string group: title: Group type: string @@ -11632,34 +11632,34 @@ definitions: x-properties-groups: '': - module - - args - - background + - verbose - become - become_method - - check - - connection - - diff - - extra_vars - - forks - inventory - - limit - list_hosts - - one_line - - playbook_dir + - limit - poll + - background + - one_line + - tree - private_key - - scp_extra_args - - sftp_extra_args + - user + - connection + - timeout - ssh_common_args + - sftp_extra_args + - scp_extra_args - ssh_extra_args + - check - syntax_check - - timeout - - tree - - user + - diff + - extra_vars - vault_password_file - - verbose + - forks + - playbook_dir + - args - group - x-view-field-name: args + x-view-field-name: verbose ExecuteResponse: required: - detail @@ -11703,10 +11703,55 @@ definitions: usePrefetch: true value_field: playbook view_field: name - args: - title: Args - description: Playbook(s) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection debugging) + type: integer + maximum: 4 + private_key: + title: Private key + description: use this file to authenticate the connection + type: string + format: secretfile + x-options: + media_types: + - '*/*' + user: + title: User + description: connect as this user (default=None) + type: string + connection: + title: Connection + description: connection type to use (default=smart) + type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer + ssh_common_args: + title: Ssh common args + description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) + type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. -l) + type: string + ssh_extra_args: + title: Ssh extra args + description: specify extra arguments to pass to ssh only (e.g. -R) type: string + force_handlers: + title: Force handlers + description: run handlers even if a task fails + type: boolean + flush_cache: + title: Flush cache + description: clear the fact cache for every host in inventory + type: boolean become: title: Become description: run operations with become (does not imply password prompting) @@ -11716,110 +11761,46 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string + tags: + title: Tags + description: only run plays and tasks tagged with these values + type: string + skip_tags: + title: Skip tags + description: only run plays and tasks whose tags do not match these values + type: string check: title: Check description: don't make any changes; instead, try to predict some of the changes that may occur type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string + syntax_check: + title: Syntax check + description: perform a syntax check on the playbook, but do not execute it + type: boolean diff: title: Diff description: when changing (small) files and templates, show the differences in those files; works great with --check type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, if filename - prepend with @ - type: string - flush_cache: - title: Flush cache - description: clear the fact cache for every host in inventory - type: boolean - force_handlers: - title: Force handlers - description: run handlers even if a task fails - type: boolean - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer inventory: title: Inventory description: specify inventory host path or comma separated host list. --inventory-file is deprecated type: string format: inventory - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - list_tags: - title: List tags - description: list all available tags - type: boolean - list_tasks: - title: List tasks - description: list all tasks that would be executed - type: boolean - private_key: - title: Private key - description: use this file to authenticate the connection - type: string - format: secretfile - x-options: - media_types: - - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. -f, -l) - type: string - skip_tags: - title: Skip tags - description: only run plays and tasks whose tags do not match these values - type: string - ssh_common_args: - title: Ssh common args - description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) - type: string - ssh_extra_args: - title: Ssh extra args - description: specify extra arguments to pass to ssh only (e.g. -R) - type: string - start_at_task: - title: Start at task - description: start the playbook at the task matching this name - type: string - step: - title: Step - description: 'one-step-at-a-time: confirm each task before running' - type: boolean - syntax_check: - title: Syntax check - description: perform a syntax check on the playbook, but do not execute it - type: boolean - tags: - title: Tags - description: only run plays and tasks tagged with these values + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - user: - title: User - description: connect as this user (default=None) + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, if filename + prepend with @ type: string vault_password_file: title: Vault password file @@ -11829,44 +11810,63 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + list_tasks: + title: List tasks + description: list all tasks that would be executed + type: boolean + list_tags: + title: List tags + description: list all available tags + type: boolean + step: + title: Step + description: 'one-step-at-a-time: confirm each task before running' + type: boolean + start_at_task: + title: Start at task + description: start the playbook at the task matching this name + type: string + args: + title: Args + description: Playbook(s) + type: string x-properties-groups: '': - playbook - - args + - verbose + - private_key + - user + - connection + - timeout + - ssh_common_args + - sftp_extra_args + - scp_extra_args + - ssh_extra_args + - force_handlers + - flush_cache - become - become_method + - tags + - skip_tags - check - - connection + - syntax_check - diff - - extra_vars - - flush_cache - - force_handlers - - forks - inventory - - limit - list_hosts - - list_tags + - limit + - extra_vars + - vault_password_file + - forks - list_tasks - - private_key - - scp_extra_args - - sftp_extra_args - - skip_tags - - ssh_common_args - - ssh_extra_args - - start_at_task + - list_tags - step - - syntax_check - - tags - - timeout - - user - - vault_password_file - - verbose - x-view-field-name: args + - start_at_task + - args + x-view-field-name: verbose ExecutionTemplate: required: - name @@ -11969,10 +11969,12 @@ definitions: vars: type: object properties: - background: - title: Background - description: run asynchronously, failing after X seconds (default=N/A) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) type: integer + maximum: 4 become: title: Become description: run operations with become (does not imply password @@ -11983,52 +11985,31 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string - check: - title: Check - description: don't make any changes; instead, try to predict - some of the changes that may occur - type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string - diff: - title: Diff - description: when changing (small) files and templates, show - the differences in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, - if filename prepend with @ - type: string - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - one_line: - title: One line - description: condense output - type: boolean - playbook_dir: - title: Playbook dir - description: Since this tool does not use playbooks, use this - as a substitute playbook directory.This sets the relative - path for many features including roles/ group_vars/ etc. + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string poll: title: Poll description: set the poll interval if using -B (default=15) type: integer + background: + title: Background + description: run asynchronously, failing after X seconds (default=N/A) + type: integer + one_line: + title: One line + description: condense output + type: boolean + tree: + title: Tree + description: log output to this directory + type: string private_key: title: Private key description: use this file to authenticate the connection @@ -12037,42 +12018,57 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) + user: + title: User + description: connect as this user (default=None) type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) + connection: + title: Connection + description: connection type to use (default=smart) type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string + check: + title: Check + description: don't make any changes; instead, try to predict + some of the changes that may occur + type: boolean syntax_check: title: Syntax check description: perform a syntax check on the playbook, but do not execute it type: boolean - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - tree: - title: Tree - description: log output to this directory - type: string - user: - title: User - description: connect as this user (default=None) + diff: + title: Diff + description: when changing (small) files and templates, show + the differences in those files; works great with --check + type: boolean + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, + if filename prepend with @ type: string vault_password_file: title: Vault password file @@ -12082,12 +12078,16 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + playbook_dir: + title: Playbook dir + description: Since this tool does not use playbooks, use this + as a substitute playbook directory.This sets the relative + path for many features including roles/ group_vars/ etc. + type: string Task: required: - playbook @@ -12106,10 +12106,60 @@ definitions: vars: type: object properties: - args: - title: Args - description: Playbook(s) - type: string + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) + type: integer + maximum: 4 + private_key: + title: Private key + description: use this file to authenticate the connection + type: string + format: secretfile + x-options: + media_types: + - '*/*' + user: + title: User + description: connect as this user (default=None) + type: string + connection: + title: Connection + description: connection type to use (default=smart) + type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer + ssh_common_args: + title: Ssh common args + description: specify common arguments to pass to sftp/scp/ssh + (e.g. ProxyCommand) + type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string + ssh_extra_args: + title: Ssh extra args + description: specify extra arguments to pass to ssh only (e.g. + -R) + type: string + force_handlers: + title: Force handlers + description: run handlers even if a task fails + type: boolean + flush_cache: + title: Flush cache + description: clear the fact cache for every host in inventory + type: boolean become: title: Become description: run operations with become (does not imply password @@ -12120,126 +12170,76 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string + tags: + title: Tags + description: only run plays and tasks tagged with these values + type: string + skip_tags: + title: Skip tags + description: only run plays and tasks whose tags do not match + these values + type: string check: title: Check description: don't make any changes; instead, try to predict some of the changes that may occur type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string + syntax_check: + title: Syntax check + description: perform a syntax check on the playbook, but do + not execute it + type: boolean diff: title: Diff description: when changing (small) files and templates, show the differences in those files; works great with --check type: boolean + list_hosts: + title: List hosts + description: outputs a list of matching hosts; does not execute + anything else + type: boolean + limit: + title: Limit + description: further limit selected hosts to an additional pattern + type: string extra_vars: title: Extra vars description: set additional variables as key=value or YAML/JSON, if filename prepend with @ type: string - flush_cache: - title: Flush cache - description: clear the fact cache for every host in inventory - type: boolean - force_handlers: - title: Force handlers - description: run handlers even if a task fails - type: boolean + vault_password_file: + title: Vault password file + description: vault password file + type: string + format: secretfile + x-options: + media_types: + - '*/*' forks: title: Forks description: specify number of parallel processes to use (default=5) type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string - list_hosts: - title: List hosts - description: outputs a list of matching hosts; does not execute - anything else + list_tasks: + title: List tasks + description: list all tasks that would be executed type: boolean list_tags: title: List tags description: list all available tags type: boolean - list_tasks: - title: List tasks - description: list all tasks that would be executed - type: boolean - private_key: - title: Private key - description: use this file to authenticate the connection - type: string - format: secretfile - x-options: - media_types: - - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) - type: string - skip_tags: - title: Skip tags - description: only run plays and tasks whose tags do not match - these values - type: string - ssh_common_args: - title: Ssh common args - description: specify common arguments to pass to sftp/scp/ssh - (e.g. ProxyCommand) - type: string - ssh_extra_args: - title: Ssh extra args - description: specify extra arguments to pass to ssh only (e.g. - -R) - type: string - start_at_task: - title: Start at task - description: start the playbook at the task matching this name - type: string step: title: Step description: 'one-step-at-a-time: confirm each task before running' type: boolean - syntax_check: - title: Syntax check - description: perform a syntax check on the playbook, but do - not execute it - type: boolean - tags: - title: Tags - description: only run plays and tasks tagged with these values - type: string - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - user: - title: User - description: connect as this user (default=None) + start_at_task: + title: Start at task + description: start the playbook at the task matching this name type: string - vault_password_file: - title: Vault password file - description: vault password file + args: + title: Args + description: Playbook(s) type: string - format: secretfile - x-options: - media_types: - - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) - type: integer - maximum: 4 x-properties-groups: '': - id @@ -12324,10 +12324,12 @@ definitions: vars: type: object properties: - background: - title: Background - description: run asynchronously, failing after X seconds (default=N/A) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) type: integer + maximum: 4 become: title: Become description: run operations with become (does not imply password @@ -12338,52 +12340,31 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string - check: - title: Check - description: don't make any changes; instead, try to predict - some of the changes that may occur - type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string - diff: - title: Diff - description: when changing (small) files and templates, show - the differences in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, - if filename prepend with @ - type: string - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - one_line: - title: One line - description: condense output - type: boolean - playbook_dir: - title: Playbook dir - description: Since this tool does not use playbooks, use this - as a substitute playbook directory.This sets the relative - path for many features including roles/ group_vars/ etc. + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string poll: title: Poll description: set the poll interval if using -B (default=15) type: integer + background: + title: Background + description: run asynchronously, failing after X seconds (default=N/A) + type: integer + one_line: + title: One line + description: condense output + type: boolean + tree: + title: Tree + description: log output to this directory + type: string private_key: title: Private key description: use this file to authenticate the connection @@ -12392,42 +12373,57 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) + user: + title: User + description: connect as this user (default=None) type: string - ssh_common_args: + connection: + title: Connection + description: connection type to use (default=smart) + type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer + ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string + check: + title: Check + description: don't make any changes; instead, try to predict + some of the changes that may occur + type: boolean syntax_check: title: Syntax check description: perform a syntax check on the playbook, but do not execute it type: boolean - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - tree: - title: Tree - description: log output to this directory - type: string - user: - title: User - description: connect as this user (default=None) + diff: + title: Diff + description: when changing (small) files and templates, show + the differences in those files; works great with --check + type: boolean + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, + if filename prepend with @ type: string vault_password_file: title: Vault password file @@ -12437,12 +12433,16 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + playbook_dir: + title: Playbook dir + description: Since this tool does not use playbooks, use this + as a substitute playbook directory.This sets the relative + path for many features including roles/ group_vars/ etc. + type: string Task: required: - playbook @@ -12461,10 +12461,60 @@ definitions: vars: type: object properties: - args: - title: Args - description: Playbook(s) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) + type: integer + maximum: 4 + private_key: + title: Private key + description: use this file to authenticate the connection + type: string + format: secretfile + x-options: + media_types: + - '*/*' + user: + title: User + description: connect as this user (default=None) + type: string + connection: + title: Connection + description: connection type to use (default=smart) + type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer + ssh_common_args: + title: Ssh common args + description: specify common arguments to pass to sftp/scp/ssh + (e.g. ProxyCommand) + type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string + ssh_extra_args: + title: Ssh extra args + description: specify extra arguments to pass to ssh only (e.g. + -R) + type: string + force_handlers: + title: Force handlers + description: run handlers even if a task fails + type: boolean + flush_cache: + title: Flush cache + description: clear the fact cache for every host in inventory + type: boolean become: title: Become description: run operations with become (does not imply password @@ -12475,126 +12525,76 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string + tags: + title: Tags + description: only run plays and tasks tagged with these values + type: string + skip_tags: + title: Skip tags + description: only run plays and tasks whose tags do not match + these values + type: string check: title: Check description: don't make any changes; instead, try to predict some of the changes that may occur type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string + syntax_check: + title: Syntax check + description: perform a syntax check on the playbook, but do + not execute it + type: boolean diff: title: Diff description: when changing (small) files and templates, show the differences in those files; works great with --check type: boolean + list_hosts: + title: List hosts + description: outputs a list of matching hosts; does not execute + anything else + type: boolean + limit: + title: Limit + description: further limit selected hosts to an additional pattern + type: string extra_vars: title: Extra vars description: set additional variables as key=value or YAML/JSON, if filename prepend with @ type: string - flush_cache: - title: Flush cache - description: clear the fact cache for every host in inventory - type: boolean - force_handlers: - title: Force handlers - description: run handlers even if a task fails - type: boolean + vault_password_file: + title: Vault password file + description: vault password file + type: string + format: secretfile + x-options: + media_types: + - '*/*' forks: title: Forks description: specify number of parallel processes to use (default=5) type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string - list_hosts: - title: List hosts - description: outputs a list of matching hosts; does not execute - anything else + list_tasks: + title: List tasks + description: list all tasks that would be executed type: boolean list_tags: title: List tags description: list all available tags type: boolean - list_tasks: - title: List tasks - description: list all tasks that would be executed - type: boolean - private_key: - title: Private key - description: use this file to authenticate the connection - type: string - format: secretfile - x-options: - media_types: - - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) - type: string - skip_tags: - title: Skip tags - description: only run plays and tasks whose tags do not match - these values - type: string - ssh_common_args: - title: Ssh common args - description: specify common arguments to pass to sftp/scp/ssh - (e.g. ProxyCommand) - type: string - ssh_extra_args: - title: Ssh extra args - description: specify extra arguments to pass to ssh only (e.g. - -R) - type: string - start_at_task: - title: Start at task - description: start the playbook at the task matching this name - type: string step: title: Step description: 'one-step-at-a-time: confirm each task before running' type: boolean - syntax_check: - title: Syntax check - description: perform a syntax check on the playbook, but do - not execute it - type: boolean - tags: - title: Tags - description: only run plays and tasks tagged with these values - type: string - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - user: - title: User - description: connect as this user (default=None) + start_at_task: + title: Start at task + description: start the playbook at the task matching this name type: string - vault_password_file: - title: Vault password file - description: vault password file + args: + title: Args + description: Playbook(s) type: string - format: secretfile - x-options: - media_types: - - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) - type: integer - maximum: 4 x-properties-groups: '': - id @@ -12701,10 +12701,12 @@ definitions: vars: type: object properties: - background: - title: Background - description: run asynchronously, failing after X seconds (default=N/A) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) type: integer + maximum: 4 become: title: Become description: run operations with become (does not imply password @@ -12715,52 +12717,31 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string - check: - title: Check - description: don't make any changes; instead, try to predict - some of the changes that may occur - type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string - diff: - title: Diff - description: when changing (small) files and templates, show - the differences in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, - if filename prepend with @ - type: string - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - one_line: - title: One line - description: condense output - type: boolean - playbook_dir: - title: Playbook dir - description: Since this tool does not use playbooks, use this - as a substitute playbook directory.This sets the relative - path for many features including roles/ group_vars/ etc. + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string poll: title: Poll description: set the poll interval if using -B (default=15) type: integer + background: + title: Background + description: run asynchronously, failing after X seconds (default=N/A) + type: integer + one_line: + title: One line + description: condense output + type: boolean + tree: + title: Tree + description: log output to this directory + type: string private_key: title: Private key description: use this file to authenticate the connection @@ -12769,42 +12750,57 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) + user: + title: User + description: connect as this user (default=None) type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) + connection: + title: Connection + description: connection type to use (default=smart) type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string + check: + title: Check + description: don't make any changes; instead, try to predict + some of the changes that may occur + type: boolean syntax_check: title: Syntax check description: perform a syntax check on the playbook, but do not execute it type: boolean - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - tree: - title: Tree - description: log output to this directory - type: string - user: - title: User - description: connect as this user (default=None) + diff: + title: Diff + description: when changing (small) files and templates, show + the differences in those files; works great with --check + type: boolean + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, + if filename prepend with @ type: string vault_password_file: title: Vault password file @@ -12814,12 +12810,16 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + playbook_dir: + title: Playbook dir + description: Since this tool does not use playbooks, use this + as a substitute playbook directory.This sets the relative + path for many features including roles/ group_vars/ etc. + type: string Task: required: - playbook @@ -12838,10 +12838,60 @@ definitions: vars: type: object properties: - args: - title: Args - description: Playbook(s) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) + type: integer + maximum: 4 + private_key: + title: Private key + description: use this file to authenticate the connection + type: string + format: secretfile + x-options: + media_types: + - '*/*' + user: + title: User + description: connect as this user (default=None) type: string + connection: + title: Connection + description: connection type to use (default=smart) + type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer + ssh_common_args: + title: Ssh common args + description: specify common arguments to pass to sftp/scp/ssh + (e.g. ProxyCommand) + type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string + ssh_extra_args: + title: Ssh extra args + description: specify extra arguments to pass to ssh only (e.g. + -R) + type: string + force_handlers: + title: Force handlers + description: run handlers even if a task fails + type: boolean + flush_cache: + title: Flush cache + description: clear the fact cache for every host in inventory + type: boolean become: title: Become description: run operations with become (does not imply password @@ -12852,126 +12902,76 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string + tags: + title: Tags + description: only run plays and tasks tagged with these values + type: string + skip_tags: + title: Skip tags + description: only run plays and tasks whose tags do not match + these values + type: string check: title: Check description: don't make any changes; instead, try to predict some of the changes that may occur type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string + syntax_check: + title: Syntax check + description: perform a syntax check on the playbook, but do + not execute it + type: boolean diff: title: Diff description: when changing (small) files and templates, show the differences in those files; works great with --check type: boolean + list_hosts: + title: List hosts + description: outputs a list of matching hosts; does not execute + anything else + type: boolean + limit: + title: Limit + description: further limit selected hosts to an additional pattern + type: string extra_vars: title: Extra vars description: set additional variables as key=value or YAML/JSON, if filename prepend with @ type: string - flush_cache: - title: Flush cache - description: clear the fact cache for every host in inventory - type: boolean - force_handlers: - title: Force handlers - description: run handlers even if a task fails - type: boolean + vault_password_file: + title: Vault password file + description: vault password file + type: string + format: secretfile + x-options: + media_types: + - '*/*' forks: title: Forks description: specify number of parallel processes to use (default=5) type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string - list_hosts: - title: List hosts - description: outputs a list of matching hosts; does not execute - anything else + list_tasks: + title: List tasks + description: list all tasks that would be executed type: boolean list_tags: title: List tags description: list all available tags type: boolean - list_tasks: - title: List tasks - description: list all tasks that would be executed - type: boolean - private_key: - title: Private key - description: use this file to authenticate the connection - type: string - format: secretfile - x-options: - media_types: - - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) - type: string - skip_tags: - title: Skip tags - description: only run plays and tasks whose tags do not match - these values - type: string - ssh_common_args: - title: Ssh common args - description: specify common arguments to pass to sftp/scp/ssh - (e.g. ProxyCommand) - type: string - ssh_extra_args: - title: Ssh extra args - description: specify extra arguments to pass to ssh only (e.g. - -R) - type: string - start_at_task: - title: Start at task - description: start the playbook at the task matching this name - type: string step: title: Step description: 'one-step-at-a-time: confirm each task before running' type: boolean - syntax_check: - title: Syntax check - description: perform a syntax check on the playbook, but do - not execute it - type: boolean - tags: - title: Tags - description: only run plays and tasks tagged with these values - type: string - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - user: - title: User - description: connect as this user (default=None) + start_at_task: + title: Start at task + description: start the playbook at the task matching this name type: string - vault_password_file: - title: Vault password file - description: vault password file + args: + title: Args + description: Playbook(s) type: string - format: secretfile - x-options: - media_types: - - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) - type: integer - maximum: 4 x-properties-groups: '': - id @@ -13034,10 +13034,12 @@ definitions: vars: type: object properties: - background: - title: Background - description: run asynchronously, failing after X seconds (default=N/A) + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) type: integer + maximum: 4 become: title: Become description: run operations with become (does not imply password @@ -13048,52 +13050,31 @@ definitions: description: privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. type: string - check: - title: Check - description: don't make any changes; instead, try to predict - some of the changes that may occur - type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string - diff: - title: Diff - description: when changing (small) files and templates, show - the differences in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, - if filename prepend with @ - type: string - forks: - title: Forks - description: specify number of parallel processes to use (default=5) - type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern - type: string list_hosts: title: List hosts description: outputs a list of matching hosts; does not execute anything else type: boolean - one_line: - title: One line - description: condense output - type: boolean - playbook_dir: - title: Playbook dir - description: Since this tool does not use playbooks, use this - as a substitute playbook directory.This sets the relative - path for many features including roles/ group_vars/ etc. + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string poll: title: Poll description: set the poll interval if using -B (default=15) type: integer + background: + title: Background + description: run asynchronously, failing after X seconds (default=N/A) + type: integer + one_line: + title: One line + description: condense output + type: boolean + tree: + title: Tree + description: log output to this directory + type: string private_key: title: Private key description: use this file to authenticate the connection @@ -13102,137 +13083,100 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) + user: + title: User + description: connect as this user (default=None) type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) + connection: + title: Connection + description: connection type to use (default=smart) type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string - syntax_check: - title: Syntax check - description: perform a syntax check on the playbook, but do - not execute it - type: boolean - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - tree: - title: Tree - description: log output to this directory - type: string - user: - title: User - description: connect as this user (default=None) - type: string - vault_password_file: - title: Vault password file - description: vault password file - type: string - format: secretfile - x-options: - media_types: - - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) - type: integer - maximum: 4 - Task: - required: - - playbook - type: object - properties: - playbook: - title: Playbook - type: string - format: fk_autocomplete - x-options: - model: - $ref: '#/definitions/Playbook' - usePrefetch: true - value_field: playbook - view_field: playbook - vars: - type: object - properties: - args: - title: Args - description: Playbook(s) - type: string - become: - title: Become - description: run operations with become (does not imply password - prompting) - type: boolean - become_method: - title: Become method - description: privilege escalation method to use (default=sudo), - use `ansible-doc -t become -l` to list valid choices. - type: string check: title: Check description: don't make any changes; instead, try to predict some of the changes that may occur type: boolean - connection: - title: Connection - description: connection type to use (default=smart) - type: string + syntax_check: + title: Syntax check + description: perform a syntax check on the playbook, but do + not execute it + type: boolean diff: title: Diff - description: when changing (small) files and templates, show - the differences in those files; works great with --check - type: boolean - extra_vars: - title: Extra vars - description: set additional variables as key=value or YAML/JSON, - if filename prepend with @ - type: string - flush_cache: - title: Flush cache - description: clear the fact cache for every host in inventory - type: boolean - force_handlers: - title: Force handlers - description: run handlers even if a task fails + description: when changing (small) files and templates, show + the differences in those files; works great with --check type: boolean + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, + if filename prepend with @ + type: string + vault_password_file: + title: Vault password file + description: vault password file + type: string + format: secretfile + x-options: + media_types: + - '*/*' forks: title: Forks description: specify number of parallel processes to use (default=5) type: integer - limit: - title: Limit - description: further limit selected hosts to an additional pattern + playbook_dir: + title: Playbook dir + description: Since this tool does not use playbooks, use this + as a substitute playbook directory.This sets the relative + path for many features including roles/ group_vars/ etc. type: string - list_hosts: - title: List hosts - description: outputs a list of matching hosts; does not execute - anything else - type: boolean - list_tags: - title: List tags - description: list all available tags - type: boolean - list_tasks: - title: List tasks - description: list all tasks that would be executed - type: boolean + Task: + required: + - playbook + type: object + properties: + playbook: + title: Playbook + type: string + format: fk_autocomplete + x-options: + model: + $ref: '#/definitions/Playbook' + usePrefetch: true + value_field: playbook + view_field: playbook + vars: + type: object + properties: + verbose: + title: Verbose + description: verbose mode (-vvv for more, -vvvv to enable connection + debugging) + type: integer + maximum: 4 private_key: title: Private key description: use this file to authenticate the connection @@ -13241,55 +13185,93 @@ definitions: x-options: media_types: - '*/*' - scp_extra_args: - title: Scp extra args - description: specify extra arguments to pass to scp only (e.g. - -l) - type: string - sftp_extra_args: - title: Sftp extra args - description: specify extra arguments to pass to sftp only (e.g. - -f, -l) + user: + title: User + description: connect as this user (default=None) type: string - skip_tags: - title: Skip tags - description: only run plays and tasks whose tags do not match - these values + connection: + title: Connection + description: connection type to use (default=smart) type: string + timeout: + title: Timeout + description: override the connection timeout in seconds (default=10) + type: integer ssh_common_args: title: Ssh common args description: specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) type: string + sftp_extra_args: + title: Sftp extra args + description: specify extra arguments to pass to sftp only (e.g. + -f, -l) + type: string + scp_extra_args: + title: Scp extra args + description: specify extra arguments to pass to scp only (e.g. + -l) + type: string ssh_extra_args: title: Ssh extra args description: specify extra arguments to pass to ssh only (e.g. -R) type: string - start_at_task: - title: Start at task - description: start the playbook at the task matching this name + force_handlers: + title: Force handlers + description: run handlers even if a task fails + type: boolean + flush_cache: + title: Flush cache + description: clear the fact cache for every host in inventory + type: boolean + become: + title: Become + description: run operations with become (does not imply password + prompting) + type: boolean + become_method: + title: Become method + description: privilege escalation method to use (default=sudo), + use `ansible-doc -t become -l` to list valid choices. type: string - step: - title: Step - description: 'one-step-at-a-time: confirm each task before running' + tags: + title: Tags + description: only run plays and tasks tagged with these values + type: string + skip_tags: + title: Skip tags + description: only run plays and tasks whose tags do not match + these values + type: string + check: + title: Check + description: don't make any changes; instead, try to predict + some of the changes that may occur type: boolean syntax_check: title: Syntax check description: perform a syntax check on the playbook, but do not execute it type: boolean - tags: - title: Tags - description: only run plays and tasks tagged with these values + diff: + title: Diff + description: when changing (small) files and templates, show + the differences in those files; works great with --check + type: boolean + list_hosts: + title: List hosts + description: outputs a list of matching hosts; does not execute + anything else + type: boolean + limit: + title: Limit + description: further limit selected hosts to an additional pattern type: string - timeout: - title: Timeout - description: override the connection timeout in seconds (default=10) - type: integer - user: - title: User - description: connect as this user (default=None) + extra_vars: + title: Extra vars + description: set additional variables as key=value or YAML/JSON, + if filename prepend with @ type: string vault_password_file: title: Vault password file @@ -13299,12 +13281,30 @@ definitions: x-options: media_types: - '*/*' - verbose: - title: Verbose - description: verbose mode (-vvv for more, -vvvv to enable connection - debugging) + forks: + title: Forks + description: specify number of parallel processes to use (default=5) type: integer - maximum: 4 + list_tasks: + title: List tasks + description: list all tasks that would be executed + type: boolean + list_tags: + title: List tags + description: list all available tags + type: boolean + step: + title: Step + description: 'one-step-at-a-time: confirm each task before running' + type: boolean + start_at_task: + title: Start at task + description: start the playbook at the task matching this name + type: string + args: + title: Args + description: Playbook(s) + type: string x-properties-groups: '': - id @@ -13794,63 +13794,63 @@ definitions: types: MODULE: enum: - - args - - background + - verbose - become - become_method - - check - - connection - - diff - - extra_vars - - forks - - limit - list_hosts - - one_line - - playbook_dir + - limit - poll + - background + - one_line + - tree - private_key - - scp_extra_args - - sftp_extra_args + - user + - connection + - timeout - ssh_common_args + - sftp_extra_args + - scp_extra_args - ssh_extra_args + - check - syntax_check - - timeout - - tree - - user + - diff + - extra_vars - vault_password_file - - verbose + - forks + - playbook_dir + - args - group type: string PLAYBOOK: enum: - - args + - verbose + - private_key + - user + - connection + - timeout + - ssh_common_args + - sftp_extra_args + - scp_extra_args + - ssh_extra_args + - force_handlers + - flush_cache - become - become_method + - tags + - skip_tags - check - - connection + - syntax_check - diff + - list_hosts + - limit - extra_vars - - flush_cache - - force_handlers + - vault_password_file - forks - - limit - - list_hosts - - list_tags - list_tasks - - private_key - - scp_extra_args - - sftp_extra_args - - skip_tags - - ssh_common_args - - ssh_extra_args - - start_at_task + - list_tags - step - - syntax_check - - tags - - timeout - - user - - vault_password_file - - verbose + - start_at_task + - args type: string value: format: dynamic diff --git a/polemarch/api/v2/permissions.py b/polemarch/api/v2/permissions.py index 00900562..4f886c75 100644 --- a/polemarch/api/v2/permissions.py +++ b/polemarch/api/v2/permissions.py @@ -1,21 +1,19 @@ from rest_framework import permissions +from vstutils.utils import lazy_translate as __ -class ModelPermission(permissions.IsAuthenticated): +class CreateTeamPermission(permissions.IsAuthenticated): def has_permission(self, request, view): - # pylint: disable=useless-super-delegation - return super().has_permission(request, view) - - def get_user_permission(self, request, view, obj): # nocv - # pylint: disable=unused-argument - if hasattr(obj, 'owner') and obj.owner == request.user: + if request.method == 'GET': return True - return False + return request.user.is_superuser or request.user.is_staff + + +class SetOwnerPermission(permissions.IsAuthenticated): + message = __('Only owner can change owner.') def has_object_permission(self, request, view, obj): - if request.user.is_staff: - return True - return self.get_user_permission(request, view, obj) # nocv + return request.user.is_superuser or obj.owner == request.user class InventoryItemsPermission(permissions.IsAuthenticated): diff --git a/polemarch/api/v2/serializers.py b/polemarch/api/v2/serializers.py index 02c69901..c4f4a8c7 100644 --- a/polemarch/api/v2/serializers.py +++ b/polemarch/api/v2/serializers.py @@ -10,7 +10,7 @@ from django.contrib.auth import get_user_model from django.db import transaction -from rest_framework import serializers, exceptions +from rest_framework import serializers from vstutils.api import auth as vst_auth from vstutils.api import serializers as vst_serializers, fields as vst_fields @@ -76,11 +76,6 @@ def to_internal_value(self, data): inventory = super().to_internal_value(data) try: inventory = models.Inventory.objects.get(id=int(inventory)) - user = self.context['request'].user - if not inventory.acl_handler.viewable_by(user): - raise exceptions.PermissionDenied( - "You don't have permission to inventory." - ) # noce except (ValueError, KeyError): if ',' not in inventory: path_validator(inventory) @@ -109,30 +104,13 @@ class ExecuteResponseSerializer(ActionResponseSerializer): executor = serializers.IntegerField(default=None, allow_null=True) -class SetOwnerSerializer(DataSerializer): - perms_msg = 'Permission denied. Only owner can change owner.' - user_id = vst_fields.FkField(required=True, select='User', - label='New owner', - autocomplete_represent='username') - - def update(self, instance, validated_data): - if not self.instance.acl_handler.owned_by(self.current_user()): # noce - raise exceptions.PermissionDenied(self.perms_msg) - user = self.get_user(validated_data) - self.instance.acl_handler.set_owner(user) - return user - - def get_user(self, validated_data: dict): - return User.objects.get(**validated_data) - - def current_user(self) -> User: - return self.context['request'].user - - def to_representation(self, value: User): # pylint: disable=arguments-renamed - return dict(user_id=value.pk) - - def to_internal_value(self, data: dict): - return dict(pk=data['user_id']) +class SetOwnerSerializer(BaseSerializer): + user_id = vst_fields.FkField( + required=True, + select='User', + label='New owner', + autocomplete_represent='username' + ) class CreateUserSerializer(vst_auth.CreateUserSerializer): # noee @@ -860,7 +838,7 @@ class DashboardJobsSerializer(DataSerializer): year = YearDashboardJobSerializer(many=True) -class DashboardStatisticSerializer(DataSerializer): +class DashboardStatisticsSerializer(DataSerializer): projects = serializers.IntegerField() templates = serializers.IntegerField() inventories = serializers.IntegerField() diff --git a/polemarch/api/v2/views.py b/polemarch/api/v2/views.py index c8f8e450..1ebd0479 100644 --- a/polemarch/api/v2/views.py +++ b/polemarch/api/v2/views.py @@ -1,5 +1,4 @@ # pylint: disable=unused-argument,protected-access,too-many-ancestors -from collections import OrderedDict from django.db import transaction from django.http.response import HttpResponse @@ -14,10 +13,16 @@ from vstutils.api.responses import HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT from . import filters -from .permissions import InventoryItemsPermission, CreateUsersPermission +from .permissions import ( + InventoryItemsPermission, + CreateUsersPermission, + SetOwnerPermission, + CreateTeamPermission, +) from . import serializers as sers from ..v3 import serializers as sers3 from ...main import utils +from ...main.models.base import ACLModel yes = True no = False @@ -55,18 +60,22 @@ def copy_instance(self, instance): class OwnedView(base.ModelViewSet, base.CopyMixin): POST_WHITE_LIST = [] - @deco.action(methods=["post"], detail=True, serializer_class=sers.SetOwnerSerializer) + @deco.action( + methods=["post"], + detail=True, + serializer_class=sers.SetOwnerSerializer, + permission_classes=(SetOwnerPermission,) + ) def set_owner(self, request, **kwargs): # pylint: disable=unused-argument """ Change instance owner. """ - serializer = sers.SetOwnerSerializer( - self.get_object(), data=request.data, context=self.get_serializer_context() - ) + serializer = self.get_serializer(data=request.data) + instance: ACLModel = self.get_object() serializer.is_valid(raise_exception=True) - serializer.save() - return HTTP_201_CREATED(serializer.data) + instance.set_owner(serializer.validated_data['user_id']) + return HTTP_201_CREATED(serializer.validated_data) class __VarsViewSet(base.ModelViewSet): @@ -240,6 +249,7 @@ class TeamViewSet(OwnedView): serializer_class_one = sers.OneTeamSerializer filterset_class = filters.TeamFilter copy_related = ['users'] + permission_classes = list(OwnedView.permission_classes) + [CreateTeamPermission] class __HistoryLineViewSet(base.ReadOnlyModelViewSet): @@ -760,36 +770,44 @@ class HookViewSet(base.ModelViewSet): @method_decorator(name='list', decorator=swagger_auto_schema( - operation_description='Dashboard statistic.', - responses={status.HTTP_200_OK: sers.DashboardStatisticSerializer(), } + operation_description='Dashboard statistics.', + responses={status.HTTP_200_OK: sers.DashboardStatisticsSerializer()} )) -class StatisticViewSet(base.ListNonModelViewSet): +class StatisticsViewSet(base.ListNonModelViewSet): base_name = "stats" - def _get_by_user(self, model): - user = self.request.user - filter_models = (sers.User,) - if model not in filter_models: - return model.objects.all().user_filter(user) - return model.objects.all() + def _get_projects_count(self): # noee + return sers.models.Project.objects.count() - def _get_history_stats(self, request): - qs = sers.models.History.objects.all() - qs = qs.user_filter(self.request.user) - return qs.stats(int(request.query_params.get("last", "14"))) + def _get_templates_count(self): # noee + return sers.models.Template.objects.count() - def _get_by_user_projects(self, model): - return model.objects.filter(project__in=self._get_by_user(sers.models.Project).values('id')) + def _get_inventories_count(self): # noee + return sers.models.Inventory.objects.count() - def list(self, request, *args, **kwargs): - # pylint: disable=unused-argument - stats = OrderedDict() - stats['projects'] = self._get_by_user(sers.models.Project).count() - stats['templates'] = self._get_by_user_projects(sers.models.Template).count() - stats['inventories'] = self._get_by_user(sers.models.Inventory).count() - stats['groups'] = self._get_by_user(sers.models.Group).count() - stats['hosts'] = self._get_by_user(sers.models.Host).count() - stats['teams'] = self._get_by_user(sers.models.UserGroup).count() - stats['users'] = self._get_by_user(sers.User).count() - stats['jobs'] = self._get_history_stats(request) - return HTTP_200_OK(stats) + def _get_groups_count(self): # noee + return sers.models.Group.objects.count() + + def _get_hosts_count(self): # noee + return sers.models.Host.objects.count() + + def _get_teams_count(self): # noee + return sers.models.UserGroup.objects.count() + + def _get_users_count(self): # noee + return sers.User.objects.count() + + def _get_history_stats(self): # noee + return sers.models.History.objects.stats(int(self.request.query_params.get("last", "14"))) + + def list(self, *args, **kwargs): + return HTTP_200_OK({ + 'projects': self._get_projects_count(), + 'templates': self._get_templates_count(), + 'inventories': self._get_inventories_count(), + 'groups': self._get_groups_count(), + 'hosts': self._get_hosts_count(), + 'teams': self._get_teams_count(), + 'users': self._get_users_count(), + 'jobs': self._get_history_stats(), + }) diff --git a/polemarch/api/v3/views.py b/polemarch/api/v3/views.py index f88fd690..d7cc4295 100644 --- a/polemarch/api/v3/views.py +++ b/polemarch/api/v3/views.py @@ -6,6 +6,7 @@ from vstutils.api.responses import HTTP_201_CREATED from vstutils.utils import create_view, translate as _ +from ...main.models.utils import ensure_inventory_is_from_project from ...main.models import TemplateOption, Group, Project from ...main.executions import PLUGIN_HANDLERS from ..v2.filters import variables_filter, vars_help @@ -128,6 +129,7 @@ def action(self, request, plugin=plugin, *args, **kwargs): project: Project = self.get_object() data = serializer.validated_data + ensure_inventory_is_from_project(data.get('inventory'), project) history_id = project.execute(plugin, executor=request.user, execute_args=data) response_serializer = ExecuteResponseSerializer(instance={ diff --git a/polemarch/main/acl/__init__.py b/polemarch/main/acl/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/polemarch/main/acl/handlers.py b/polemarch/main/acl/handlers.py deleted file mode 100644 index 4300548a..00000000 --- a/polemarch/main/acl/handlers.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Optional, Type -from django.db.models import Model - - -class Default: - # pylint: disable=unused-argument - qs_methods = [] - - def __init__(self, model: Optional[Type[Model]] = None, instance=None): - self.instance = instance - self.model = model - - def set_owner(self, user): - ''' - Set object owner. - - :param user: - :return: - ''' - self.instance.owner = user - self.instance.save() - - def owned_by(self, user): - return user.is_staff or (getattr(self.instance, 'owner', None) == user) - - def manageable_by(self, user): # nocv - return True - - def editable_by(self, user): # nocv - return True - - def viewable_by(self, user): - return True - - def user_filter(self, qs, user, role=None): - return qs - - def qs_create(self, original_method, **kwargs): - return original_method(**kwargs) diff --git a/polemarch/main/constants.py b/polemarch/main/constants.py index ff5f9834..593f3f54 100644 --- a/polemarch/main/constants.py +++ b/polemarch/main/constants.py @@ -9,6 +9,11 @@ TEMPLATE_KINDS_MAP = {'PLAYBOOK': 'Task', 'MODULE': 'Module'} +class MemberType(BaseEnum): + USER = BaseEnum.LOWER + TEAM = BaseEnum.LOWER + + class BaseVariablesEnum(BaseEnum): @classmethod @lru_cache() diff --git a/polemarch/main/models/__init__.py b/polemarch/main/models/__init__.py index 11254efd..c5e10abb 100644 --- a/polemarch/main/models/__init__.py +++ b/polemarch/main/models/__init__.py @@ -26,6 +26,7 @@ from ..validators import RegexValidator, validate_hostname, path_validator from ..exceptions import UnknownTypeException, Conflict from ..utils import CmdExecutor +from .utils import ensure_inventory_is_from_project from ...main.constants import ProjectVariablesEnum, ANSIBLE_REFERENCE @@ -149,12 +150,10 @@ def check_circular_deps(instance: Group, action: Text, pk_set: Iterable, *args, @receiver(signals.pre_save, sender=PeriodicTask) -def validate_types(instance: PeriodicTask, **kwargs) -> None: +def validate_inventory(instance: PeriodicTask, **kwargs) -> None: if 'loaddata' in sys.argv or kwargs.get('raw', False): # nocv return - if (instance.kind not in instance.kinds) or (instance.type not in instance.types): - # Deprecated, because moved to serializers - raise UnknownTypeException(instance.kind, "Unknown kind {}.") # nocv + ensure_inventory_is_from_project(instance.inventory, instance.project) @receiver(signals.pre_save, sender=PeriodicTask) @@ -200,6 +199,7 @@ def validate_template_keys(instance: Template, **kwargs) -> None: def validate_template_args(instance: Template, **kwargs) -> None: if 'loaddata' in sys.argv or kwargs.get('raw', False): # nocv return + ensure_inventory_is_from_project(instance.inventory, instance.project) if instance.kind in ["Host", "Group"]: return # nocv ansible_args = dict(instance.data['vars']) diff --git a/polemarch/main/models/base.py b/polemarch/main/models/base.py index f1affeb6..f5833b46 100644 --- a/polemarch/main/models/base.py +++ b/polemarch/main/models/base.py @@ -1,82 +1,16 @@ # pylint: disable=no-name-in-module from __future__ import unicode_literals -from typing import Callable, Any +from typing import Any from django.db import models -from django.conf import settings from django.contrib.auth import get_user_model -from django.utils.module_loading import import_string -from vstutils.utils import classproperty -from vstutils.models import BQuerySet as _BQSet, BaseModel as _BM, Manager as _BManager +from vstutils.models import BModel -def first_staff_user() -> int: - return get_user_model().objects.filter(is_staff=True).first().id - - -class BQuerySet(_BQSet): - use_for_related_fields = True - - def __decorator(self, func: Callable) -> Callable: # noce - def wrapper(*args, **kwargs): - return func(self, *args, **kwargs) - - return wrapper - - def __getattribute__(self, item: str) -> Any: - try: - return super().__getattribute__(item) - except: - model = super().__getattribute__("model") - if model and item in model.acl_handler.qs_methods: # noce - return self.__decorator(getattr(model.acl_handler, "qs_{}".format(item))) - raise +User = get_user_model() - def create(self, **kwargs) -> _BM: - return self.model.acl_handler.qs_create(super().create, **kwargs) - def user_filter(self, user, *args, **kwargs) -> _BQSet: - # pylint: disable=unused-argument - return self.model.acl_handler.user_filter(self, user, *args, **kwargs) - - -class Manager(_BManager.from_queryset(BQuerySet)): - ''' - Polemarch model manager. - ''' - - -class BaseModel(_BM): - # pylint: disable=no-member - objects = BQuerySet.as_manager() - - class Meta: - abstract = True - - @staticmethod - def get_acl(cls, obj=None) -> Any: - # pylint: disable=bad-staticmethod-argument - handler_class_name = settings.ACL['MODEL_HANDLERS'].get( - cls.__name__, settings.ACL['MODEL_HANDLERS'].get("Default") - ) - return import_string(handler_class_name)(cls, obj) - - @classproperty - def acl_handler(self) -> Any: - if isinstance(self, BaseModel): - classObj = self.__class__ - return classObj.get_acl(classObj, self) - return self.get_acl(self) - - -class BModel(BaseModel): - id = models.AutoField(primary_key=True, max_length=20) - hidden = models.BooleanField(default=False) - - class Meta: - abstract = True - - def __unicode__(self): - return "<{}>".format(self.id) # nocv +def first_staff_user() -> int: + return User.objects.filter(is_staff=True).first().id class BGroupedModel(BModel): @@ -115,7 +49,7 @@ class ACLModel(BModel): notes = models.TextField(default="") acl = models.ManyToManyField("main.ACLPermission", blank=True) owner = models.ForeignKey( - get_user_model(), + User, on_delete=models.SET_DEFAULT, default=first_staff_user, related_name="polemarch_%(class)s_set" @@ -123,3 +57,7 @@ class ACLModel(BModel): class Meta: abstract = True + + def set_owner(self, new_owner_id): + self.owner = User.objects.get(id=new_owner_id) + self.save(update_fields=('owner',)) diff --git a/polemarch/main/models/hooks.py b/polemarch/main/models/hooks.py index 35f6e9ac..76a025f9 100644 --- a/polemarch/main/models/hooks.py +++ b/polemarch/main/models/hooks.py @@ -3,8 +3,9 @@ import logging import collections import uuid +from django.db import models from vstutils.utils import raise_context, ModelHandlers -from .base import BModel, BQuerySet, models +from vstutils.models import BModel, BQuerySet logger = logging.getLogger('polemarch') diff --git a/polemarch/main/models/projects.py b/polemarch/main/models/projects.py index 5fbe1682..b60b265b 100644 --- a/polemarch/main/models/projects.py +++ b/polemarch/main/models/projects.py @@ -15,6 +15,7 @@ from vstutils.utils import ModelHandlers, raise_context_decorator_with_default, classproperty # pylint: disable=no-name-in-module from vstutils import custom_model +from vstutils.models import BQuerySet, BModel from yaml import load try: @@ -26,7 +27,7 @@ from ..validators import path_validator from .vars import AbstractModel, AbstractVarsQuerySet, models from ..exceptions import PMException -from .base import ManyToManyFieldACL, BQuerySet, BModel +from .base import ManyToManyFieldACL from .hooks import Hook from ..utils import AnsibleModules, AnsibleConfigParser, SubCacheInterface @@ -265,7 +266,6 @@ def hook(self, when, msg) -> None: def execute(self, plugin: str, execute_args, **kwargs) -> HISTORY_ID: from ..executions import PLUGIN_HANDLERS # pylint: disable=import-outside-toplevel - return PLUGIN_HANDLERS.execute( plugin, self, diff --git a/polemarch/main/models/tasks.py b/polemarch/main/models/tasks.py index 794db313..79fe75c5 100644 --- a/polemarch/main/models/tasks.py +++ b/polemarch/main/models/tasks.py @@ -11,19 +11,19 @@ from celery.schedules import crontab from django.core.exceptions import ValidationError from django.db.utils import IntegrityError -from django.db import transaction -from django.db.models import Q +from django.db import transaction, models from django.utils import timezone from django.utils.text import slugify from django.contrib.auth import get_user_model from django.db.models import functions as dbfunc, Count from django.utils.timezone import now +from vstutils.models import BaseModel, BModel, BQuerySet from vstutils.custom_model import ListModel, CustomQuerySet from vstutils.utils import translate as _ from . import Inventory from ..exceptions import DataNotReady, NotApplicable -from .base import ForeignKeyACL, BModel, ACLModel, BQuerySet, models, BaseModel +from .base import ForeignKeyACL, ACLModel from .vars import AbstractModel, AbstractVarsQuerySet from .projects import Project, HISTORY_ID from ..constants import CYPHER, HiddenArgumentsEnum @@ -34,7 +34,6 @@ User = get_user_model() -# Block of real models class Template(ACLModel): name = models.CharField(max_length=512) kind = models.CharField(max_length=32) @@ -499,7 +498,7 @@ def facts(self) -> Dict: data = self.get_raw( original=False, excludes=( - Q(line__contains="No config file") | Q(line__contains="as config file"), + models.Q(line__contains="No config file") | models.Q(line__contains="as config file"), ) ) regex = ( diff --git a/polemarch/main/models/users.py b/polemarch/main/models/users.py index 7df83dac..099f3147 100644 --- a/polemarch/main/models/users.py +++ b/polemarch/main/models/users.py @@ -5,18 +5,44 @@ from django.contrib.auth.models import Group as BaseGroup from django.contrib.auth import get_user_model -from .base import models, BModel, ACLModel, BQuerySet +from django.db import models +from vstutils.models import BModel, BQuerySet +from .base import ACLModel +from ..constants import MemberType logger = logging.getLogger("polemarch") +User = get_user_model() + + +class UserGroup(BaseGroup, ACLModel): + objects = BQuerySet.as_manager() + parent = models.OneToOneField(BaseGroup, on_delete=models.CASCADE, parent_link=True) + users = BaseGroup.user_set + + +class ACLPermissionQuerySet(BQuerySet): + def filter_by_user(self, user): # noce + return self.filter(models.Q(user=user) | models.Q(uagroup__user=user)) + class ACLPermission(BModel): - role = models.CharField(max_length=10) - uagroup = models.ForeignKey('main.UserGroup', - on_delete=models.CASCADE, blank=True, null=True) - user = models.ForeignKey(get_user_model(), - on_delete=models.CASCADE, blank=True, null=True) + objects = ACLPermissionQuerySet.as_manager() + + role = models.CharField(max_length=10) + uagroup = models.ForeignKey( + UserGroup, + on_delete=models.CASCADE, + blank=True, + null=True, + ) + user = models.ForeignKey( + User, + on_delete=models.CASCADE, + blank=True, + null=True, + ) @property def member(self) -> int: # noce @@ -25,22 +51,8 @@ def member(self) -> int: # noce return self.user.id return self.uagroup.id - @member.setter - def member(self, value) -> None: # nocv - pass - @property def member_type(self) -> Text: # noce if self.user is not None: - return "user" - return "team" - - @member_type.setter - def member_type(self, value) -> None: # nocv - pass - - -class UserGroup(BaseGroup, ACLModel): - objects = BQuerySet.as_manager() - parent = models.OneToOneField(BaseGroup, on_delete=models.CASCADE, parent_link=True) - users = BaseGroup.user_set + return MemberType.USER + return MemberType.TEAM diff --git a/polemarch/main/models/utils.py b/polemarch/main/models/utils.py index 5eb8ff04..bd267329 100644 --- a/polemarch/main/models/utils.py +++ b/polemarch/main/models/utils.py @@ -14,6 +14,7 @@ from subprocess import Popen from django.apps import apps from django.utils import timezone +from rest_framework.exceptions import ValidationError from vstutils.utils import KVExchanger from .hosts import Inventory @@ -25,6 +26,18 @@ logger = logging.getLogger("polemarch") +def ensure_inventory_is_from_project(inventory, project): # pylint: disable=invalid-name + if isinstance(inventory, Inventory): + inventory_id = inventory.id + elif isinstance(inventory, int): + inventory_id = inventory + else: + return + + if not project.inventories.filter(id=inventory_id).exists(): + raise ValidationError('No Inventory matches the given query.') + + # Classes and methods for support class DummyHistory: # pylint: disable=unused-argument diff --git a/polemarch/main/models/vars.py b/polemarch/main/models/vars.py index d28a9c49..9b3f28e4 100644 --- a/polemarch/main/models/vars.py +++ b/polemarch/main/models/vars.py @@ -6,13 +6,14 @@ from functools import reduce from collections import OrderedDict -from django.db import transaction +from django.db import transaction, models from django.db.models import Case, When, Value from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from vstutils.utils import tmp_file +from vstutils.models import BQuerySet, BModel from vstutils.api.decorators import cache_method_result -from .base import ACLModel, BQuerySet, BModel, models +from .base import ACLModel from ..constants import CYPHER, InventoryVariablesEnum logger = logging.getLogger("polemarch") diff --git a/polemarch/main/settings.py b/polemarch/main/settings.py index 79445db7..f7512171 100644 --- a/polemarch/main/settings.py +++ b/polemarch/main/settings.py @@ -34,10 +34,6 @@ # API settings VST_API_VERSION = 'v3' -REST_FRAMEWORK["DEFAULT_PERMISSION_CLASSES"] = [ - "{}.api.v2.permissions.ModelPermission".format(VST_PROJECT_LIB_NAME), -] - API_URL = VST_API_URL DEFAULT_API_URL = "/{}/{}".format(API_URL, VST_API_VERSION) API = { @@ -52,7 +48,7 @@ team={'view': '{}.api.v2.views.TeamViewSet'.format(VST_PROJECT_LIB_NAME)}, token={'view': '{}.api.v2.views.TokenView'.format(VST_PROJECT_LIB_NAME), 'type': 'view'}, hook={'view': '{}.api.v2.views.HookViewSet'.format(VST_PROJECT_LIB_NAME)}, - stats={'view': '{}.api.v2.views.StatisticViewSet'.format(VST_PROJECT_LIB_NAME), 'op_types': ['get']} + stats={'view': '{}.api.v2.views.StatisticsViewSet'.format(VST_PROJECT_LIB_NAME), 'op_types': ['get']} ) } API[VST_API_VERSION] = { @@ -274,12 +270,6 @@ class PluginOptionsSection(PluginSection): CLONE_RETRY = rpc.getint('clone_retry_count', fallback=5) -# ACL settings -ACL = { - "MODEL_HANDLERS": { - "Default": "{}.main.acl.handlers.Default".format(VST_PROJECT_LIB_NAME) - } -} # Outgoing hooks settings HOOKS = { diff --git a/polemarch/translations/en.py b/polemarch/translations/en.py index fb769716..1b89050e 100644 --- a/polemarch/translations/en.py +++ b/polemarch/translations/en.py @@ -14,4 +14,7 @@ 'hosts counter': 'hosts | host | hosts', 'users counter': 'users | user | users', 'all_tasks': 'all tasks', + + 'Vars': 'Variables', + 'Acl': 'ACL' } diff --git a/polemarch/translations/ru.py b/polemarch/translations/ru.py index 4b9c5f22..f8052750 100644 --- a/polemarch/translations/ru.py +++ b/polemarch/translations/ru.py @@ -51,6 +51,8 @@ 'Directory with playbooks': 'Каталог с плейбуками', 'Information': 'Информация', 'Arguments': 'Аргументы', + 'Vars': 'Переменные', + 'Data': 'Данные', 'Task type': 'Тип задачи', 'Interval type': 'Типа интервала', 'Contains groups': 'Содержит группы', diff --git a/requirements.txt b/requirements.txt index 8cf258ed..fd9ce705 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Main -vstutils[rpc,doc,prod]~=5.2.2 +vstutils[rpc,doc,prod]~=5.2.5 docutils~=0.16.0 markdown2~=2.4.0 diff --git a/setup.py b/setup.py index d56faca3..2694e5a4 100644 --- a/setup.py +++ b/setup.py @@ -372,7 +372,11 @@ def make_setup(**opts): webpack_path = os.path.join(os.getcwd(), 'webpack.config.js') if os.path.exists(webpack_path) and is_build and os.environ.get('DONT_YARN', "") != 'true': try: - subprocess.check_call(['yarn', 'install', '--pure-lockfile'], stdout=sys.stdout, stderr=sys.stderr) + subprocess.check_call( + ['yarn', 'install', '--pure-lockfile', '--mutex network'], + stdout=sys.stdout, + stderr=sys.stderr + ) subprocess.check_call(['yarn', 'devBuild' if is_develop else 'build'], stdout=sys.stdout, stderr=sys.stderr) except Exception as err: raise errors.CompileError(str(err)) diff --git a/tests.py b/tests.py index d7befd91..1e9c68c4 100644 --- a/tests.py +++ b/tests.py @@ -316,6 +316,7 @@ def create_execution_template_bulk_data(self, project_id=None, inventory=None, * class ProjectTestCase(BaseProjectTestCase): def test_set_owner(self): user = self._create_user(is_super_user=False, is_staff=True) + user2 = self._create_user(is_super_user=False, is_staff=True) results = self.bulk([ { 'method': 'post', @@ -327,16 +328,59 @@ def test_set_owner(self): 'path': ['project', self.project.id, 'set_owner'], 'data': {'user_id': 146} }, - {'method': 'get', 'path': ['project', self.project.id]} + {'method': 'get', 'path': ['project', self.project.id]}, ]) self.assertEqual(results[0]['status'], 201) self.assertEqual(results[1]['status'], 400) self.assertEqual(results[2]['status'], 200) self.assertEqual(results[2]['data']['owner']['id'], user.id) + with self.user_as(self, user2): + results = self.bulk([ + {'method': 'post', 'path': ['project', self.project.id, 'set_owner'], 'data': {'user_id': user.id}}, + ]) + self.assertEqual(results[0]['status'], 403) + self.assertEqual(results[0]['data']['detail'], 'Only owner can change owner.') + @own_projects_dir class InventoryTestCase(BaseProjectTestCase): + def test_fk_inventory_usage(self): + results = self.bulk_transactional([ + {'method': 'post', 'path': 'inventory', 'name': 'unreachable'}, + self.create_execution_template_bulk_data(), + self.create_periodic_task_bulk_data(), + ]) + inventory_id = results[0]['data']['id'] + template_id = results[1]['data']['id'] + periodic_task_id = results[2]['data']['id'] + + results = self.bulk([ + # [0] + self.execute_module_bulk_data(inventory=inventory_id), + # [1] + self.create_execution_template_bulk_data(inventory=inventory_id), + # [2] + self.create_periodic_task_bulk_data(inventory=inventory_id), + # [3] + { + 'method': 'patch', + 'path': ['project', self.project.id, 'execution_templates', template_id], + 'data': {'inventory': inventory_id}, + }, + # [4] + { + 'method': 'patch', + 'path': ['project', self.project.id, 'periodic_task', periodic_task_id], + 'data': {'inventory': inventory_id}, + }, + ]) + self.assertEqual(results[0]['status'], 400) + self.assertEqual(results[0]['data'], ['No Inventory matches the given query.']) + for idx in range(1, 5): + self.assertEqual(results[idx]['status'], 400) + self.assertEqual(results[idx]['data'], ['No Inventory matches the given query.']) + def test_import_inventory(self): def check_import(file_import=False): inventory = (TEST_DATA_DIR / 'inventory.yml').read_text() @@ -2778,6 +2822,7 @@ def test_history_actions(self): self.assertEqual(results[4]['status'], 200) self.assertEqual(results[4]['data'], {'detail': f'Task canceled: {self.project.id}'}) + @skipIf(settings.VST_PROJECT_LIB_NAME != 'polemarch', 'Stats may vary') def test_stats(self): def generate_history(status="OK"): project = self.get_model_class('main.Project').objects.create(name="Stats", repository='') diff --git a/yarn.lock b/yarn.lock index 0957f7e7..45434b03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,26 +17,31 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1": version "7.20.1" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== +"@babel/compat-data@^7.20.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" + integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== + "@babel/core@^7.16.7": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" - integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113" + integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.2" + "@babel/generator" "^7.20.5" "@babel/helper-compilation-targets" "^7.20.0" "@babel/helper-module-transforms" "^7.20.2" - "@babel/helpers" "^7.20.1" - "@babel/parser" "^7.20.2" + "@babel/helpers" "^7.20.5" + "@babel/parser" "^7.20.5" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -52,12 +57,12 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.0" -"@babel/generator@^7.20.1", "@babel/generator@^7.20.2": - version "7.20.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.4.tgz#4d9f8f0c30be75fd90a0562099a26e5839602ab8" - integrity sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA== +"@babel/generator@^7.20.1", "@babel/generator@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95" + integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== dependencies: - "@babel/types" "^7.20.2" + "@babel/types" "^7.20.5" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -253,14 +258,14 @@ "@babel/traverse" "^7.19.0" "@babel/types" "^7.19.0" -"@babel/helpers@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" - integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== +"@babel/helpers@^7.20.5": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763" + integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== dependencies: "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.0" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" "@babel/highlight@^7.18.6": version "7.18.6" @@ -271,10 +276,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" - integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== +"@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" + integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -896,7 +901,7 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1": +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1": version "7.20.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== @@ -912,7 +917,32 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.4.4": +"@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133" + integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.5" + "@babel/types" "^7.20.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84" + integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@babel/types@^7.18.9", "@babel/types@^7.4.4": version "7.20.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== @@ -926,29 +956,34 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@eslint/eslintrc@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" - integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.1" - globals "^13.9.0" + espree "^9.4.0" + globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" - minimatch "^3.0.4" + minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.11.6": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" + integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -972,7 +1007,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -995,15 +1030,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.14": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== @@ -1018,6 +1045,27 @@ dependencies: eslint-scope "5.1.1" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@polka/url@^1.0.0-next.20": version "1.0.0-next.21" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" @@ -1032,9 +1080,9 @@ "@types/estree" "*" "@types/eslint@*": - version "8.4.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" - integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + version "8.4.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" + integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1055,9 +1103,9 @@ integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/node@*": - version "18.7.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.17.tgz#52438111ea98f77475470fc62d79b9eb96bb2c92" - integrity sha512-0UyfUnt02zIuqp7yC8RYtDkp/vo8bFaQ13KkSEvUAohPOAlnVNbj5Fi3fgPSuwzakS+EvvnnZ4x9y7i6ASaSPQ== + version "18.11.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.14.tgz#a8571b25f3a31e9ded14e3ab9488509adef831d8" + integrity sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ== "@vue/component-compiler-utils@^3.1.0": version "3.3.0" @@ -1228,7 +1276,7 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1238,21 +1286,11 @@ acorn-walk@^8.0.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.0.4: +acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== -acorn@^8.5.0, acorn@^8.7.1: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== - -acorn@^8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -1288,9 +1326,9 @@ ansi-styles@^4.1.0: color-convert "^2.0.1" anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1354,6 +1392,11 @@ bluebird@^3.1.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1369,17 +1412,7 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== - dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" - -browserslist@^4.21.3, browserslist@^4.21.4: +browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -1399,10 +1432,10 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001400: - version "1.0.30001431" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795" - integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== +caniuse-lite@^1.0.30001400: + version "1.0.30001439" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb" + integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A== chalk@^2.0.0: version "2.4.2" @@ -1456,9 +1489,9 @@ clone-deep@^4.0.1: shallow-clone "^3.0.0" codemirror@^5.65.6: - version "5.65.9" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.9.tgz#ec70c92aa206ee4c9853d5f1e7c4ed356cdab68c" - integrity sha512-19Jox5sAKpusTDgqgKB5dawPpQcY+ipQK7xoEI+MVucEF9qqFaXpeqY1KaoyGBso/wHQoDa4HMMxMjdsS3Zzzw== + version "5.65.10" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.10.tgz#4276a93b8534ce91f14b733ba9a1ac949666eac9" + integrity sha512-IXAG5wlhbgcTJ6rZZcmi4+sjWIbJqIGfeg3tNa3yX84Jb3T4huS5qzQAo/cUisc1l3bI47WZodpyf7cYcocDKg== color-convert@^1.9.0: version "1.9.3" @@ -1507,7 +1540,7 @@ commondir@^1.0.1: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== consolidate@^0.15.1: version "0.15.1" @@ -1538,18 +1571,18 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: which "^2.0.1" css-loader@^6.5.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== + version "6.7.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.2.tgz#26bc22401b5921686a10fbeba75d124228302304" + integrity sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q== dependencies: icss-utils "^5.1.0" - postcss "^8.4.7" + postcss "^8.4.18" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.5" + semver "^7.3.8" cssesc@^3.0.0: version "3.0.0" @@ -1590,7 +1623,7 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -electron-to-chromium@^1.4.202, electron-to-chromium@^1.4.251: +electron-to-chromium@^1.4.251: version "1.4.284" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== @@ -1601,9 +1634,9 @@ emojis-list@^3.0.0: integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + version "5.12.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" + integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -1634,24 +1667,26 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-prettier@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== eslint-plugin-prettier@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0" - integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== dependencies: prettier-linter-helpers "^1.0.0" eslint-plugin-vue@^8.2.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.5.0.tgz#65832bba43ca713fa5da16bdfcf55d0095677f6f" - integrity sha512-i1uHCTAKOoEj12RDvdtONWrGzjFm/djkzqfhmQ0d6M/W8KM81mhswd/z+iTZ0jCpdUedW3YRgcVfQ37/J4zoYQ== + version "8.7.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz#f13c53547a0c9d64588a675cc5ecc6ccaf63703f" + integrity sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg== dependencies: eslint-utils "^3.0.0" natural-compare "^1.4.0" + nth-check "^2.0.1" + postcss-selector-parser "^6.0.9" semver "^7.3.5" vue-eslint-parser "^8.0.1" @@ -1689,12 +1724,14 @@ eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.3.0: integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== eslint@^8.6.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" - integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA== - dependencies: - "@eslint/eslintrc" "^1.2.1" - "@humanwhocodes/config-array" "^0.9.2" + version "8.29.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.29.0.tgz#d74a88a20fb44d59c51851625bc4ee8d0ec43f87" + integrity sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg== + dependencies: + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -1704,38 +1741,40 @@ eslint@^8.6.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.1" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.15.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" regexpp "^3.2.0" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.0.0, espree@^9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" - integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== +espree@^9.0.0, espree@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" + integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== dependencies: - acorn "^8.7.0" - acorn-jsx "^5.3.1" + acorn "^8.8.0" + acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" esquery@^1.4.0: @@ -1790,13 +1829,20 @@ fast-json-stable-stringify@^2.0.0: fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== +fastq@^1.6.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.14.0.tgz#107f69d7295b11e0fccc264e1fc6389f623731ce" + integrity sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg== + dependencies: + reusify "^1.0.4" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1828,6 +1874,14 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -1837,14 +1891,14 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" - integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.3.2: version "2.3.2" @@ -1856,17 +1910,12 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -1886,14 +1935,14 @@ glob-to-regexp@^0.4.1: integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" @@ -1902,10 +1951,10 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.6.0, globals@^13.9.0: - version "13.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" - integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== +globals@^13.15.0: + version "13.19.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" + integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== dependencies: type-fest "^0.20.2" @@ -1914,6 +1963,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -1959,9 +2013,9 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.2.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.1.tgz#c2b1f76cb999ede1502f3a226a9310fdfe88d46c" + integrity sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA== immutable@^4.0.0: version "4.1.0" @@ -1987,12 +2041,12 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" @@ -2038,6 +2092,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2064,6 +2123,11 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" +js-sdsl@^4.1.4: + version "4.2.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" + integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2099,7 +2163,7 @@ json-schema-traverse@^0.4.1: json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^1.0.1: version "1.0.1" @@ -2161,6 +2225,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -2222,10 +2293,10 @@ mime-types@^2.1.27: dependencies: mime-db "1.52.0" -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" @@ -2244,15 +2315,15 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -nanoid@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== neo-async@^2.6.2: version "2.6.2" @@ -2260,19 +2331,26 @@ neo-async@^2.6.2: integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + version "2.0.7" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.7.tgz#593edbc7c22860ee4d32d3933cfebdfab0c0e0e5" + integrity sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -2300,6 +2378,13 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -2307,6 +2392,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2327,7 +2419,7 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.1.0: version "3.1.1" @@ -2389,7 +2481,7 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-selector-parser@^6.0.2: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.9: version "6.0.11" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== @@ -2397,20 +2489,7 @@ postcss-selector-parser@^6.0.2: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-selector-parser@^6.0.4: - version "6.0.9" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" - integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" - integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== - -postcss-value-parser@^4.2.0: +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== @@ -2423,12 +2502,12 @@ postcss@^7.0.36: picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.4.7: - version "8.4.12" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" - integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== +postcss@^8.4.18: + version "8.4.20" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" + integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== dependencies: - nanoid "^3.3.1" + nanoid "^3.3.4" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -2464,6 +2543,11 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -2564,6 +2648,11 @@ resolve@^1.14.2, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -2571,6 +2660,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -2585,9 +2681,9 @@ sass-loader@^12.4.0: neo-async "^2.6.2" sass@^1.48.0: - version "1.56.1" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.1.tgz#94d3910cd468fd075fa87f5bb17437a0b617d8a7" - integrity sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ== + version "1.56.2" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.2.tgz#9433b345ab3872996c82a53a58c014fd244fd095" + integrity sha512-ciEJhnyCRwzlBCB+h5cCPM6ie/6f8HrhZMQOf5vlU60Y1bI1rx5Zb0vlDZvaycHsg/MqFfF1Eq2eokAa32iw8w== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -2616,10 +2712,10 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== +semver@^7.3.5, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" @@ -2736,9 +2832,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.14.1" terser@^5.14.1: - version "5.15.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" - integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== + version "5.16.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.1.tgz#5af3bc3d0f24241c7fb2024199d5c461a1075880" + integrity sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -2748,7 +2844,7 @@ terser@^5.14.1: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== to-fast-properties@^2.0.0: version "2.0.0" @@ -2802,7 +2898,7 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -update-browserslist-db@^1.0.5, update-browserslist-db@^1.0.9: +update-browserslist-db@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== @@ -2822,11 +2918,6 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vue-eslint-parser@^8.0.1: version "8.3.0" resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d" @@ -2932,9 +3023,9 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.74.0: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + version "5.75.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" + integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -2981,7 +3072,7 @@ word-wrap@^1.2.3: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== ws@^7.3.1: version "7.5.9" @@ -2997,3 +3088,8 @@ yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From e4a0308eeb2207b1740df6e00a0041cc3c2b11c4 Mon Sep 17 00:00:00 2001 From: Vladislav Korenkov <vladnfs3@gmail.com> Date: Mon, 26 Dec 2022 18:08:50 +1000 Subject: [PATCH 8/8] Optimization: `filter_by_user` query --- doc/gui.rst | 5 +++++ polemarch/main/models/users.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/gui.rst b/doc/gui.rst index 10d8e2f4..94ca88da 100644 --- a/doc/gui.rst +++ b/doc/gui.rst @@ -557,6 +557,11 @@ As you can see, the form of new group creation consists of following fields: * **Notes** - not required field for some user’s notes, for example, for what purpose this group was created or something like this. +.. warning:: + By default SQLite's maximum expression tree depth is 1000. This could create + problems with very nested groups. If you encounter so, please refer to + `documentation https://www.sqlite.org/limits.html#max_expr_depth`_. + After group creation you will see the next page: .. image:: new_screenshots/test_group.png diff --git a/polemarch/main/models/users.py b/polemarch/main/models/users.py index 099f3147..dd5a9fbb 100644 --- a/polemarch/main/models/users.py +++ b/polemarch/main/models/users.py @@ -24,7 +24,7 @@ class UserGroup(BaseGroup, ACLModel): class ACLPermissionQuerySet(BQuerySet): def filter_by_user(self, user): # noce - return self.filter(models.Q(user=user) | models.Q(uagroup__user=user)) + return self.filter(models.Q(user=user) | models.Q(uagroup__id__in=user.groups.values('id'))) class ACLPermission(BModel):