From 4eca999da4328746582c261219636b7da6c5bb38 Mon Sep 17 00:00:00 2001 From: bakebot Date: Wed, 6 Mar 2024 13:14:07 +0000 Subject: [PATCH 1/6] Cookie updated by NetworkToCode Cookie Drift Manager Tool Template: ``` { "template": "https://github.com/nautobot/cookiecutter-nautobot-app.git", "dir": "nautobot-app", "ref": "refs/tags/nautobot-app-v2.2.0", "path": null } ``` Cookie: ``` { "remote": "https://github.com/nautobot/nautobot-app-chatops.git", "path": "/tmp/tmptn61c5i5/nautobot-app-chatops", "repository_path": "/tmp/tmptn61c5i5/nautobot-app-chatops", "dir": "", "branch_prefix": "drift-manager", "context": { "codeowner_github_usernames": "@glennmatthews @jvanderaa @smk4664 @whitej6", "full_name": "Network to Code, LLC", "email": "opensource@networktocode.com", "github_org": "nautobot", "app_name": "nautobot_chatops", "verbose_name": "Nautobot ChatOps App", "app_slug": "nautobot-chatops", "project_slug": "nautobot-app-chatops", "repo_url": "https://github.com/nautobot/nautobot-app-chatops/", "base_url": "chatops", "min_nautobot_version": "2.0.0", "max_nautobot_version": "2.9999", "camel_name": "NautobotChatOpsApp", "project_short_description": "Nautobot ChatOps App", "model_class_name": "None", "open_source_license": "Apache-2.0", "docs_base_url": "https://docs.nautobot.com", "docs_app_url": "https://docs.nautobot.com/projects/chatops/en/latest", "_template": "https://github.com/nautobot/cookiecutter-nautobot-app.git", "_output_dir": "/tmp/tmptn61c5i5", "_repo_dir": "/github/home/.cookiecutters/cookiecutter-nautobot-app/nautobot-app", "_checkout": "refs/tags/nautobot-app-v2.2.0" }, "base_branch": "develop", "remote_name": "origin", "pull_request_strategy": "PullRequestStrategy.CREATE", "post_actions": [ "PostAction.BLACK" ], "baked_commit_ref": "4b6c888ec08af5233332d01d66b9f71c2f9368a8", "draft": true } ``` CLI Arguments: ``` { "cookie_dir": "", "input": false, "json_filename": "", "output_dir": "", "push": true, "template": "", "template_dir": "", "template_ref": "refs/tags/nautobot-app-v2.2.0", "pull_request": null, "post_action": [], "disable_post_actions": false, "draft": null } ``` --- .cookiecutter.json | 4 +- .../pull_request_template.md | 1 - .github/workflows/ci.yml | 72 ++++----------- README.md | 4 +- development/Dockerfile | 2 +- development/app_config_schema.py | 64 +++++++++++++ development/nautobot_config.py | 4 +- development/towncrier_template.j2 | 2 +- docs/admin/install.md | 10 ++- docs/dev/contributing.md | 37 ++++---- docs/dev/dev_environment.md | 20 ++++- docs/user/app_overview.md | 2 +- mkdocs.yml | 6 +- nautobot_chatops/app-config-schema.json | 1 + pyproject.toml | 6 +- tasks.py | 89 +++++++++---------- 16 files changed, 185 insertions(+), 139 deletions(-) create mode 100644 development/app_config_schema.py create mode 100644 nautobot_chatops/app-config-schema.json diff --git a/.cookiecutter.json b/.cookiecutter.json index 6e537e17..f8d8c592 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -21,7 +21,7 @@ "_drift_manager": { "template": "https://github.com/nautobot/cookiecutter-nautobot-app.git", "template_dir": "nautobot-app", - "template_ref": "refs/tags/nautobot-app-v2.1.0", + "template_ref": "refs/tags/nautobot-app-v2.2.0", "cookie_dir": "", "branch_prefix": "drift-manager", "pull_request_strategy": "create", @@ -29,7 +29,7 @@ "black" ], "draft": true, - "baked_commit_ref": "4b6c888ec08af5233332d01d66b9f71c2f9368a8" + "baked_commit_ref": "b221d6a21e9b9a07df4b85782af19053e5c6c624" } } } diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md index 31b4e282..cdba2d2a 100644 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -31,5 +31,4 @@ - [ ] Attached Screenshots, Payload Example - [ ] Unit, Integration Tests - [ ] Documentation Updates (when adding/changing features) -- [ ] Example App Updates (when adding/changing features) - [ ] Outline Remaining Work, Constraints from Design diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66358568..17bd2cfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: black" run: "poetry run invoke black" bandit: @@ -35,7 +35,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: bandit" run: "poetry run invoke bandit" ruff: @@ -46,7 +46,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: ruff" run: "poetry run invoke ruff" check-docs-build: @@ -57,7 +57,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Check Docs Build" run: "poetry run invoke build-and-check-docs" flake8: @@ -68,7 +68,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: flake8" run: "poetry run invoke flake8" poetry: @@ -79,7 +79,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Checking: poetry lock file" run: "poetry run invoke lock --check" yamllint: @@ -90,10 +90,10 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: yamllint" run: "poetry run invoke yamllint" - pylint: + check-in-docker: needs: - "bandit" - "ruff" @@ -114,7 +114,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Set up Docker Buildx" id: "buildx" uses: "docker/setup-buildx-action@v3" @@ -136,53 +136,13 @@ jobs: run: "cp development/creds.example.env development/creds.env" - name: "Linting: pylint" run: "poetry run invoke pylint" - check-migrations: - needs: - - "bandit" - - "ruff" - - "flake8" - - "poetry" - - "yamllint" - - "black" - runs-on: "ubuntu-22.04" - strategy: - fail-fast: true - matrix: - python-version: ["3.11"] - nautobot-version: ["2.0.0"] - env: - INVOKE_NAUTOBOT_CHATOPS_PYTHON_VER: "${{ matrix.python-version }}" - INVOKE_NAUTOBOT_CHATOPS_NAUTOBOT_VER: "${{ matrix.nautobot-version }}" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v4" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" - - name: "Set up Docker Buildx" - id: "buildx" - uses: "docker/setup-buildx-action@v3" - - name: "Build" - uses: "docker/build-push-action@v5" - with: - builder: "${{ steps.buildx.outputs.name }}" - context: "./" - push: false - load: true - tags: "${{ env.APP_NAME }}/nautobot:${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" - file: "./development/Dockerfile" - cache-from: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" - cache-to: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" - build-args: | - NAUTOBOT_VER=${{ matrix.nautobot-version }} - PYTHON_VER=${{ matrix.python-version }} - - name: "Copy credentials" - run: "cp development/creds.example.env development/creds.env" + - name: "Checking: App Config" + run: "poetry run invoke validate-app-config" - name: "Checking: migrations" run: "poetry run invoke check-migrations" unittest: needs: - - "pylint" - - "check-migrations" + - "check-in-docker" strategy: fail-fast: true matrix: @@ -204,7 +164,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Set up Docker Buildx" id: "buildx" uses: "docker/setup-buildx-action@v3" @@ -240,7 +200,7 @@ jobs: with: fetch-depth: "0" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v4" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Check for changelog entry" run: | git fetch --no-tags origin +refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} @@ -257,7 +217,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Set up Python" - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: "3.11" - name: "Install Python Packages" @@ -292,7 +252,7 @@ jobs: - name: "Check out repository code" uses: "actions/checkout@v4" - name: "Set up Python" - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: "3.11" - name: "Install Python Packages" diff --git a/README.md b/README.md index 5af700d6..dff54f22 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@


- - + +
diff --git a/development/Dockerfile b/development/Dockerfile index e3c3bec8..69d8a0f9 100644 --- a/development/Dockerfile +++ b/development/Dockerfile @@ -28,7 +28,7 @@ ENV INVOKE_NAUTOBOT_CHATOPS_LOCAL=true # Since this is only used for development and we don't ship this container, pinning Poetry back is not expressly necessary # We also don't need virtual environments in container RUN which poetry || curl -sSL https://install.python-poetry.org | python3 - && \ - poetry config virtualenvs.create false + poetry config virtualenvs.create false # !!! USE CAUTION WHEN MODIFYING LINES ABOVE # ------------------------------------------------------------------------------------- diff --git a/development/app_config_schema.py b/development/app_config_schema.py new file mode 100644 index 00000000..47009954 --- /dev/null +++ b/development/app_config_schema.py @@ -0,0 +1,64 @@ +"""App Config Schema Generator and Validator.""" +import json +from importlib import import_module +from os import getenv +from pathlib import Path +from urllib.parse import urlparse + +import jsonschema +import toml +from django.conf import settings +from to_json_schema.to_json_schema import SchemaBuilder + + +def _enrich_object_schema(schema, defaults, required): + schema["additionalProperties"] = False + for key, value in schema["properties"].items(): + if required and key in required: + value["required"] = True + default_value = defaults and defaults.get(key, None) + if value["type"] == "object" and "properties" in value: + _enrich_object_schema(value, default_value, None) + elif default_value is not None: + value["default"] = default_value + + +def _main(): + pyproject = toml.loads(Path("pyproject.toml").read_text()) + url = urlparse(pyproject["tool"]["poetry"]["repository"]) + _, owner, repository = url.path.split("/") + package_name = pyproject["tool"]["poetry"]["packages"][0]["include"] + app_config = settings.PLUGINS_CONFIG[package_name] # type: ignore + schema_path = Path(package_name) / "app-config-schema.json" + command = getenv("APP_CONFIG_SCHEMA_COMMAND", "") + if command == "generate": + schema = { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": f"https://raw.githubusercontent.com/{owner}/{repository}/develop/{package_name}/app-config-schema.json", + "$comment": "TBD: Update $id, replace `develop` with the future release tag", + **SchemaBuilder().to_json_schema(app_config), # type: ignore + } + app_config = import_module(package_name).config + _enrich_object_schema(schema, app_config.default_settings, app_config.required_settings) + schema_path.write_text(json.dumps(schema, indent=4) + "\n") + print(f"\n==================\nGenerated schema:\n\n{schema_path}\n") + print( + "WARNING: Review and edit the generated file before committing.\n" + "\n" + "Its content is inferred from:\n" + "\n" + "- The current configuration in `PLUGINS_CONFIG`\n" + "- `NautobotAppConfig.default_settings`\n" + "- `NautobotAppConfig.required_settings`" + ) + elif command == "validate": + schema = json.loads(schema_path.read_text()) + jsonschema.validate(app_config, schema) + print( + f"\n==================\nValidated configuration using the schema:\n{schema_path}\nConfiguration is valid." + ) + else: + raise RuntimeError(f"Unknown command: {command}") + + +_main() diff --git a/development/nautobot_config.py b/development/nautobot_config.py index 52a474f4..06a7fb25 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -92,11 +92,11 @@ "disable_existing_loggers": False, "formatters": { "normal": { - "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)s :\n %(message)s", + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)s : %(message)s", "datefmt": "%H:%M:%S", }, "verbose": { - "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)-20s %(filename)-15s %(funcName)30s() :\n %(message)s", + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)-20s %(filename)-15s %(funcName)30s() : %(message)s", "datefmt": "%H:%M:%S", }, }, diff --git a/development/towncrier_template.j2 b/development/towncrier_template.j2 index 7010b057..b0f6e12f 100644 --- a/development/towncrier_template.j2 +++ b/development/towncrier_template.j2 @@ -1,6 +1,6 @@ {% if render_title %} -## [v{{ versiondata.version }} ({{ versiondata.date }})](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v{{ versiondata.version}}) +## [v{{ versiondata.version }} ({{ versiondata.date }})]({{ cookiecutter.repo_url }}/releases/tag/v{{ versiondata.version}}) {% endif %} {% for section, _ in sections.items() %} diff --git a/docs/admin/install.md b/docs/admin/install.md index a432d036..7039b7e6 100644 --- a/docs/admin/install.md +++ b/docs/admin/install.md @@ -71,7 +71,15 @@ Set up your chosen chat platform: !!! warning Follow the [Nautobot App Installation Instructions](https://nautobot.readthedocs.io/en/stable/plugins/#installing-plugins) for complete and most recent guidelines. -The App is a Python package available on PyPI, installable with `pip`: +!!! warning "Developer Note - Remove Me!" + What external systems (if any) it needs access to in order to work. + +## Install Guide + +!!! note + Apps can be installed from the [Python Package Index](https://pypi.org/) or locally. See the [Nautobot documentation](https://docs.nautobot.com/projects/core/en/stable/user-guide/administration/installation/app-install/) for more details. The pip package name for this app is [`nautobot-chatops`](https://pypi.org/project/nautobot-chatops/). + +The app is available as a Python package via PyPI and can be installed with `pip`: ```shell pip install nautobot-chatops diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md index 1d03330e..30fa558d 100644 --- a/docs/dev/contributing.md +++ b/docs/dev/contributing.md @@ -181,33 +181,30 @@ these checks): The branching policy includes the following tenets: -- The `develop` branch is the primary branch to develop off of. +- The `develop` branch is the branch of the next major and minor paired version planned. - PRs intended to add new features should be sourced from the `develop` branch. -- PRs intended to address bug fixes and security patches should be sourced from the `develop` branch. -- PRs intended to add new features that break backward compatibility should be discussed before a PR is created. +- PRs intended to fix issues in the Nautobot LTM compatible release should be sourced from the latest `ltm-` branch instead of `develop`. -Nautobot ChatOps app will observe semantic versioning, as of 1.0. This may result in a quick turn around in minor versions to keep pace with an ever-growing feature set. +Nautobot ChatOps App will observe semantic versioning, as of 1.0. This may result in a quick turnaround in minor versions to keep pace with an ever growing feature set. ## Release Policy -Nautobot ChatOps currently has no intended scheduled release schedule, and will release new features in minor versions. +Nautobot ChatOps App has currently no intended scheduled release schedule, and will release new features in minor versions. -When a new release of any kind (e.g. from `develop` to `main`, or a release of a `stable-.`) is created the following should happen. +When a new release, from `develop` to `main`, is created the following should happen. -- A release PR is created: - - Add and/or update to the changelog in `docs/admin/release_notes/version_..md` file to reflect the changes. - - Update the mkdocs.yml file to include updates when adding a new release_notes version file. - - Change the version from `..-beta` to `..` in `pyproject.toml`. - - Set the PR to the proper branch, e.g. either `main` or `stable-.`. +- A release PR is created from `develop` with: + - Update the release notes in `docs/admin/release_notes/version_..md` file to reflect the changes. + - Change the version from `..-beta` to `..` in `pyproject.toml`. + - Set the PR to the `main` branch. - Ensure the tests for the PR pass. - Merge the PR. - Create a new tag: - - The tag should be in the form of `v..`. - - The title should be in the form of `v..`. - - The description should be the changes that were added to the `version_..md` document. -- If merged into `main`, then push from `main` to `develop`, in order to retain the merge commit created when the PR was merged. -- If there is a new `.`, create a `stable-.` for the **previous** version, so that security updates to old versions may be applied more easily. -- A post release PR is created: - - Change the version from `..` to `..-beta` in `pyproject.toml`. - - Set the PR to the proper branch, e.g. either `develop` or `stable-.`. - - Once tests pass, merge. + - The tag should be in the form of `v..`. + - The title should be in the form of `v..`. + - The description should be the changes that were added to the `version_..md` document. +- If merged into `main`, then push from `main` to `develop`, in order to retain the merge commit created when the PR was merged +- A post release PR is created with: + - Change the version from `..` to `..-beta` in both `pyproject.toml` and `nautobot.__init__.__version__`. + - Set the PR to the proper branch, `develop`. + - Once tests pass, merge. diff --git a/docs/dev/dev_environment.md b/docs/dev/dev_environment.md index 9a9a458e..621c4ea2 100644 --- a/docs/dev/dev_environment.md +++ b/docs/dev/dev_environment.md @@ -82,7 +82,7 @@ nautobot-server migrate !!! note If you want to develop on the latest develop branch of Nautobot, run the following command: `poetry add --optional git+https://github.com/nautobot/nautobot@develop`. After the `@` symbol must match either a branch or a tag. -You can now run `nautobot-server` commands as you would from the [Nautobot documentation](https://nautobot.readthedocs.io/en/latest/) for example to start the development server: +You can now run `nautobot-server` commands as you would from the [Nautobot documentation](https://docs.nautobot.com/projects/core/en/stable/user-guide/administration/tools/nautobot-server/) for example to start the development server: ```shell nautobot-server runserver 0.0.0.0:8080 --insecure @@ -478,3 +478,21 @@ To run an individual test, you can run any or all of the following: ➜ invoke ruff ➜ invoke pylint ``` + +### App Configuration Schema + +In the package source, there is the `nautobot_chatops/app-config-schema.json` file, conforming to the [JSON Schema](https://json-schema.org/) format. This file is used to validate the configuration of the app in CI pipelines. + +If you make changes to `PLUGINS_CONFIG` or the configuration schema, you can run the following command to validate the schema: + +```bash +invoke validate-app-config +``` + +To generate the `app-config-schema.json` file based on the current `PLUGINS_CONFIG` configuration, run the following command: + +```bash +invoke generate-app-config-schema +``` + +This command can only guess the schema, so it's up to the developer to manually update the schema as needed. diff --git a/docs/user/app_overview.md b/docs/user/app_overview.md index 0e8a188f..e27cfd55 100644 --- a/docs/user/app_overview.md +++ b/docs/user/app_overview.md @@ -1,6 +1,6 @@ # App Overview -This document provides an overview of the App including critical information and import considerations when applying it to your Nautobot environment. +This document provides an overview of the App including critical information and important considerations when applying it to your Nautobot environment. !!! note Throughout this documentation, the terms "app" and "plugin" will be used interchangeably. diff --git a/mkdocs.yml b/mkdocs.yml index 804d4f31..73677dc0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -81,7 +81,11 @@ markdown_extensions: anchor_linenums: true - "pymdownx.inlinehilite" - "pymdownx.snippets" - - "pymdownx.superfences" + - "pymdownx.superfences": + custom_fences: + - name: "mermaid" + class: "mermaid" + format: !!python/name:pymdownx.superfences.fence_code_format - "footnotes" plugins: - "search" diff --git a/nautobot_chatops/app-config-schema.json b/nautobot_chatops/app-config-schema.json new file mode 100644 index 00000000..27ba77dd --- /dev/null +++ b/nautobot_chatops/app-config-schema.json @@ -0,0 +1 @@ +true diff --git a/pyproject.toml b/pyproject.toml index 77230393..163d94ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ license = "Apache-2.0" readme = "README.md" homepage = "https://github.com/nautobot/nautobot-app-chatops/" repository = "https://github.com/nautobot/nautobot-app-chatops/" +documentation = "https://docs.nautobot.com/projects/chatops/en/latest/" keywords = ["nautobot", "nautobot-app", "nautobot-plugin"] classifiers = [ "Intended Audience :: Developers", @@ -92,7 +93,8 @@ requests-mock = "^1.9.3" ruff = "*" toml = "*" towncrier = "~23.6.0" -yamllint = "*" +to-json-schema = "*" +jsonschema = "*" [tool.poetry.extras] all = [ @@ -257,7 +259,7 @@ requires = ["poetry_core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.towncrier] -package = "nautobot" +package = "nautobot_chatops" directory = "changes" filename = "docs/admin/release_notes/version_X.Y.md" template = "development/towncrier_template.j2" diff --git a/tasks.py b/tasks.py index 8891db05..7b1e4891 100644 --- a/tasks.py +++ b/tasks.py @@ -151,15 +151,27 @@ def docker_compose(context, command, **kwargs): def run_command(context, command, **kwargs): """Wrapper to run a command locally or inside the nautobot container.""" if is_truthy(context.nautobot_chatops.local): + if "command_env" in kwargs: + kwargs["env"] = { + **kwargs.get("env", {}), + **kwargs.pop("command_env"), + } context.run(command, **kwargs) else: # Check if nautobot is running, no need to start another nautobot container to run a command docker_compose_status = "ps --services --filter status=running" results = docker_compose(context, docker_compose_status, hide="out") if "nautobot" in results.stdout: - compose_command = f"exec nautobot {command}" + compose_command = "exec" else: - compose_command = f"run --rm --entrypoint '{command}' nautobot" + compose_command = "run --rm --entrypoint=''" + + if "command_env" in kwargs: + command_env = kwargs.pop("command_env") + for key, value in command_env.items(): + compose_command += f' --env="{key}={value}"' + + compose_command += f" -- nautobot {command}" pty = kwargs.pop("pty", True) @@ -329,15 +341,22 @@ def logs(context, service="", follow=False, tail=0): # ------------------------------------------------------------------------------ # ACTIONS # ------------------------------------------------------------------------------ -@task(help={"file": "Python file to execute"}) -def nbshell(context, file=""): +@task( + help={ + "file": "Python file to execute", + "env": "Environment variables to pass to the command", + "plain": "Flag to run nbshell in plain mode (default: False)", + }, +) +def nbshell(context, file="", env={}, plain=False): """Launch an interactive nbshell session.""" command = [ "nautobot-server", "nbshell", + "--plain" if plain else "", f"< '{file}'" if file else "", ] - run_command(context, " ".join(command), pty=not bool(file)) + run_command(context, " ".join(command), pty=not bool(file), command_env=env) @task @@ -672,7 +691,7 @@ def pylint(context): def autoformat(context): """Run code autoformatting.""" black(context, autoformat=True) - ruff(context, action="both", fix=True) + ruff(context, fix=True) @task( @@ -800,6 +819,8 @@ def tests(context, failfast=False, keepdb=False, lint_only=False): pylint(context) print("Running mkdocs...") build_and_check_docs(context) + print("Checking app config schema...") + validate_app_config(context) if not lint_only: print("Running unit tests...") unittest(context, failfast=failfast, keepdb=keepdb) @@ -807,52 +828,24 @@ def tests(context, failfast=False, keepdb=False, lint_only=False): print("All tests have passed!") -# ------------------------------------------------------------------------------ -# APP CUSTOM -# ------------------------------------------------------------------------------ @task -def bootstrap_mattermost(context): - """Bootstrap Nautobot data to be used with Mattermost.""" - nbshell(context, file="development/mattermost/nautobot_bootstrap.py") +def generate_app_config_schema(context): + """Generate the app config schema from the current app config. + WARNING: Review and edit the generated file before committing. -@task -def backup_mattermost(context): - """Export Mattermost data to the SQL file. Certain tables are ignored.""" - output = "./development/mattermost/dump.sql" - - command = [ - "exec", - "--", - "mattermost", - "bash", - "-c", - "'", - "pg_dump", - "--inserts", - "--user=$POSTGRES_USER", - "--dbname=$POSTGRES_DB", - "'", - f"> {output}", - ] + Its content is inferred from: - docker_compose(context, " ".join(command)) + - The current configuration in `PLUGINS_CONFIG` + - `NautobotAppConfig.default_settings` + - `NautobotAppConfig.required_settings` + """ + start(context, service="nautobot") + nbshell(context, file="development/app_config_schema.py", env={"APP_CONFIG_SCHEMA_COMMAND": "generate"}) @task -def connect_awx_container(context, container_name="tools_awx_1"): - """Connect nautobot and celery containers to awx container. - - Bridge network is defined in `development/ansible/docker-compose.yaml`. - - To run testing awx instance, follow [instructions] - (https://github.com/ansible/awx/tree/devel/tools/docker-compose#getting-started) - - Before running `make docker-compose` comment out `- 8080:8080` port mapping in file - `tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2` to avoid port conflict with nautobot. - - After setting up awx, cd back to chatops repo and run `invoke connect-awx-container`. - """ - bridge_network = f"{context.nautobot_chatops.project_name}_awx" - context.run(f"docker network connect --alias awx {bridge_network} {container_name}") - print(f"Container {container_name} connected to {bridge_network} network") +def validate_app_config(context): + """Validate the app config based on the app config schema.""" + start(context, service="nautobot") + nbshell(context, plain=True, file="development/app_config_schema.py", env={"APP_CONFIG_SCHEMA_COMMAND": "validate"}) From 6f21e6574f6dfdd005f931ef9314755c9d8eff0d Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Thu, 7 Mar 2024 10:37:16 +0000 Subject: [PATCH 2/6] fix: Added changelog fragment --- changes/8.housekeeping | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/8.housekeeping diff --git a/changes/8.housekeeping b/changes/8.housekeeping new file mode 100644 index 00000000..653c54ac --- /dev/null +++ b/changes/8.housekeeping @@ -0,0 +1 @@ +Re-baked from the latest template. From 97f593abd527b2f7fbaddfe4e6f6f346235e5d92 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Thu, 7 Mar 2024 11:47:36 +0000 Subject: [PATCH 3/6] fix: Lock poetry --- poetry.lock | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 88348e98..27b63337 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. [[package]] name = "aiodns" @@ -4463,6 +4463,20 @@ files = [ {file = "texttable-1.6.7.tar.gz", hash = "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2"}, ] +[[package]] +name = "to-json-schema" +version = "1.0.1" +description = "" +optional = false +python-versions = "*" +files = [ + {file = "to_json_schema-1.0.1-py3-none-any.whl", hash = "sha256:5708663f1c81815e4ff01fce910ac32ee3964d0c6b3587fd4fff2e38d5c9aa7b"}, + {file = "to_json_schema-1.0.1.tar.gz", hash = "sha256:ec747bd5129256dd571105f66a7bc9a4546228cd5e5fbf5e06dc9776e255400e"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov", "setuptools"] + [[package]] name = "toml" version = "0.10.2" @@ -4846,24 +4860,6 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] -[[package]] -name = "yamllint" -version = "1.32.0" -description = "A linter for YAML files." -optional = false -python-versions = ">=3.7" -files = [ - {file = "yamllint-1.32.0-py3-none-any.whl", hash = "sha256:d97a66e48da820829d96077d76b8dfbe6c6140f106e558dae87e81ac4e6b30b7"}, - {file = "yamllint-1.32.0.tar.gz", hash = "sha256:d01dde008c65de5b235188ab3110bebc59d18e5c65fc8a58267cd211cd9df34a"}, -] - -[package.dependencies] -pathspec = ">=0.5.3" -pyyaml = "*" - -[package.extras] -dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] - [[package]] name = "yarl" version = "1.9.2" @@ -4980,4 +4976,4 @@ panorama = ["defusedxml", "ipaddr", "netmiko", "netutils", "pan-os-python"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "9edc678921261739f715585db93b205eb9d4e92b525c11a27d87dbe7625d1196" +content-hash = "352d2cdc13f37b487004c249b50f331e5dfeec1aa37bed959a1da26a08348a82" From e499edfe525138b3ce7bba53b9319d9899dd102c Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Thu, 7 Mar 2024 13:22:44 +0000 Subject: [PATCH 4/6] fix: Remove trailing slash from repo url --- .cookiecutter.json | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cookiecutter.json b/.cookiecutter.json index f8d8c592..c90e2c72 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -8,7 +8,7 @@ "verbose_name": "Nautobot ChatOps App", "app_slug": "nautobot-chatops", "project_slug": "nautobot-app-chatops", - "repo_url": "https://github.com/nautobot/nautobot-app-chatops/", + "repo_url": "https://github.com/nautobot/nautobot-app-chatops", "base_url": "chatops", "min_nautobot_version": "2.0.0", "max_nautobot_version": "2.9999", diff --git a/README.md b/README.md index dff54f22..84579bd6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@


- + From 4c65b1cec9d80051454faa8928afb7291c451f9c Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Thu, 7 Mar 2024 13:24:01 +0000 Subject: [PATCH 5/6] fix: Leaked cookiecutter template string --- development/towncrier_template.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/towncrier_template.j2 b/development/towncrier_template.j2 index b0f6e12f..7010b057 100644 --- a/development/towncrier_template.j2 +++ b/development/towncrier_template.j2 @@ -1,6 +1,6 @@ {% if render_title %} -## [v{{ versiondata.version }} ({{ versiondata.date }})]({{ cookiecutter.repo_url }}/releases/tag/v{{ versiondata.version}}) +## [v{{ versiondata.version }} ({{ versiondata.date }})](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v{{ versiondata.version}}) {% endif %} {% for section, _ in sections.items() %} From 973000b1e3166fd77caad704efee6dbc59c8d9e5 Mon Sep 17 00:00:00 2001 From: Jan Snasel Date: Thu, 7 Mar 2024 13:35:11 +0000 Subject: [PATCH 6/6] chore: Manual fixes --- docs/admin/install.md | 3 --- tasks.py | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/admin/install.md b/docs/admin/install.md index 7039b7e6..5dcf3ddb 100644 --- a/docs/admin/install.md +++ b/docs/admin/install.md @@ -71,9 +71,6 @@ Set up your chosen chat platform: !!! warning Follow the [Nautobot App Installation Instructions](https://nautobot.readthedocs.io/en/stable/plugins/#installing-plugins) for complete and most recent guidelines. -!!! warning "Developer Note - Remove Me!" - What external systems (if any) it needs access to in order to work. - ## Install Guide !!! note diff --git a/tasks.py b/tasks.py index 7b1e4891..62dad57a 100644 --- a/tasks.py +++ b/tasks.py @@ -849,3 +849,54 @@ def validate_app_config(context): """Validate the app config based on the app config schema.""" start(context, service="nautobot") nbshell(context, plain=True, file="development/app_config_schema.py", env={"APP_CONFIG_SCHEMA_COMMAND": "validate"}) + + +# ------------------------------------------------------------------------------ +# APP CUSTOM +# ------------------------------------------------------------------------------ +@task +def bootstrap_mattermost(context): + """Bootstrap Nautobot data to be used with Mattermost.""" + nbshell(context, file="development/mattermost/nautobot_bootstrap.py") + + +@task +def backup_mattermost(context): + """Export Mattermost data to the SQL file. Certain tables are ignored.""" + output = "./development/mattermost/dump.sql" + + command = [ + "exec", + "--", + "mattermost", + "bash", + "-c", + "'", + "pg_dump", + "--inserts", + "--user=$POSTGRES_USER", + "--dbname=$POSTGRES_DB", + "'", + f"> {output}", + ] + + docker_compose(context, " ".join(command)) + + +@task +def connect_awx_container(context, container_name="tools_awx_1"): + """Connect nautobot and celery containers to awx container. + + Bridge network is defined in `development/ansible/docker-compose.yaml`. + + To run testing awx instance, follow [instructions] + (https://github.com/ansible/awx/tree/devel/tools/docker-compose#getting-started) + + Before running `make docker-compose` comment out `- 8080:8080` port mapping in file + `tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2` to avoid port conflict with nautobot. + + After setting up awx, cd back to chatops repo and run `invoke connect-awx-container`. + """ + bridge_network = f"{context.nautobot_chatops.project_name}_awx" + context.run(f"docker network connect --alias awx {bridge_network} {container_name}") + print(f"Container {container_name} connected to {bridge_network} network")