diff --git a/.bandit.yml b/.bandit.yml index 4824c564..d42f9460 100644 --- a/.bandit.yml +++ b/.bandit.yml @@ -1,7 +1,7 @@ --- +skips: + - "B404" # Ignore subprocess # No need to check for security issues in the test scripts! exclude_dirs: - "./nautobot_chatops/tests/" - -skips: - - "B404" + - "./.venv/" diff --git a/.cookiecutter.json b/.cookiecutter.json new file mode 100644 index 00000000..d1e2df97 --- /dev/null +++ b/.cookiecutter.json @@ -0,0 +1,35 @@ +{ + "cookiecutter": { + "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", + "_drift_manager": { + "template": "https://github.com/nautobot/cookiecutter-nautobot-app.git", + "template_dir": "nautobot-app", + "template_ref": "refs/tags/nautobot-app-v2.2.1", + "cookie_dir": "", + "branch_prefix": "drift-manager", + "pull_request_strategy": "create", + "post_actions": [ + "black" + ], + "draft": true, + "baked_commit_ref": "cfd9475f3ea601572d0f3b23d4bb6d9655bc2721" + } + } +} diff --git a/.dockerignore b/.dockerignore index aacfd4e3..2270f496 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,27 @@ +# Docker related +development/Dockerfile +development/docker-compose*.yml +development/*.env +*.env +environments/ + +# Python **/*.pyc **/*.pyo -**/*.log +**/__pycache__/ +**/.pytest_cache/ +**/.venv/ + + +# Other +docs/_build +FAQ.md .git/ -.github/ .gitignore -Dockerfile -docker-compose.yml -.env -docs/_build -__pycache__/ \ No newline at end of file +.github +tasks.py +LICENSE +**/*.log +**/.vscode/ +invoke*.yml +tasks.py diff --git a/.flake8 b/.flake8 index 8193a5d0..696795e1 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,12 @@ [flake8] -# E501: Line length is enforced by Black, so flake8 doesn't need to check it -# W503: Black disagrees with this rule, as does PEP 8; Black wins -ignore = E501, W503, F811, F401 \ No newline at end of file +ignore = + F401, # Module imported but unused + F811, # Redefinition of unused name from line N + E501, # Line length is enforced by Black, so flake8 doesn't need to check it + W503 # Black disagrees with this rule, as does PEP 8; Black wins +exclude = + migrations, + __pycache__, + manage.py, + settings.py, + .venv diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5f4290b0..2f389fec 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,9 @@ -# Default owners for all files in this repository -* @glennmatthews @jvanderaa @smk4664 @whitej6 +# Default owner(s) of all files in this repository +* @glennmatthews @smk4664 @whitej6 @romanukes +/nautobot_chatops/integrations/aci/ @pato23arg +/nautobot_chatops/integrations/ansible/ @smk4664 +/nautobot_chatops/integrations/aristacv/ @qduk +/nautobot_chatops/integrations/grafana/ @davidban77 +/nautobot_chatops/integrations/meraki/ @jeffkala +/nautobot_chatops/integrations/ipfabric/ @alhogan @pke11y +/nautobot_chatops/integrations/panorama/ @jdrew82 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2a57e1af..93878502 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,12 +1,19 @@ --- name: 🐛 Bug Report -about: Report a reproducible bug in the current release of nautobot-plugin-chatops +about: Report a reproducible bug in the current release of nautobot-chatops --- ### Environment -* Python version: -* Nautobot version: -* nautobot-plugin-chatops version: +* Python version: +* Nautobot version: +* nautobot-chatops version: + + +### Expected Behavior + + + +### Observed Behavior -### Expected Behavior - - - -### Observed Behavior \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbeb5de2..2324a93a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -5,8 +5,8 @@ about: Propose a new feature or enhancement --- ### Environment -* Nautobot version: -* nautobot-plugin-chatops version: +* Nautobot version: +* nautobot-chatops version: + # Closes: # ## What's Changed + -## TODO +## To Do + - [ ] Explanation of Change(s) -- [ ] Added change log fragment(s) (for more information see [the documentation](https://docs.nautobot.com/projects/chatops/en/latest/dev/contributing/#creating-changelog-fragments)) +- [ ] Added change log fragment(s) (for more information see [the documentation](https://docs.nautobot.com/projects/core/en/stable/development/#creating-changelog-fragments)) - [ ] Attached Screenshots, Payload Example - [ ] Unit, Integration Tests - [ ] Documentation Updates (when adding/changing features) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59d01289..17bd2cfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,152 +3,223 @@ name: "CI" concurrency: # Cancel any existing runs of this workflow for this same PR group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true -on: # yamllint disable - - "push" - - "pull_request" +on: # yamllint disable-line rule:truthy rule:comments + push: + branches: + - "main" + - "develop" + tags: + - "v*" + pull_request: ~ + +env: + APP_NAME: "nautobot-app-chatops" jobs: black: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - with: - python-version: "3.10" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: black" run: "poetry run invoke black" bandit: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - with: - python-version: "3.10" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: bandit" run: "poetry run invoke bandit" - needs: - - "black" - pydocstyle: - runs-on: "ubuntu-20.04" + ruff: + runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - with: - python-version: "3.10" - - name: "Linting: pydocstyle" - run: "poetry run invoke pydocstyle" - needs: - - "black" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + - name: "Linting: ruff" + run: "poetry run invoke ruff" + check-docs-build: + runs-on: "ubuntu-22.04" + env: + INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v4" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + - name: "Check Docs Build" + run: "poetry run invoke build-and-check-docs" flake8: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - with: - python-version: "3.10" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: flake8" run: "poetry run invoke flake8" - needs: - - "black" + poetry: + runs-on: "ubuntu-22.04" + env: + INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v4" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + - name: "Checking: poetry lock file" + run: "poetry run invoke lock --check" yamllint: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - with: - python-version: "3.10" + uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Linting: yamllint" run: "poetry run invoke yamllint" + check-in-docker: needs: + - "bandit" + - "ruff" + - "flake8" + - "poetry" + - "yamllint" - "black" - pylint: - runs-on: "ubuntu-20.04" + 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@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + - name: "Set up Docker Buildx" + id: "buildx" + uses: "docker/setup-buildx-action@v3" + - name: "Build" + uses: "docker/build-push-action@v5" with: - python-version: "3.10" + 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: "Linting: Pylint" + - name: "Linting: pylint" run: "poetry run invoke pylint" - needs: - - "bandit" - - "pydocstyle" - - "flake8" - - "yamllint" + - name: "Checking: App Config" + run: "poetry run invoke validate-app-config" + - name: "Checking: migrations" + run: "poetry run invoke check-migrations" unittest: + needs: + - "check-in-docker" strategy: fail-fast: true matrix: - python-version: ["3.8"] - db-backend: ["postgresql", "mysql"] - nautobot-version: ["2.0.0"] - # The include is a method to limit the amount of jobs ran. This essentially - # means that in addition to standard postgres and stable, also the lowest - # supported version and with mysql + python-version: ["3.8", "3.11"] + db-backend: ["postgresql"] + nautobot-version: ["stable"] include: - python-version: "3.11" db-backend: "postgresql" nautobot-version: "2.0.0" - - python-version: "3.11" - db-backend: "postgresql" - nautobot-version: "stable" - python-version: "3.11" db-backend: "mysql" nautobot-version: "stable" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" 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@v2" + uses: "actions/checkout@v4" - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + - name: "Set up Docker Buildx" + id: "buildx" + uses: "docker/setup-buildx-action@v3" + - name: "Build" + uses: "docker/build-push-action@v5" with: - python-version: "${{ matrix.python-version }}" + 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: "Build Container" - run: "poetry run invoke build" + - name: "Use Mysql invoke settings when needed" + run: "cp invoke.mysql.yml invoke.yml" + if: "matrix.db-backend == 'mysql'" - name: "Run Tests" run: "poetry run invoke unittest" - needs: - - "pylint" + changelog: + if: | + contains(fromJson('["develop","ltm-1.6"]'), github.base_ref) && + (github.head_ref != 'main') + runs-on: "ubuntu-22.04" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v4" + with: + fetch-depth: "0" + - name: "Setup environment" + 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 }} + poetry run towncrier check --compare-with origin/${{ github.base_ref }} publish_gh: + needs: + - "unittest" name: "Publish to GitHub" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" if: "startsWith(github.ref, 'refs/tags/v')" + env: + INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Set up Python" - uses: "actions/setup-python@v2" + uses: "actions/setup-python@v5" with: - python-version: "3.9" + python-version: "3.11" - name: "Install Python Packages" run: "pip install poetry" - name: "Set env" @@ -158,7 +229,7 @@ jobs: - name: "Install Dependencies (needed for mkdocs)" run: "poetry install --no-root" - name: "Build Documentation" - run: "poetry run mkdocs build --no-directory-urls --strict" + run: "poetry run invoke build-and-check-docs" - name: "Run Poetry Build" run: "poetry build" - name: "Upload binaries to release" @@ -169,19 +240,21 @@ jobs: tag: "${{ github.ref }}" overwrite: true file_glob: true + publish_pypi: needs: - "unittest" - publish_pypi: name: "Push Package to PyPI" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" if: "startsWith(github.ref, 'refs/tags/v')" + env: + INVOKE_NAUTOBOT_CHATOPS_LOCAL: "True" steps: - name: "Check out repository code" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Set up Python" - uses: "actions/setup-python@v2" + uses: "actions/setup-python@v5" with: - python-version: "3.9" + python-version: "3.11" - name: "Install Python Packages" run: "pip install poetry" - name: "Set env" @@ -191,7 +264,7 @@ jobs: - name: "Install Dependencies (needed for mkdocs)" run: "poetry install --no-root" - name: "Build Documentation" - run: "poetry run mkdocs build --no-directory-urls --strict" + run: "poetry run invoke build-and-check-docs" - name: "Run Poetry Build" run: "poetry build" - name: "Push to PyPI" @@ -199,20 +272,38 @@ jobs: with: user: "__token__" password: "${{ secrets.PYPI_API_TOKEN }}" + slack-notify: needs: - - "unittest" - - changelog: - if: github.base_ref == 'develop' || github.base_ref == 'next' - runs-on: "ubuntu-20.04" + - "publish_gh" + - "publish_pypi" + runs-on: "ubuntu-22.04" + env: + SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" + SLACK_MESSAGE: >- + *NOTIFICATION: NEW-RELEASE-PUBLISHED*\n + Repository: <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}>\n + Release: <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}>\n + Published by: <${{ github.server_url }}/${{ github.actor }}|${{ github.actor }}> steps: - - name: "Check out repository code" - uses: "actions/checkout@v2" + - name: "Send a notification to Slack" + # ENVs cannot be used directly in job.if. This is a workaround to check + # if SLACK_WEBHOOK_URL is present. + if: "env.SLACK_WEBHOOK_URL != ''" + uses: "slackapi/slack-github-action@v1" with: - fetch-depth: "0" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v2" - - name: "Check for changelog entry" - run: | - git fetch --no-tags origin +refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} - poetry run towncrier check --compare-with origin/${{ github.base_ref }} + payload: | + { + "text": "${{ env.SLACK_MESSAGE }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ env.SLACK_MESSAGE }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" + SLACK_WEBHOOK_TYPE: "INCOMING_WEBHOOK" diff --git a/.github/workflows/upstream_testing.yml b/.github/workflows/upstream_testing.yml index f6177d89..f8bc77b5 100644 --- a/.github/workflows/upstream_testing.yml +++ b/.github/workflows/upstream_testing.yml @@ -1,5 +1,5 @@ --- -name: "Nautobot Upstream Testing" +name: "Nautobot Upstream Monitor" on: # yamllint disable-line rule:truthy rule:comments schedule: @@ -10,4 +10,4 @@ jobs: uses: "nautobot/nautobot/.github/workflows/plugin_upstream_testing_base.yml@develop" with: # Below could potentially be collapsed into a single argument if a concrete relationship between both is enforced invoke_context_name: "NAUTOBOT_CHATOPS" - plugin_name: "nautobot-chatops-plugin" + plugin_name: "nautobot-app-chatops" diff --git a/.gitignore b/.gitignore index d1cbef39..e0e74aa7 100644 --- a/.gitignore +++ b/.gitignore @@ -171,7 +171,6 @@ ehthumbs_vista.db # Dump file *.stackdump -dumps/ # Folder config file [Dd]esktop.ini @@ -193,8 +192,28 @@ $RECYCLE.BIN/ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -# Jetbrains IDE configs -.idea/ +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, @@ -278,11 +297,14 @@ fabric.properties # Rando creds.env +development/*.txt # Invoke overrides invoke.yml -# Static docs -/nautobot_chatops/static/nautobot_chatops/docs/ +# Docs +public /compose.yaml /dump.sql +/nautobot_chatops/static/nautobot_chatops/docs +docs/admin/release_notes/version_X.Y.md diff --git a/.pydocstyle.ini b/.pydocstyle.ini deleted file mode 100644 index 71bf7596..00000000 --- a/.pydocstyle.ini +++ /dev/null @@ -1,11 +0,0 @@ -[pydocstyle] -convention = google -inherit = false -match = (?!__init__).*\.py -match-dir = (?!tests)[^\.].* -# D212 is enabled by default in google convention, and complains if we have a docstring like: -# """ -# My docstring is on the line after the opening quotes instead of on the same line as them. -# """ -# We've discussed and concluded that we consider this to be a valid style choice. -add_ignore = D212, D417 \ No newline at end of file diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 882d19e9..9a0a64c7 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,14 +8,13 @@ version: 2 # Set the version of Python in the build environment. build: - os: "ubuntu-20.04" + os: "ubuntu-22.04" tools: - python: "3.9" + python: "3.10" -# MKDocs configuration file mkdocs: configuration: "mkdocs.yml" - # fail_on_warning: true + fail_on_warning: true # Use our docs/requirements.txt during installation. python: diff --git a/.yamllint.yml b/.yamllint.yml index 1cc1bcec..3bcf4764 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -1,13 +1,14 @@ --- extends: "default" -ignore: | - setup_files/ - compose.yaml rules: comments: "enable" - empty-values: "enable" + empty-values: "disable" indentation: indent-sequences: "consistent" line-length: "disable" quoted-strings: quote-type: "double" +ignore: | + .venv/ + compose.yaml + setup_files/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1331da75..cd6a4584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Changelog - Nautobot Plugin ChatOps +# Changelog - Nautobot App ChatOps The changelog has been moved to the [project release notes](https://docs.nautobot.com/projects/chatops/en/latest/admin/release_notes/). diff --git a/LICENSE b/LICENSE index 2a07d287..bf295f49 100644 --- a/LICENSE +++ b/LICENSE @@ -1,15 +1,15 @@ -Copyright 2020 Network to Code -Network to Code, LLC +Apache Software License 2.0 + +Copyright (c) 2024, Network to Code, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 +http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file +limitations under the License. diff --git a/README.md b/README.md index 36c0a150..43a0c439 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ -# Nautobot ChatOps +# Nautobot ChatOps App

- +
- - + +
- A multi-platform ChatOps bot App for Nautobot. + A multi-platform ChatOps bot App for Nautobot.

+## Overview + - Support for multiple chat platforms: - Mattermost - Microsoft Teams @@ -25,36 +27,48 @@ - Cisco Meraki - Palo Alto Panorama - Write a command once and run it on every supported platform, including rich content formatting. -- Extensible - other Nautobot plugins can provide additional commands which will be dynamically discovered. +- Extensible - other Nautobot apps can provide additional commands which will be dynamically discovered. - Automatic generation of basic help menus (accessed via `help`, `/command help`, or `/command sub-command help`). -- Metrics of command usage via the `nautobot_capacity_metrics` plugin. +- Metrics of command usage via the `nautobot_capacity_metrics` app. -## Documentation +### Screenshots -Full web-based HTML documentation for this app can be found over on the [Nautobot Docs](https://docs.nautobot.com/projects/chatops/en/latest/) website: +#### Command: `/nautobot` -- [User Guide](https://docs.nautobot.com/projects/chatops/en/latest/user/app_overview/) - Overview, Using the App, Getting Started -- [Administrator Guide](https://docs.nautobot.com/projects/chatops/en/latest/admin/install/) - How to Install, Configure, Upgrade, or Uninstall the App. -- [Developer Guide](https://docs.nautobot.com/projects/chatops/en/latest/dev/contributing/) - Extending the App, Code Reference, Contribution Guide. -- [Release Notes / Changelog](https://docs.nautobot.com/projects/chatops/en/latest/admin/release_notes/) -- [Frequently Asked Questions](https://docs.nautobot.com/projects/chatops/en/latest/user/app_faq/) -- [Glossary](https://docs.nautobot.com/projects/chatops/en/latest/glossary/) +![image](https://user-images.githubusercontent.com/6332586/118281576-5db4e980-b49b-11eb-8574-1332ed4b9757.png) -## Try it Out +#### Command: `/nautobot get-devices` -Interested to see Nautobot ChatOps in action? It's currently setup on the [Demo Instance](https://demo.nautobot.com/) and integrated into [NTC Slack](https://slack.networktocode.com). You can sign up for that Slack workspace and join the `#nautobot-chat` channel to understand what this bot can do and try it for yourself. You can try these exact chat commands and many more: +![image](https://user-images.githubusercontent.com/6332586/118281772-95239600-b49b-11eb-9c79-e2040dc4a982.png) -### Command: `/nautobot` +#### Command: `/nautobot get-interface-connections` -![image](https://user-images.githubusercontent.com/6332586/118281576-5db4e980-b49b-11eb-8574-1332ed4b9757.png) +![image](https://user-images.githubusercontent.com/6332586/118281976-ca2fe880-b49b-11eb-87ad-2a41eaa168ed.png) -### Command: `/nautobot get-devices` +## Try it out! -![image](https://user-images.githubusercontent.com/6332586/118281772-95239600-b49b-11eb-9c79-e2040dc4a982.png) +This App is installed in the Nautobot Community Sandbox found over at [demo.nautobot.com](https://demo.nautobot.com/)! -### Command: `/nautobot get-interface-connections` +> For a full list of all the available always-on sandbox environments, head over to the main page on [networktocode.com](https://www.networktocode.com/nautobot/sandbox-environments/). -![image](https://user-images.githubusercontent.com/6332586/118281976-ca2fe880-b49b-11eb-87ad-2a41eaa168ed.png) +## Documentation + +Full documentation for this App can be found over on the [Nautobot Docs](https://docs.nautobot.com) website: + +- [User Guide](https://docs.nautobot.com/projects/chatops/en/latest/user/app_overview/) - Overview, Using the App, Getting Started. +- [Administrator Guide](https://docs.nautobot.com/projects/chatops/en/latest/admin/install/) - How to Install, Configure, Upgrade, or Uninstall the App. +- [Developer Guide](https://docs.nautobot.com/projects/chatops/en/latest/dev/contributing/) - Extending the App, Code Reference, Contribution Guide. +- [Release Notes / Changelog](https://docs.nautobot.com/projects/chatops/en/latest/admin/release_notes/). +- [Frequently Asked Questions](https://docs.nautobot.com/projects/chatops/en/latest/user/faq/). +- [Glossary](https://docs.nautobot.com/projects/chatops/en/latest/glossary/) + +### Contributing to the Documentation + +You can find all the Markdown source for the App documentation under the [`docs`](https://github.com/nautobot/nautobot-app-chatops/tree/develop/docs) folder in this repository. For simple edits, a Markdown capable editor is sufficient: clone the repository and edit away. + +If you need to view the fully-generated documentation site, you can build it with [MkDocs](https://www.mkdocs.org/). A container hosting the documentation can be started using the `invoke` commands (details in the [Development Environment Guide](https://docs.nautobot.com/projects/chatops/en/latest/dev/dev_environment/#docker-development-environment)) on [http://localhost:8001](http://localhost:8001). Using this container, as your changes to the documentation are saved, they will be automatically rebuilt and any pages currently being viewed will be reloaded in your browser. + +Any PRs with fixes or improvements are very welcome! ## Questions @@ -63,7 +77,7 @@ Sign up [here](https://slack.networktocode.com/) ## Acknowledgements -This project includes code originally written in separate plugins, which have been merged into this project: +This project includes code originally written in separate apps, which have been merged into this project: - [nautobot-plugin-chatops-aci](https://github.com/nautobot/nautobot-plugin-chatops-aci): Thanks diff --git a/changes/309.housekeeping b/changes/309.housekeeping new file mode 100644 index 00000000..9d48b6f2 --- /dev/null +++ b/changes/309.housekeeping @@ -0,0 +1 @@ +Release v3.0.2 diff --git a/development/Dockerfile b/development/Dockerfile index a5931cf7..69d8a0f9 100644 --- a/development/Dockerfile +++ b/development/Dockerfile @@ -6,11 +6,11 @@ # ------------------------------------------------------------------------------------- # !!! USE CAUTION WHEN MODIFYING LINES BELOW -# Accepts a desired Nautobot version as build argument, default to 1.5.4 -ARG NAUTOBOT_VER="1.5.4" +# Accepts a desired Nautobot version as build argument, default to 2.0.0 +ARG NAUTOBOT_VER="2.0.0" -# Accepts a desired Python version as build argument, default to 3.8 -ARG PYTHON_VER="3.8" +# Accepts a desired Python version as build argument, default to 3.11 +ARG PYTHON_VER="3.11" # Retrieve published development image of Nautobot base which should include most CI dependencies FROM ghcr.io/nautobot/nautobot-dev:${NAUTOBOT_VER}-py${PYTHON_VER} @@ -19,20 +19,21 @@ FROM ghcr.io/nautobot/nautobot-dev:${NAUTOBOT_VER}-py${PYTHON_VER} ARG NAUTOBOT_ROOT=/opt/nautobot ENV prometheus_multiproc_dir=/prom_cache -ENV NAUTOBOT_ROOT ${NAUTOBOT_ROOT} +ENV NAUTOBOT_ROOT=${NAUTOBOT_ROOT} +ENV INVOKE_NAUTOBOT_CHATOPS_LOCAL=true # Install Poetry manually via its installer script; # We might be using an older version of Nautobot that includes an older version of Poetry # and CI and local development may have a newer version of Poetry # 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 curl -sSL https://install.python-poetry.org | python3 - && \ - poetry config virtualenvs.create false +RUN which poetry || curl -sSL https://install.python-poetry.org | python3 - && \ + poetry config virtualenvs.create false # !!! USE CAUTION WHEN MODIFYING LINES ABOVE # ------------------------------------------------------------------------------------- # App-specifc system build/test dependencies. -# +# # Example: LDAP requires `libldap2-dev` to be apt-installed before the Python package. # ------------------------------------------------------------------------------------- # --> Start safe to modify section @@ -62,17 +63,19 @@ RUN pip show nautobot | grep "^Version: " | sed -e 's/Version: /nautobot==/' > c # # We can't use the entire freeze as it takes forever to resolve with rigidly fixed non-direct dependencies, # especially those that are only direct to Nautobot but the container included versions slightly mismatch -RUN poetry export -f requirements.txt --without-hashes --output poetry_freeze_base.txt -RUN poetry export -f requirements.txt --with dev --without-hashes --output poetry_freeze_all.txt +RUN poetry export -f requirements.txt --without-hashes --extras all --output poetry_freeze_base.txt +RUN poetry export -f requirements.txt --without-hashes --extras all --with dev --output poetry_freeze_all.txt RUN sort poetry_freeze_base.txt poetry_freeze_all.txt | uniq -u > poetry_freeze_dev.txt # Install all local project as editable, constrained on Nautobot version, to get any additional # direct dependencies of the app -RUN pip install -c constraints.txt -e .[all] +RUN --mount=type=cache,target="/root/.cache/pip",sharing=locked \ + pip install -c constraints.txt -e .[all] # Install any dev dependencies frozen from Poetry # Can be improved in Poetry 1.2 which allows `poetry install --only dev` -RUN pip install -c constraints.txt -r poetry_freeze_dev.txt +RUN --mount=type=cache,target="/root/.cache/pip",sharing=locked \ + pip install -c constraints.txt -r poetry_freeze_dev.txt COPY development/nautobot_config.py ${NAUTOBOT_ROOT}/nautobot_config.py # !!! 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/creds.example.env b/development/creds.example.env index 34f27de1..e269244a 100644 --- a/development/creds.example.env +++ b/development/creds.example.env @@ -29,7 +29,7 @@ MYSQL_PASSWORD=${NAUTOBOT_DB_PASSWORD} # = Chat Platforms =================== # - Mattermost ----------------------- -MATTERMOST_API_TOKEN="5qsffxoapt883qfdygbdgf17jy" +MATTERMOST_API_TOKEN="nsutx44ibbd69r5hjjmd3hx4sw" # - Microsoft Teams ------------------ # MICROSOFT_APP_ID="changeme" @@ -69,7 +69,7 @@ NAUTOBOT_TOWER_PASSWORD="admin" # - Grafana -------------------------- # GRAFANA_API_KEY="changeme" -# - IPFabric --------------------- +# - IPFabric ------------------------- # IPFABRIC_API_TOKEN="changeme" # - Cisco Meraki --------------------- @@ -77,3 +77,7 @@ NAUTOBOT_TOWER_PASSWORD="admin" # - Palo Alto Panorama --------------- # PANORAMA_PASSWORD="changeme" + +# - Cisco NSO ------------------------ +# NSO_USERNAME="changeme" +# NSO_PASSWORD="changeme" \ No newline at end of file diff --git a/development/development.env b/development/development.env index b395947b..82706ab8 100644 --- a/development/development.env +++ b/development/development.env @@ -7,8 +7,6 @@ NAUTOBOT_BANNER_TOP="Local" NAUTOBOT_CHANGELOG_RETENTION=0 NAUTOBOT_DEBUG=True -NAUTOBOT_DJANGO_EXTENSIONS_ENABLED=True -NAUTOBOT_DJANGO_TOOLBAR_ENABLED=True NAUTOBOT_LOG_LEVEL=DEBUG NAUTOBOT_METRICS_ENABLED=True NAUTOBOT_NAPALM_TIMEOUT=5 @@ -96,3 +94,9 @@ NAUTOBOT_CHATOPS_ENABLE_MERAKI="False" NAUTOBOT_CHATOPS_ENABLE_PANORAMA="False" PANORAMA_HOST="https://panorama.example.com" PANORAMA_USER="admin" + +# - Cisco NSO ------------------------ +NAUTOBOT_CHATOPS_ENABLE_NSO="False" +# NSO_URL="https://nso.example.com" +# NSO_USERNAME="admin" +# NSO_PASSWORD="admin" diff --git a/development/docker-compose.base.yml b/development/docker-compose.base.yml index 680e3786..9e17c4ad 100644 --- a/development/docker-compose.base.yml +++ b/development/docker-compose.base.yml @@ -7,7 +7,7 @@ x-nautobot-build: &nautobot-build context: "../" dockerfile: "development/Dockerfile" x-nautobot-base: &nautobot-base - image: "nautobot-chatops-plugin/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" + image: "nautobot-chatops/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" env_file: - "development.env" - "creds.env" @@ -28,9 +28,10 @@ services: entrypoint: - "sh" - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env - - "watchmedo auto-restart --directory './' --pattern '*.py' --recursive -- nautobot-server celery worker -l $$NAUTOBOT_LOG_LEVEL --events" ## $$ because of docker-compose + - "nautobot-server celery worker -l $$NAUTOBOT_LOG_LEVEL --events" ## $$ because of docker-compose depends_on: - - "nautobot" + nautobot: + condition: "service_healthy" healthcheck: interval: "30s" timeout: "10s" @@ -44,7 +45,8 @@ services: - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env - "nautobot-server celery beat -l $$NAUTOBOT_LOG_LEVEL" ## $$ because of docker-compose depends_on: - - "nautobot" + nautobot: + condition: "service_healthy" healthcheck: disable: true <<: *nautobot-base diff --git a/development/docker-compose.dev.yml b/development/docker-compose.dev.yml index 1c74cb19..106be230 100644 --- a/development/docker-compose.dev.yml +++ b/development/docker-compose.dev.yml @@ -12,18 +12,37 @@ services: volumes: - "./nautobot_config.py:/opt/nautobot/nautobot_config.py" - "../:/source" + healthcheck: + interval: "30s" + timeout: "10s" + start_period: "60s" + retries: 3 + test: ["CMD", "true"] # Due to layering, disable: true won't work. Instead, change the test docs: entrypoint: "mkdocs serve -v -a 0.0.0.0:8080" ports: - "8001:8080" volumes: - - "../docs:/source/docs:ro" - - "../mkdocs.yml:/source/mkdocs.yml:ro" - image: "nautobot-chatops-plugin/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" + - "../:/source" + image: "nautobot-chatops/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" healthcheck: disable: true tty: true worker: + entrypoint: + - "sh" + - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env + - "watchmedo auto-restart --directory './' --pattern '*.py' --recursive -- nautobot-server celery worker -l $$NAUTOBOT_LOG_LEVEL --events" ## $$ because of docker-compose + volumes: + - "./nautobot_config.py:/opt/nautobot/nautobot_config.py" + - "../:/source" + healthcheck: + test: ["CMD", "true"] # Due to layering, disable: true won't work. Instead, change the test + beat: + entrypoint: + - "sh" + - "-c" # this is to evaluate the $NAUTOBOT_LOG_LEVEL from the env + - "watchmedo auto-restart --directory './' --pattern '*.py' --recursive -- nautobot-server celery beat -l $$NAUTOBOT_LOG_LEVEL" ## $$ because of docker-compose volumes: - "./nautobot_config.py:/opt/nautobot/nautobot_config.py" - "../:/source" diff --git a/development/docker-compose.mysql.yml b/development/docker-compose.mysql.yml index 32f1f945..062ada94 100644 --- a/development/docker-compose.mysql.yml +++ b/development/docker-compose.mysql.yml @@ -20,7 +20,7 @@ services: image: "mysql:8" command: - "--default-authentication-plugin=mysql_native_password" - - "--max_connections=200" + - "--max_connections=1000" env_file: - "development.env" - "creds.env" diff --git a/development/docker-compose.postgres.yml b/development/docker-compose.postgres.yml index 8582412b..12d1de31 100644 --- a/development/docker-compose.postgres.yml +++ b/development/docker-compose.postgres.yml @@ -14,7 +14,6 @@ services: - "development.env" - "creds.env" volumes: - # - "./nautobot.sql:/tmp/nautobot.sql" - "postgres_data:/var/lib/postgresql/data" healthcheck: test: "pg_isready --username=$$POSTGRES_USER --dbname=$$POSTGRES_DB" diff --git a/development/grafana/prometheus.yml b/development/grafana/prometheus.yml index b51ced44..5471c53d 100644 --- a/development/grafana/prometheus.yml +++ b/development/grafana/prometheus.yml @@ -20,11 +20,6 @@ scrape_configs: static_configs: - targets: ["nautobot:8080"] - - job_name: "nautobot_rq" - metrics_path: "/api/plugins/capacity-metrics/rq-metrics" - static_configs: - - targets: ["nautobot:8080"] - - job_name: "worker" dns_sd_configs: - names: diff --git a/development/mattermost/docker-compose.yml b/development/mattermost/docker-compose.yml index f1041801..db35af18 100644 --- a/development/mattermost/docker-compose.yml +++ b/development/mattermost/docker-compose.yml @@ -10,10 +10,11 @@ services: worker: <<: *nautobot mattermost: - image: "mattermost/mattermost-preview:7.8.9" + image: "mattermost/mattermost-preview:9.0.1" hostname: "mattermost" environment: MM_LOGSETTINGS_SENDCRASHREPORTS: "false" + MM_SERVICESETTINGS_ALLOWCORSFROM: "*" MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS: "0.0.0.0/0" MM_SERVICESETTINGS_ENABLEDEVELOPER: "true" MM_SERVICESETTINGS_ENABLEDIAGNOSTICS: "false" @@ -23,6 +24,6 @@ services: - "8065:8065" volumes: - "./mattermost/dump.sql:/docker-entrypoint-initdb.d/dump.sql" - - "mattermost-data:/var/lib/mysql" + - "mattermost-data:/var/lib/postgresql/data" volumes: mattermost-data: {} diff --git a/development/mattermost/dump.sql b/development/mattermost/dump.sql index f0e3cb82..26260c29 100644 --- a/development/mattermost/dump.sql +++ b/development/mattermost/dump.sql @@ -1,1863 +1,4131 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 12.16 (Debian 12.16-1.pgdg120+1) +-- Dumped by pg_dump version 12.16 (Debian 12.16-1.pgdg120+1) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: channel_type; Type: TYPE; Schema: public; Owner: mmuser +-- + +CREATE TYPE public.channel_type AS ENUM ( + 'P', + 'G', + 'O', + 'D' +); + + +ALTER TYPE public.channel_type OWNER TO mmuser; + +-- +-- Name: team_type; Type: TYPE; Schema: public; Owner: mmuser +-- + +CREATE TYPE public.team_type AS ENUM ( + 'I', + 'O' +); + + +ALTER TYPE public.team_type OWNER TO mmuser; + +-- +-- Name: upload_session_type; Type: TYPE; Schema: public; Owner: mmuser +-- + +CREATE TYPE public.upload_session_type AS ENUM ( + 'attachment', + 'import' +); + + +ALTER TYPE public.upload_session_type OWNER TO mmuser; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: audits; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.audits ( + id character varying(26) NOT NULL, + createat bigint, + userid character varying(26), + action character varying(512), + extrainfo character varying(1024), + ipaddress character varying(64), + sessionid character varying(26) +); + + +ALTER TABLE public.audits OWNER TO mmuser; + +-- +-- Name: bots; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.bots ( + userid character varying(26) NOT NULL, + description character varying(1024), + ownerid character varying(190), + createat bigint, + updateat bigint, + deleteat bigint, + lasticonupdate bigint +); + + +ALTER TABLE public.bots OWNER TO mmuser; + +-- +-- Name: channelmemberhistory; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.channelmemberhistory ( + channelid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + jointime bigint NOT NULL, + leavetime bigint +); + + +ALTER TABLE public.channelmemberhistory OWNER TO mmuser; + +-- +-- Name: channelmembers; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.channelmembers ( + channelid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + roles character varying(256), + lastviewedat bigint, + msgcount bigint, + mentioncount bigint, + notifyprops jsonb, + lastupdateat bigint, + schemeuser boolean, + schemeadmin boolean, + schemeguest boolean, + mentioncountroot bigint, + msgcountroot bigint, + urgentmentioncount bigint +); + + +ALTER TABLE public.channelmembers OWNER TO mmuser; + +-- +-- Name: channels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.channels ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + teamid character varying(26), + type public.channel_type, + displayname character varying(64), + name character varying(64), + header character varying(1024), + purpose character varying(250), + lastpostat bigint, + totalmsgcount bigint, + extraupdateat bigint, + creatorid character varying(26), + schemeid character varying(26), + groupconstrained boolean, + shared boolean, + totalmsgcountroot bigint, + lastrootpostat bigint DEFAULT '0'::bigint +); + + +ALTER TABLE public.channels OWNER TO mmuser; + +-- +-- Name: clusterdiscovery; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.clusterdiscovery ( + id character varying(26) NOT NULL, + type character varying(64), + clustername character varying(64), + hostname character varying(512), + gossipport integer, + port integer, + createat bigint, + lastpingat bigint +); + + +ALTER TABLE public.clusterdiscovery OWNER TO mmuser; + +-- +-- Name: commands; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.commands ( + id character varying(26) NOT NULL, + token character varying(26), + createat bigint, + updateat bigint, + deleteat bigint, + creatorid character varying(26), + teamid character varying(26), + trigger character varying(128), + method character varying(1), + username character varying(64), + iconurl character varying(1024), + autocomplete boolean, + autocompletedesc character varying(1024), + autocompletehint character varying(1024), + displayname character varying(64), + description character varying(128), + url character varying(1024), + pluginid character varying(190) +); + + +ALTER TABLE public.commands OWNER TO mmuser; + +-- +-- Name: commandwebhooks; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.commandwebhooks ( + id character varying(26) NOT NULL, + createat bigint, + commandid character varying(26), + userid character varying(26), + channelid character varying(26), + rootid character varying(26), + usecount integer +); + + +ALTER TABLE public.commandwebhooks OWNER TO mmuser; + +-- +-- Name: compliances; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.compliances ( + id character varying(26) NOT NULL, + createat bigint, + userid character varying(26), + status character varying(64), + count integer, + "desc" character varying(512), + type character varying(64), + startat bigint, + endat bigint, + keywords character varying(512), + emails character varying(1024) +); + + +ALTER TABLE public.compliances OWNER TO mmuser; + +-- +-- Name: db_lock; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.db_lock ( + id character varying(64) NOT NULL, + expireat bigint +); + + +ALTER TABLE public.db_lock OWNER TO mmuser; + +-- +-- Name: db_migrations; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.db_migrations ( + version bigint NOT NULL, + name character varying NOT NULL +); + + +ALTER TABLE public.db_migrations OWNER TO mmuser; + +-- +-- Name: drafts; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.drafts ( + createat bigint, + updateat bigint, + deleteat bigint, + userid character varying(26) NOT NULL, + channelid character varying(26) NOT NULL, + rootid character varying(26) DEFAULT ''::character varying NOT NULL, + message character varying(65535), + props character varying(8000), + fileids character varying(300), + priority text +); + + +ALTER TABLE public.drafts OWNER TO mmuser; + +-- +-- Name: emoji; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.emoji ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + creatorid character varying(26), + name character varying(64) +); + + +ALTER TABLE public.emoji OWNER TO mmuser; + +-- +-- Name: fileinfo; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.fileinfo ( + id character varying(26) NOT NULL, + creatorid character varying(26), + postid character varying(26), + createat bigint, + updateat bigint, + deleteat bigint, + path character varying(512), + thumbnailpath character varying(512), + previewpath character varying(512), + name character varying(256), + extension character varying(64), + size bigint, + mimetype character varying(256), + width integer, + height integer, + haspreviewimage boolean, + minipreview bytea, + content text, + remoteid character varying(26), + archived boolean DEFAULT false NOT NULL, + channelid character varying(26) +) +WITH (autovacuum_vacuum_scale_factor='0.1', autovacuum_analyze_scale_factor='0.05'); + + +ALTER TABLE public.fileinfo OWNER TO mmuser; + +-- +-- Name: groupchannels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.groupchannels ( + groupid character varying(26) NOT NULL, + autoadd boolean, + schemeadmin boolean, + createat bigint, + deleteat bigint, + updateat bigint, + channelid character varying(26) NOT NULL +); + + +ALTER TABLE public.groupchannels OWNER TO mmuser; + +-- +-- Name: groupmembers; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.groupmembers ( + groupid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + createat bigint, + deleteat bigint +); + + +ALTER TABLE public.groupmembers OWNER TO mmuser; + +-- +-- Name: groupteams; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.groupteams ( + groupid character varying(26) NOT NULL, + autoadd boolean, + schemeadmin boolean, + createat bigint, + deleteat bigint, + updateat bigint, + teamid character varying(26) NOT NULL +); + + +ALTER TABLE public.groupteams OWNER TO mmuser; + +-- +-- Name: incomingwebhooks; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.incomingwebhooks ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + userid character varying(26), + channelid character varying(26), + teamid character varying(26), + displayname character varying(64), + description character varying(500), + username character varying(255), + iconurl character varying(1024), + channellocked boolean +); + + +ALTER TABLE public.incomingwebhooks OWNER TO mmuser; + +-- +-- Name: ir_category; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_category ( + id character varying(26) NOT NULL, + name character varying(512) NOT NULL, + teamid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + collapsed boolean DEFAULT false, + createat bigint NOT NULL, + updateat bigint DEFAULT 0 NOT NULL, + deleteat bigint DEFAULT 0 NOT NULL +); + + +ALTER TABLE public.ir_category OWNER TO mmuser; + +-- +-- Name: ir_category_item; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_category_item ( + type character varying(1) NOT NULL, + categoryid character varying(26) NOT NULL, + itemid character varying(26) NOT NULL +); + + +ALTER TABLE public.ir_category_item OWNER TO mmuser; + +-- +-- Name: ir_channelaction; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_channelaction ( + id character varying(26) NOT NULL, + channelid character varying(26), + enabled boolean DEFAULT false, + deleteat bigint DEFAULT 0 NOT NULL, + actiontype character varying(65535) NOT NULL, + triggertype character varying(65535) NOT NULL, + payload json NOT NULL +); + + +ALTER TABLE public.ir_channelaction OWNER TO mmuser; + +-- +-- Name: ir_incident; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_incident ( + id character varying(26) NOT NULL, + name character varying(1024) NOT NULL, + description character varying(4096) NOT NULL, + isactive boolean NOT NULL, + commanderuserid character varying(26) NOT NULL, + teamid character varying(26) NOT NULL, + channelid character varying(26) NOT NULL, + createat bigint NOT NULL, + endat bigint DEFAULT 0 NOT NULL, + deleteat bigint DEFAULT 0 NOT NULL, + activestage bigint NOT NULL, + postid character varying(26) DEFAULT ''::text NOT NULL, + playbookid character varying(26) DEFAULT ''::text NOT NULL, + checklistsjson json NOT NULL, + activestagetitle character varying(1024) DEFAULT ''::text, + reminderpostid character varying(26), + broadcastchannelid character varying(26) DEFAULT ''::text, + previousreminder bigint DEFAULT 0 NOT NULL, + remindermessagetemplate character varying(65535) DEFAULT ''::text, + currentstatus character varying(1024) DEFAULT 'Active'::text NOT NULL, + reporteruserid character varying(26) DEFAULT ''::text NOT NULL, + concatenatedinviteduserids character varying(65535) DEFAULT ''::text, + defaultcommanderid character varying(26) DEFAULT ''::text, + announcementchannelid character varying(26) DEFAULT ''::text, + concatenatedwebhookoncreationurls character varying(65535) DEFAULT ''::text, + concatenatedinvitedgroupids character varying(65535) DEFAULT ''::text, + retrospective character varying(65535) DEFAULT ''::text, + messageonjoin character varying(65535) DEFAULT ''::text, + retrospectivepublishedat bigint DEFAULT 0 NOT NULL, + retrospectivereminderintervalseconds bigint DEFAULT 0 NOT NULL, + retrospectivewascanceled boolean DEFAULT false, + concatenatedwebhookonstatusupdateurls character varying(65535) DEFAULT ''::text, + laststatusupdateat bigint DEFAULT 0, + exportchannelonfinishedenabled boolean DEFAULT false NOT NULL, + categorizechannelenabled boolean DEFAULT false, + categoryname character varying(65535) DEFAULT ''::text, + concatenatedbroadcastchannelids character varying(65535), + channelidtorootid character varying(65535) DEFAULT ''::text, + remindertimerdefaultseconds bigint DEFAULT 0 NOT NULL, + statusupdateenabled boolean DEFAULT true, + retrospectiveenabled boolean DEFAULT true, + statusupdatebroadcastchannelsenabled boolean DEFAULT false, + statusupdatebroadcastwebhooksenabled boolean DEFAULT false, + summarymodifiedat bigint DEFAULT 0 NOT NULL, + createchannelmemberonnewparticipant boolean DEFAULT true, + removechannelmemberonremovedparticipant boolean DEFAULT true, + runtype character varying(32) DEFAULT 'playbook'::character varying +); + + +ALTER TABLE public.ir_incident OWNER TO mmuser; + +-- +-- Name: ir_metric; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_metric ( + incidentid character varying(26) NOT NULL, + metricconfigid character varying(26) NOT NULL, + value bigint, + published boolean NOT NULL +); + + +ALTER TABLE public.ir_metric OWNER TO mmuser; + +-- +-- Name: ir_metricconfig; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_metricconfig ( + id character varying(26) NOT NULL, + playbookid character varying(26) NOT NULL, + title character varying(512) NOT NULL, + description character varying(4096) NOT NULL, + type character varying(32) NOT NULL, + target bigint, + ordering smallint DEFAULT 0 NOT NULL, + deleteat bigint DEFAULT 0 NOT NULL +); + + +ALTER TABLE public.ir_metricconfig OWNER TO mmuser; + +-- +-- Name: ir_playbook; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_playbook ( + id character varying(26) NOT NULL, + title character varying(1024) NOT NULL, + description character varying(4096) NOT NULL, + teamid character varying(26) NOT NULL, + createpublicincident boolean NOT NULL, + createat bigint NOT NULL, + deleteat bigint DEFAULT 0 NOT NULL, + checklistsjson json NOT NULL, + numstages bigint DEFAULT 0 NOT NULL, + numsteps bigint DEFAULT 0 NOT NULL, + broadcastchannelid character varying(26) DEFAULT ''::text, + remindermessagetemplate character varying(65535) DEFAULT ''::text, + remindertimerdefaultseconds bigint DEFAULT 0 NOT NULL, + concatenatedinviteduserids character varying(65535) DEFAULT ''::text, + inviteusersenabled boolean DEFAULT false, + defaultcommanderid character varying(26) DEFAULT ''::text, + defaultcommanderenabled boolean DEFAULT false, + announcementchannelid character varying(26) DEFAULT ''::text, + announcementchannelenabled boolean DEFAULT false, + concatenatedwebhookoncreationurls character varying(65535) DEFAULT ''::text, + webhookoncreationenabled boolean DEFAULT false, + concatenatedinvitedgroupids character varying(65535) DEFAULT ''::text, + messageonjoin character varying(65535) DEFAULT ''::text, + messageonjoinenabled boolean DEFAULT false, + retrospectivereminderintervalseconds bigint DEFAULT 0 NOT NULL, + retrospectivetemplate character varying(65535), + concatenatedwebhookonstatusupdateurls character varying(65535) DEFAULT ''::text, + webhookonstatusupdateenabled boolean DEFAULT false, + concatenatedsignalanykeywords character varying(65535) DEFAULT ''::text, + signalanykeywordsenabled boolean DEFAULT false, + updateat bigint DEFAULT 0 NOT NULL, + exportchannelonfinishedenabled boolean DEFAULT false NOT NULL, + categorizechannelenabled boolean DEFAULT false, + categoryname character varying(65535) DEFAULT ''::text, + concatenatedbroadcastchannelids character varying(65535), + broadcastenabled boolean DEFAULT false, + runsummarytemplate character varying(65535) DEFAULT ''::text, + channelnametemplate character varying(65535) DEFAULT ''::text, + statusupdateenabled boolean DEFAULT true, + retrospectiveenabled boolean DEFAULT true, + public boolean DEFAULT false, + runsummarytemplateenabled boolean DEFAULT true, + createchannelmemberonnewparticipant boolean DEFAULT true, + removechannelmemberonremovedparticipant boolean DEFAULT true, + channelid character varying(26) DEFAULT ''::character varying, + channelmode character varying(32) DEFAULT 'create_new_channel'::character varying +); + + +ALTER TABLE public.ir_playbook OWNER TO mmuser; + +-- +-- Name: ir_playbookautofollow; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_playbookautofollow ( + playbookid character varying(26) NOT NULL, + userid character varying(26) NOT NULL +); + + +ALTER TABLE public.ir_playbookautofollow OWNER TO mmuser; + +-- +-- Name: ir_playbookmember; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_playbookmember ( + playbookid character varying(26) NOT NULL, + memberid character varying(26) NOT NULL, + roles character varying(65535) +); + + +ALTER TABLE public.ir_playbookmember OWNER TO mmuser; + +-- +-- Name: ir_run_participants; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_run_participants ( + userid character varying(26) NOT NULL, + incidentid character varying(26) NOT NULL, + isfollower boolean DEFAULT false NOT NULL, + isparticipant boolean DEFAULT false +); + + +ALTER TABLE public.ir_run_participants OWNER TO mmuser; + +-- +-- Name: ir_statusposts; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_statusposts ( + incidentid character varying(26) NOT NULL, + postid character varying(26) NOT NULL +); + + +ALTER TABLE public.ir_statusposts OWNER TO mmuser; + +-- +-- Name: ir_system; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_system ( + skey character varying(64) NOT NULL, + svalue character varying(1024) +); + + +ALTER TABLE public.ir_system OWNER TO mmuser; + +-- +-- Name: ir_timelineevent; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_timelineevent ( + id character varying(26) NOT NULL, + incidentid character varying(26) NOT NULL, + createat bigint NOT NULL, + deleteat bigint DEFAULT 0 NOT NULL, + eventat bigint NOT NULL, + eventtype character varying(32) DEFAULT ''::text NOT NULL, + summary character varying(256) DEFAULT ''::text NOT NULL, + details character varying(4096) DEFAULT ''::text NOT NULL, + postid character varying(26) DEFAULT ''::text NOT NULL, + subjectuserid character varying(26) DEFAULT ''::text NOT NULL, + creatoruserid character varying(26) DEFAULT ''::text NOT NULL +); + + +ALTER TABLE public.ir_timelineevent OWNER TO mmuser; + +-- +-- Name: ir_userinfo; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_userinfo ( + id character varying(26) NOT NULL, + lastdailytododmat bigint, + digestnotificationsettingsjson json +); + + +ALTER TABLE public.ir_userinfo OWNER TO mmuser; + +-- +-- Name: ir_viewedchannel; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.ir_viewedchannel ( + channelid character varying(26) NOT NULL, + userid character varying(26) NOT NULL +); + + +ALTER TABLE public.ir_viewedchannel OWNER TO mmuser; + +-- +-- Name: jobs; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.jobs ( + id character varying(26) NOT NULL, + type character varying(32), + priority bigint, + createat bigint, + startat bigint, + lastactivityat bigint, + status character varying(32), + progress bigint, + data jsonb +); + + +ALTER TABLE public.jobs OWNER TO mmuser; + +-- +-- Name: licenses; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.licenses ( + id character varying(26) NOT NULL, + createat bigint, + bytes character varying(10000) +); + + +ALTER TABLE public.licenses OWNER TO mmuser; + +-- +-- Name: linkmetadata; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.linkmetadata ( + hash bigint NOT NULL, + url character varying(2048), + "timestamp" bigint, + type character varying(16), + data jsonb +); + + +ALTER TABLE public.linkmetadata OWNER TO mmuser; + +-- +-- Name: notifyadmin; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.notifyadmin ( + userid character varying(26) NOT NULL, + createat bigint, + requiredplan character varying(100) NOT NULL, + requiredfeature character varying(255) NOT NULL, + trial boolean NOT NULL, + sentat bigint +); + + +ALTER TABLE public.notifyadmin OWNER TO mmuser; + +-- +-- Name: oauthaccessdata; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.oauthaccessdata ( + token character varying(26) NOT NULL, + refreshtoken character varying(26), + redirecturi character varying(256), + clientid character varying(26), + userid character varying(26), + expiresat bigint, + scope character varying(128) +); + + +ALTER TABLE public.oauthaccessdata OWNER TO mmuser; + +-- +-- Name: oauthapps; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.oauthapps ( + id character varying(26) NOT NULL, + creatorid character varying(26), + createat bigint, + updateat bigint, + clientsecret character varying(128), + name character varying(64), + description character varying(512), + callbackurls character varying(1024), + homepage character varying(256), + istrusted boolean, + iconurl character varying(512), + mattermostappid character varying(32) DEFAULT ''::character varying NOT NULL +); + + +ALTER TABLE public.oauthapps OWNER TO mmuser; + +-- +-- Name: oauthauthdata; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.oauthauthdata ( + clientid character varying(26), + userid character varying(26), + code character varying(128) NOT NULL, + expiresin integer, + createat bigint, + redirecturi character varying(256), + state character varying(1024), + scope character varying(128) +); + + +ALTER TABLE public.oauthauthdata OWNER TO mmuser; + +-- +-- Name: outgoingwebhooks; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.outgoingwebhooks ( + id character varying(26) NOT NULL, + token character varying(26), + createat bigint, + updateat bigint, + deleteat bigint, + creatorid character varying(26), + channelid character varying(26), + teamid character varying(26), + triggerwords character varying(1024), + callbackurls character varying(1024), + displayname character varying(64), + contenttype character varying(128), + triggerwhen integer, + username character varying(64), + iconurl character varying(1024), + description character varying(500) +); + + +ALTER TABLE public.outgoingwebhooks OWNER TO mmuser; + +-- +-- Name: persistentnotifications; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.persistentnotifications ( + postid character varying(26) NOT NULL, + createat bigint, + lastsentat bigint, + deleteat bigint, + sentcount smallint +); + + +ALTER TABLE public.persistentnotifications OWNER TO mmuser; + +-- +-- Name: pluginkeyvaluestore; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.pluginkeyvaluestore ( + pluginid character varying(190) NOT NULL, + pkey character varying(150) NOT NULL, + pvalue bytea, + expireat bigint +); + + +ALTER TABLE public.pluginkeyvaluestore OWNER TO mmuser; + +-- +-- Name: postacknowledgements; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.postacknowledgements ( + postid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + acknowledgedat bigint +); + + +ALTER TABLE public.postacknowledgements OWNER TO mmuser; + +-- +-- Name: postreminders; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.postreminders ( + postid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + targettime bigint +); + + +ALTER TABLE public.postreminders OWNER TO mmuser; + +-- +-- Name: posts; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.posts ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + userid character varying(26), + channelid character varying(26), + rootid character varying(26), + originalid character varying(26), + message character varying(65535), + type character varying(26), + props jsonb, + hashtags character varying(1000), + filenames character varying(4000), + fileids character varying(300), + hasreactions boolean, + editat bigint, + ispinned boolean, + remoteid character varying(26) +) +WITH (autovacuum_vacuum_scale_factor='0.1', autovacuum_analyze_scale_factor='0.05'); + + +ALTER TABLE public.posts OWNER TO mmuser; + +-- +-- Name: postspriority; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.postspriority ( + postid character varying(26) NOT NULL, + channelid character varying(26) NOT NULL, + priority character varying(32) NOT NULL, + requestedack boolean, + persistentnotifications boolean +); + + +ALTER TABLE public.postspriority OWNER TO mmuser; + +-- +-- Name: preferences; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.preferences ( + userid character varying(26) NOT NULL, + category character varying(32) NOT NULL, + name character varying(32) NOT NULL, + value character varying(2000) +) +WITH (autovacuum_vacuum_scale_factor='0.1', autovacuum_analyze_scale_factor='0.05'); + + +ALTER TABLE public.preferences OWNER TO mmuser; + +-- +-- Name: productnoticeviewstate; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.productnoticeviewstate ( + userid character varying(26) NOT NULL, + noticeid character varying(26) NOT NULL, + viewed integer, + "timestamp" bigint +); + + +ALTER TABLE public.productnoticeviewstate OWNER TO mmuser; + +-- +-- Name: publicchannels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.publicchannels ( + id character varying(26) NOT NULL, + deleteat bigint, + teamid character varying(26), + displayname character varying(64), + name character varying(64), + header character varying(1024), + purpose character varying(250) +); + + +ALTER TABLE public.publicchannels OWNER TO mmuser; + +-- +-- Name: reactions; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.reactions ( + userid character varying(26) NOT NULL, + postid character varying(26) NOT NULL, + emojiname character varying(64) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + remoteid character varying(26), + channelid character varying(26) DEFAULT ''::character varying NOT NULL +); + + +ALTER TABLE public.reactions OWNER TO mmuser; + +-- +-- Name: recentsearches; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.recentsearches ( + userid character(26) NOT NULL, + searchpointer integer NOT NULL, + query jsonb, + createat bigint NOT NULL +); + + +ALTER TABLE public.recentsearches OWNER TO mmuser; + +-- +-- Name: remoteclusters; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.remoteclusters ( + remoteid character varying(26) NOT NULL, + remoteteamid character varying(26), + name character varying(64) NOT NULL, + displayname character varying(64), + siteurl character varying(512), + createat bigint, + lastpingat bigint, + token character varying(26), + remotetoken character varying(26), + topics character varying(512), + creatorid character varying(26) +); + + +ALTER TABLE public.remoteclusters OWNER TO mmuser; + +-- +-- Name: retentionpolicies; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.retentionpolicies ( + id character varying(26) NOT NULL, + displayname character varying(64), + postduration bigint +); + + +ALTER TABLE public.retentionpolicies OWNER TO mmuser; + +-- +-- Name: retentionpolicieschannels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.retentionpolicieschannels ( + policyid character varying(26), + channelid character varying(26) NOT NULL +); + + +ALTER TABLE public.retentionpolicieschannels OWNER TO mmuser; + +-- +-- Name: retentionpoliciesteams; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.retentionpoliciesteams ( + policyid character varying(26), + teamid character varying(26) NOT NULL +); + + +ALTER TABLE public.retentionpoliciesteams OWNER TO mmuser; + +-- +-- Name: roles; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.roles ( + id character varying(26) NOT NULL, + name character varying(64), + displayname character varying(128), + description character varying(1024), + createat bigint, + updateat bigint, + deleteat bigint, + permissions text, + schememanaged boolean, + builtin boolean +); + + +ALTER TABLE public.roles OWNER TO mmuser; + +-- +-- Name: schemes; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.schemes ( + id character varying(26) NOT NULL, + name character varying(64), + displayname character varying(128), + description character varying(1024), + createat bigint, + updateat bigint, + deleteat bigint, + scope character varying(32), + defaultteamadminrole character varying(64), + defaultteamuserrole character varying(64), + defaultchanneladminrole character varying(64), + defaultchanneluserrole character varying(64), + defaultteamguestrole character varying(64), + defaultchannelguestrole character varying(64), + defaultplaybookadminrole character varying(64) DEFAULT ''::character varying, + defaultplaybookmemberrole character varying(64) DEFAULT ''::character varying, + defaultrunadminrole character varying(64) DEFAULT ''::character varying, + defaultrunmemberrole character varying(64) DEFAULT ''::character varying +); + + +ALTER TABLE public.schemes OWNER TO mmuser; + +-- +-- Name: sessions; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sessions ( + id character varying(26) NOT NULL, + token character varying(26), + createat bigint, + expiresat bigint, + lastactivityat bigint, + userid character varying(26), + deviceid character varying(512), + roles character varying(256), + isoauth boolean, + props jsonb, + expirednotify boolean +); + + +ALTER TABLE public.sessions OWNER TO mmuser; + +-- +-- Name: sharedchannelattachments; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sharedchannelattachments ( + id character varying(26) NOT NULL, + fileid character varying(26), + remoteid character varying(26), + createat bigint, + lastsyncat bigint +); + + +ALTER TABLE public.sharedchannelattachments OWNER TO mmuser; + +-- +-- Name: sharedchannelremotes; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sharedchannelremotes ( + id character varying(26) NOT NULL, + channelid character varying(26) NOT NULL, + creatorid character varying(26), + createat bigint, + updateat bigint, + isinviteaccepted boolean, + isinviteconfirmed boolean, + remoteid character varying(26), + lastpostupdateat bigint, + lastpostid character varying(26) +); + + +ALTER TABLE public.sharedchannelremotes OWNER TO mmuser; + +-- +-- Name: sharedchannels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sharedchannels ( + channelid character varying(26) NOT NULL, + teamid character varying(26), + home boolean, + readonly boolean, + sharename character varying(64), + sharedisplayname character varying(64), + sharepurpose character varying(250), + shareheader character varying(1024), + creatorid character varying(26), + createat bigint, + updateat bigint, + remoteid character varying(26) +); + + +ALTER TABLE public.sharedchannels OWNER TO mmuser; + +-- +-- Name: sharedchannelusers; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sharedchannelusers ( + id character varying(26) NOT NULL, + userid character varying(26), + remoteid character varying(26), + createat bigint, + lastsyncat bigint, + channelid character varying(26) +); + + +ALTER TABLE public.sharedchannelusers OWNER TO mmuser; + +-- +-- Name: sidebarcategories; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sidebarcategories ( + id character varying(128) NOT NULL, + userid character varying(26), + teamid character varying(26), + sortorder bigint, + sorting character varying(64), + type character varying(64), + displayname character varying(64), + muted boolean, + collapsed boolean +); + + +ALTER TABLE public.sidebarcategories OWNER TO mmuser; + +-- +-- Name: sidebarchannels; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.sidebarchannels ( + channelid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + categoryid character varying(128) NOT NULL, + sortorder bigint +); + + +ALTER TABLE public.sidebarchannels OWNER TO mmuser; + +-- +-- Name: status; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.status ( + userid character varying(26) NOT NULL, + status character varying(32), + manual boolean, + lastactivityat bigint, + dndendtime bigint, + prevstatus character varying(32) +); + + +ALTER TABLE public.status OWNER TO mmuser; + +-- +-- Name: systems; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.systems ( + name character varying(64) NOT NULL, + value character varying(1024) +); + + +ALTER TABLE public.systems OWNER TO mmuser; + +-- +-- Name: teammembers; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.teammembers ( + teamid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + roles character varying(256), + deleteat bigint, + schemeuser boolean, + schemeadmin boolean, + schemeguest boolean, + createat bigint DEFAULT 0 +); + + +ALTER TABLE public.teammembers OWNER TO mmuser; + +-- +-- Name: teams; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.teams ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + displayname character varying(64), + name character varying(64), + description character varying(255), + email character varying(128), + type public.team_type, + companyname character varying(64), + alloweddomains character varying(1000), + inviteid character varying(32), + schemeid character varying(26), + allowopeninvite boolean, + lastteamiconupdate bigint, + groupconstrained boolean, + cloudlimitsarchived boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public.teams OWNER TO mmuser; + +-- +-- Name: termsofservice; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.termsofservice ( + id character varying(26) NOT NULL, + createat bigint, + userid character varying(26), + text character varying(65535) +); + + +ALTER TABLE public.termsofservice OWNER TO mmuser; + +-- +-- Name: threadmemberships; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.threadmemberships ( + postid character varying(26) NOT NULL, + userid character varying(26) NOT NULL, + following boolean, + lastviewed bigint, + lastupdated bigint, + unreadmentions bigint +) +WITH (autovacuum_vacuum_scale_factor='0.1', autovacuum_analyze_scale_factor='0.05'); + + +ALTER TABLE public.threadmemberships OWNER TO mmuser; + +-- +-- Name: threads; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.threads ( + postid character varying(26) NOT NULL, + replycount bigint, + lastreplyat bigint, + participants jsonb, + channelid character varying(26), + threaddeleteat bigint, + threadteamid character varying(26) +); + + +ALTER TABLE public.threads OWNER TO mmuser; + +-- +-- Name: tokens; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.tokens ( + token character varying(64) NOT NULL, + createat bigint, + type character varying(64), + extra character varying(2048) +); + + +ALTER TABLE public.tokens OWNER TO mmuser; + +-- +-- Name: trueupreviewhistory; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.trueupreviewhistory ( + duedate bigint NOT NULL, + completed boolean +); + + +ALTER TABLE public.trueupreviewhistory OWNER TO mmuser; + +-- +-- Name: uploadsessions; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.uploadsessions ( + id character varying(26) NOT NULL, + type public.upload_session_type, + createat bigint, + userid character varying(26), + channelid character varying(26), + filename character varying(256), + path character varying(512), + filesize bigint, + fileoffset bigint, + remoteid character varying(26), + reqfileid character varying(26) +); + + +ALTER TABLE public.uploadsessions OWNER TO mmuser; + +-- +-- Name: useraccesstokens; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.useraccesstokens ( + id character varying(26) NOT NULL, + token character varying(26), + userid character varying(26), + description character varying(512), + isactive boolean +); + + +ALTER TABLE public.useraccesstokens OWNER TO mmuser; + +-- +-- Name: usergroups; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.usergroups ( + id character varying(26) NOT NULL, + name character varying(64), + displayname character varying(128), + description character varying(1024), + source character varying(64), + remoteid character varying(48), + createat bigint, + updateat bigint, + deleteat bigint, + allowreference boolean +); + + +ALTER TABLE public.usergroups OWNER TO mmuser; + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.users ( + id character varying(26) NOT NULL, + createat bigint, + updateat bigint, + deleteat bigint, + username character varying(64), + password character varying(128), + authdata character varying(128), + authservice character varying(32), + email character varying(128), + emailverified boolean, + nickname character varying(64), + firstname character varying(64), + lastname character varying(64), + roles character varying(256), + allowmarketing boolean, + props jsonb, + notifyprops jsonb, + lastpasswordupdate bigint, + lastpictureupdate bigint, + failedattempts integer, + locale character varying(5), + mfaactive boolean, + mfasecret character varying(128), + "position" character varying(128), + timezone jsonb, + remoteid character varying(26) +); + + +ALTER TABLE public.users OWNER TO mmuser; + +-- +-- Name: usertermsofservice; Type: TABLE; Schema: public; Owner: mmuser +-- + +CREATE TABLE public.usertermsofservice ( + userid character varying(26) NOT NULL, + termsofserviceid character varying(26), + createat bigint +); + + +ALTER TABLE public.usertermsofservice OWNER TO mmuser; + +-- +-- Data for Name: audits; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.audits VALUES ('dkj3tzm46inzubfgf8tcdp7pgw', 1698320750982, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/login', 'attempt - login_id=', '10.166.35.2', ''); +INSERT INTO public.audits VALUES ('xtxom8758j8mxxdhrtcycp1tyo', 1698320751056, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/login', 'authenticated', '10.166.35.2', ''); +INSERT INTO public.audits VALUES ('1u86rwj3ybbpfxmyxunew5iiyo', 1698320751070, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/login', 'success session_user=5md7bsji6pbijpxitu8bwezaqy', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('epra3qoyoifddyceqttxptsq4c', 1698320751647, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/system/onboarding/complete', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('ipozu9wift8fbms4rb9ix7kenw', 1698320870617, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/config', 'updateConfig', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('8fp9etosrfdfxy6z178qwzw4wy', 1698321187446, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/config', 'updateConfig', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('yb5cthepg7gd7xe6y1es4q3i8o', 1698321288420, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/w7uyhzuo7fnfueen6og9cxmn9h/image', '', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('jbu85hiszig9xxmz6r3omg4nwy', 1698321288523, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/w7uyhzuo7fnfueen6og9cxmn9h/tokens', '', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('pyhkh6us4tf8ic1qrcfm3n894a', 1698321288537, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/w7uyhzuo7fnfueen6og9cxmn9h/tokens', 'success - token_id=7xnejgyhj7nxtmq6t95iah7n7c', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('cu16juhnu7b4fn8owx5nxfhfsy', 1698321288591, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/users/w7uyhzuo7fnfueen6og9cxmn9h/roles', 'user=w7uyhzuo7fnfueen6og9cxmn9h roles=system_user system_admin', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('ox8eh5qg3b8didjy49qxt3e4zw', 1698321530586, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('e8mxhfjtnjyh3eksti7mmujsmo', 1698321530615, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('zekyg5c5bfgqbx4kzfdh8syrba', 1698322016025, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('ku9ztthjwtdw8fh1apbd8m7bwc', 1698322016048, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('xujye8uua78q9rzccctgu8hpsa', 1698322240876, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('5beieks3zbf83xehax7g5jqfuh', 1698322240899, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('j1pfzdoo5tffmfwey58nfoijuy', 1698322317970, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('jp4ubo31ebydjbx6rq9scoh5br', 1698322317993, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('fugumx1egbdz5psurrtzwd4pdr', 1698322371244, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('k9w475y7qjdkpksbp8yqjbuirc', 1698322371257, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('hoq9u8pfotfg3mm9kwmm7j85hr', 1698322417402, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('jzd5mhtq8briiqgy98mr11k6xe', 1698322417424, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('xwd9hbd5hby88fic55cgwkx3mo', 1698322479254, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('kjjukwgn4pffufedkzd5toeacw', 1698322479277, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('r9kxec153td49bpghdq3nme61h', 1698322532935, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('7zx6716r4fnutmhfqt49jehmoc', 1698322532958, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('n9iyafdkfpbhmxmmif9zfafjmh', 1698322585562, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'attempt', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); +INSERT INTO public.audits VALUES ('88uom3gn4bbgigihxcyzxt1wch', 1698322585586, '5md7bsji6pbijpxitu8bwezaqy', '/api/v4/commands', 'success', '10.166.35.2', 'xprkr99nfirmb8j4pdfzqhhtar'); + + +-- +-- Data for Name: bots; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.bots VALUES ('jmcgoiar5brr9nx8s7g3394c8e', 'Feedbackbot collects user feedback to improve Mattermost. [Learn more](https://mattermost.com/pl/default-nps).', 'com.mattermost.nps', 1698320582722, 1698320582722, 0, 0); +INSERT INTO public.bots VALUES ('mt3fq81mrbbydrefss1h9zfxhw', 'Playbooks bot.', 'playbooks', 1698320583270, 1698320583270, 0, 0); +INSERT INTO public.bots VALUES ('qicfanjtzbgsf8qh8zkosdq96e', 'Calls Bot', 'com.mattermost.calls', 1698320583530, 1698320583530, 0, 0); +INSERT INTO public.bots VALUES ('dnyqmp4u5tgetr9or6in55xobr', '', '5md7bsji6pbijpxitu8bwezaqy', 1698321000016, 1698321000016, 0, 0); +INSERT INTO public.bots VALUES ('w7uyhzuo7fnfueen6og9cxmn9h', 'Nautobot Mattermost Bot', '5md7bsji6pbijpxitu8bwezaqy', 1698321288290, 1698321288290, 0, 0); + + +-- +-- Data for Name: channelmemberhistory; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.channelmemberhistory VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', '5md7bsji6pbijpxitu8bwezaqy', 1698320784767, NULL); +INSERT INTO public.channelmemberhistory VALUES ('g44m7cnnkjn6tbqsica1ste4jw', '5md7bsji6pbijpxitu8bwezaqy', 1698320784798, NULL); +INSERT INTO public.channelmemberhistory VALUES ('686m6w41q3bidjcxrsuymudgba', 'w7uyhzuo7fnfueen6og9cxmn9h', 1698321288312, NULL); +INSERT INTO public.channelmemberhistory VALUES ('686m6w41q3bidjcxrsuymudgba', '5md7bsji6pbijpxitu8bwezaqy', 1698321288318, NULL); +INSERT INTO public.channelmemberhistory VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', 'w7uyhzuo7fnfueen6og9cxmn9h', 1698321691905, NULL); +INSERT INTO public.channelmemberhistory VALUES ('g44m7cnnkjn6tbqsica1ste4jw', 'w7uyhzuo7fnfueen6og9cxmn9h', 1698321691933, NULL); + + +-- +-- Data for Name: channelmembers; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.channelmembers VALUES ('g44m7cnnkjn6tbqsica1ste4jw', '5md7bsji6pbijpxitu8bwezaqy', '', 0, 0, 0, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698320784790, true, true, false, 0, 0, 0); +INSERT INTO public.channelmembers VALUES ('686m6w41q3bidjcxrsuymudgba', 'w7uyhzuo7fnfueen6og9cxmn9h', '', 0, 0, 0, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698321288298, true, false, false, 0, 0, 0); +INSERT INTO public.channelmembers VALUES ('686m6w41q3bidjcxrsuymudgba', '5md7bsji6pbijpxitu8bwezaqy', '', 1698321288325, 1, 0, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698321288325, true, false, false, 0, 1, 0); +INSERT INTO public.channelmembers VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', 'w7uyhzuo7fnfueen6og9cxmn9h', '', 0, 0, 0, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698321691897, true, false, false, 0, 0, 0); +INSERT INTO public.channelmembers VALUES ('g44m7cnnkjn6tbqsica1ste4jw', 'w7uyhzuo7fnfueen6og9cxmn9h', '', 0, 0, 1, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698321691953, true, false, false, 1, 0, 0); +INSERT INTO public.channelmembers VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', '5md7bsji6pbijpxitu8bwezaqy', '', 1698322063240, 1, 0, '{"push": "default", "email": "default", "desktop": "default", "mark_unread": "all", "ignore_channel_mentions": "default", "channel_auto_follow_threads": "off"}', 1698322063240, true, true, false, 0, 1, 0); + + +-- +-- Data for Name: channels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.channels VALUES ('686m6w41q3bidjcxrsuymudgba', 1698321288297, 1698321288297, 0, '', 'D', '', '5md7bsji6pbijpxitu8bwezaqy__w7uyhzuo7fnfueen6og9cxmn9h', '', '', 1698321288325, 1, 0, 'w7uyhzuo7fnfueen6og9cxmn9h', NULL, NULL, false, 1, 1698321288325); +INSERT INTO public.channels VALUES ('g44m7cnnkjn6tbqsica1ste4jw', 1698320784731, 1698320784731, 0, 'rkpuunm3rp8fffhzkjxw63usyc', 'O', 'Off-Topic', 'off-topic', '', '', 1698321691939, 0, 0, '', NULL, NULL, NULL, 0, 1698321691939); +INSERT INTO public.channels VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', 1698320784722, 1698320784722, 0, 'rkpuunm3rp8fffhzkjxw63usyc', 'O', 'Town Square', 'town-square', '', '', 1698322063240, 1, 0, '', NULL, NULL, NULL, 1, 1698322063240); + + +-- +-- Data for Name: clusterdiscovery; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: commands; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.commands VALUES ('pkksc6zkt7g65q7jtwadpgs9rr', 'u7p1an973bd1jqg75i3y7pxj7y', 1698321530602, 1698321530602, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'clear', 'P', '', '', false, '', '', 'Clear', 'Clear Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('z3egwchjfb85zkstcdupcge8pc', 'ncygprhkt3rrxr4rkytcaa7c9c', 1698322016041, 1698322016041, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'nautobot', 'P', '', '', false, '', '', 'Nautobot', 'Nautobot Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('qfd8w7rpq7neuphzmo3miaw1jr', 'b9wrs7paz7fi5ragz9uurwd9fa', 1698322240892, 1698322240892, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'aci', 'P', '', '', false, '', '', 'Cisco ACI', 'Cisco ACI Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('ifttckqrjpyrxr7ks1w5qjm81c', '4hz941bgtpde9g75sesdp7tp1h', 1698322317986, 1698322317986, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'ansible', 'P', '', '', false, '', '', 'Ansible', 'Ansible Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('a4u4gwfa6tggtc6kziyryxsk3a', '71o3ku7jwjyxup6biu1way1h5y', 1698322371251, 1698322371251, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'arista', 'P', '', '', false, '', '', 'Arista CloudVision', 'Arista CloudVision Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('urmj87oqbbynir8nzc33by1f4c', '3wxwh3m8mjrzxr11psersqkwue', 1698322417418, 1698322417418, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'grafana', 'P', '', '', false, '', '', 'Grafana', 'Grafana Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('mw51fho6ojd3fxqmrgfkt9xykw', 'ppm316za33ritm3xgpobcmmgre', 1698322479271, 1698322479271, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'ipfabric', 'P', '', '', false, '', '', 'IP Fabric', 'IP Fabric Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('11cwjihduffn3ceybits6n5zty', '11ix54hycjr4dmxcgw4d77qc4w', 1698322532951, 1698322532951, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'meraki', 'P', '', '', false, '', '', 'Cisco Meraki', 'Cisco Meraki Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('p43ko8rim3r89d78yexbg3fiww', 'fh1kbk45xtgm8r48jzr39ru1ww', 1698322585580, 1698322585580, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'panorama', 'P', '', '', false, '', '', 'Panorama', 'Panorama Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); +INSERT INTO public.commands VALUES ('qbxb8a33cimdw77hyxjeuyg80i', 'j9bcga71hl4lreaczecen7i5dz', 1698322527456, 1698322527456, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'nso', 'P', '', '', false, '', '', 'Cisco NSO', 'Cisco NSO Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', ''); + + +-- +-- Data for Name: commandwebhooks; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: compliances; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: db_lock; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: db_migrations; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.db_migrations VALUES (1, 'create_teams'); +INSERT INTO public.db_migrations VALUES (2, 'create_team_members'); +INSERT INTO public.db_migrations VALUES (3, 'create_cluster_discovery'); +INSERT INTO public.db_migrations VALUES (4, 'create_command_webhooks'); +INSERT INTO public.db_migrations VALUES (5, 'create_compliances'); +INSERT INTO public.db_migrations VALUES (6, 'create_emojis'); +INSERT INTO public.db_migrations VALUES (7, 'create_user_groups'); +INSERT INTO public.db_migrations VALUES (8, 'create_group_members'); +INSERT INTO public.db_migrations VALUES (9, 'create_group_teams'); +INSERT INTO public.db_migrations VALUES (10, 'create_group_channels'); +INSERT INTO public.db_migrations VALUES (11, 'create_link_metadata'); +INSERT INTO public.db_migrations VALUES (12, 'create_commands'); +INSERT INTO public.db_migrations VALUES (13, 'create_incoming_webhooks'); +INSERT INTO public.db_migrations VALUES (14, 'create_outgoing_webhooks'); +INSERT INTO public.db_migrations VALUES (15, 'create_systems'); +INSERT INTO public.db_migrations VALUES (16, 'create_reactions'); +INSERT INTO public.db_migrations VALUES (17, 'create_roles'); +INSERT INTO public.db_migrations VALUES (18, 'create_schemes'); +INSERT INTO public.db_migrations VALUES (19, 'create_licenses'); +INSERT INTO public.db_migrations VALUES (20, 'create_posts'); +INSERT INTO public.db_migrations VALUES (21, 'create_product_notice_view_state'); +INSERT INTO public.db_migrations VALUES (22, 'create_sessions'); +INSERT INTO public.db_migrations VALUES (23, 'create_terms_of_service'); +INSERT INTO public.db_migrations VALUES (24, 'create_audits'); +INSERT INTO public.db_migrations VALUES (25, 'create_oauth_access_data'); +INSERT INTO public.db_migrations VALUES (26, 'create_preferences'); +INSERT INTO public.db_migrations VALUES (27, 'create_status'); +INSERT INTO public.db_migrations VALUES (28, 'create_tokens'); +INSERT INTO public.db_migrations VALUES (29, 'create_bots'); +INSERT INTO public.db_migrations VALUES (30, 'create_user_access_tokens'); +INSERT INTO public.db_migrations VALUES (31, 'create_remote_clusters'); +INSERT INTO public.db_migrations VALUES (32, 'create_sharedchannels'); +INSERT INTO public.db_migrations VALUES (33, 'create_sidebar_channels'); +INSERT INTO public.db_migrations VALUES (34, 'create_oauthauthdata'); +INSERT INTO public.db_migrations VALUES (35, 'create_sharedchannelattachments'); +INSERT INTO public.db_migrations VALUES (36, 'create_sharedchannelusers'); +INSERT INTO public.db_migrations VALUES (37, 'create_sharedchannelremotes'); +INSERT INTO public.db_migrations VALUES (38, 'create_jobs'); +INSERT INTO public.db_migrations VALUES (39, 'create_channel_member_history'); +INSERT INTO public.db_migrations VALUES (40, 'create_sidebar_categories'); +INSERT INTO public.db_migrations VALUES (41, 'create_upload_sessions'); +INSERT INTO public.db_migrations VALUES (42, 'create_threads'); +INSERT INTO public.db_migrations VALUES (43, 'thread_memberships'); +INSERT INTO public.db_migrations VALUES (44, 'create_user_terms_of_service'); +INSERT INTO public.db_migrations VALUES (45, 'create_plugin_key_value_store'); +INSERT INTO public.db_migrations VALUES (46, 'create_users'); +INSERT INTO public.db_migrations VALUES (47, 'create_file_info'); +INSERT INTO public.db_migrations VALUES (48, 'create_oauth_apps'); +INSERT INTO public.db_migrations VALUES (49, 'create_channels'); +INSERT INTO public.db_migrations VALUES (50, 'create_channelmembers'); +INSERT INTO public.db_migrations VALUES (51, 'create_msg_root_count'); +INSERT INTO public.db_migrations VALUES (52, 'create_public_channels'); +INSERT INTO public.db_migrations VALUES (53, 'create_retention_policies'); +INSERT INTO public.db_migrations VALUES (54, 'create_crt_channelmembership_count'); +INSERT INTO public.db_migrations VALUES (55, 'create_crt_thread_count_and_unreads'); +INSERT INTO public.db_migrations VALUES (56, 'upgrade_channels_v6.0'); +INSERT INTO public.db_migrations VALUES (57, 'upgrade_command_webhooks_v6.0'); +INSERT INTO public.db_migrations VALUES (58, 'upgrade_channelmembers_v6.0'); +INSERT INTO public.db_migrations VALUES (59, 'upgrade_users_v6.0'); +INSERT INTO public.db_migrations VALUES (60, 'upgrade_jobs_v6.0'); +INSERT INTO public.db_migrations VALUES (61, 'upgrade_link_metadata_v6.0'); +INSERT INTO public.db_migrations VALUES (62, 'upgrade_sessions_v6.0'); +INSERT INTO public.db_migrations VALUES (63, 'upgrade_threads_v6.0'); +INSERT INTO public.db_migrations VALUES (64, 'upgrade_status_v6.0'); +INSERT INTO public.db_migrations VALUES (65, 'upgrade_groupchannels_v6.0'); +INSERT INTO public.db_migrations VALUES (66, 'upgrade_posts_v6.0'); +INSERT INTO public.db_migrations VALUES (67, 'upgrade_channelmembers_v6.1'); +INSERT INTO public.db_migrations VALUES (68, 'upgrade_teammembers_v6.1'); +INSERT INTO public.db_migrations VALUES (69, 'upgrade_jobs_v6.1'); +INSERT INTO public.db_migrations VALUES (70, 'upgrade_cte_v6.1'); +INSERT INTO public.db_migrations VALUES (71, 'upgrade_sessions_v6.1'); +INSERT INTO public.db_migrations VALUES (72, 'upgrade_schemes_v6.3'); +INSERT INTO public.db_migrations VALUES (73, 'upgrade_plugin_key_value_store_v6.3'); +INSERT INTO public.db_migrations VALUES (74, 'upgrade_users_v6.3'); +INSERT INTO public.db_migrations VALUES (75, 'alter_upload_sessions_index'); +INSERT INTO public.db_migrations VALUES (76, 'upgrade_lastrootpostat'); +INSERT INTO public.db_migrations VALUES (77, 'upgrade_users_v6.5'); +INSERT INTO public.db_migrations VALUES (78, 'create_oauth_mattermost_app_id'); +INSERT INTO public.db_migrations VALUES (79, 'usergroups_displayname_index'); +INSERT INTO public.db_migrations VALUES (80, 'posts_createat_id'); +INSERT INTO public.db_migrations VALUES (81, 'threads_deleteat'); +INSERT INTO public.db_migrations VALUES (82, 'upgrade_oauth_mattermost_app_id'); +INSERT INTO public.db_migrations VALUES (83, 'threads_threaddeleteat'); +INSERT INTO public.db_migrations VALUES (84, 'recent_searches'); +INSERT INTO public.db_migrations VALUES (85, 'fileinfo_add_archived_column'); +INSERT INTO public.db_migrations VALUES (86, 'add_cloud_limits_archived'); +INSERT INTO public.db_migrations VALUES (87, 'sidebar_categories_index'); +INSERT INTO public.db_migrations VALUES (88, 'remaining_migrations'); +INSERT INTO public.db_migrations VALUES (89, 'add-channelid-to-reaction'); +INSERT INTO public.db_migrations VALUES (90, 'create_enums'); +INSERT INTO public.db_migrations VALUES (91, 'create_post_reminder'); +INSERT INTO public.db_migrations VALUES (92, 'add_createat_to_teamembers'); +INSERT INTO public.db_migrations VALUES (93, 'notify_admin'); +INSERT INTO public.db_migrations VALUES (94, 'threads_teamid'); +INSERT INTO public.db_migrations VALUES (95, 'remove_posts_parentid'); +INSERT INTO public.db_migrations VALUES (96, 'threads_threadteamid'); +INSERT INTO public.db_migrations VALUES (97, 'create_posts_priority'); +INSERT INTO public.db_migrations VALUES (98, 'create_post_acknowledgements'); +INSERT INTO public.db_migrations VALUES (99, 'create_drafts'); +INSERT INTO public.db_migrations VALUES (100, 'add_draft_priority_column'); +INSERT INTO public.db_migrations VALUES (101, 'create_true_up_review_history'); +INSERT INTO public.db_migrations VALUES (102, 'posts_originalid_index'); +INSERT INTO public.db_migrations VALUES (103, 'add_sentat_to_notifyadmin'); +INSERT INTO public.db_migrations VALUES (104, 'upgrade_notifyadmin'); +INSERT INTO public.db_migrations VALUES (105, 'remove_tokens'); +INSERT INTO public.db_migrations VALUES (106, 'fileinfo_channelid'); +INSERT INTO public.db_migrations VALUES (107, 'threadmemberships_cleanup'); +INSERT INTO public.db_migrations VALUES (108, 'remove_orphaned_oauth_preferences'); +INSERT INTO public.db_migrations VALUES (109, 'create_persistent_notifications'); +INSERT INTO public.db_migrations VALUES (111, 'update_vacuuming'); + + +-- +-- Data for Name: drafts; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: emoji; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: fileinfo; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: groupchannels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: groupmembers; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: groupteams; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: incomingwebhooks; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_category; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_category_item; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_channelaction; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_incident; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_metric; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_metricconfig; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_playbook; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_playbookautofollow; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_playbookmember; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_run_participants; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_statusposts; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_system; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.ir_system VALUES ('DatabaseVersion', '0.63.0'); + + +-- +-- Data for Name: ir_timelineevent; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: ir_userinfo; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.ir_userinfo VALUES ('5md7bsji6pbijpxitu8bwezaqy', 1698320802132, '{"disable_daily_digest":false,"disable_weekly_digest":false}'); + + +-- +-- Data for Name: ir_viewedchannel; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: jobs; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.jobs VALUES ('sq83iy4bgidn3gdf4745rkzcco', 'migrations', 0, 1698320643330, 1698320652909, 1698320653134, 'success', 0, '{"last_done": "{\"current_table\":\"ChannelMembers\",\"last_team_id\":\"00000000000000000000000000\",\"last_channel_id\":\"00000000000000000000000000\",\"last_user\":\"00000000000000000000000000\"}", "migration_key": "migration_advanced_permissions_phase_2"}'); + + +-- +-- Data for Name: licenses; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: linkmetadata; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: notifyadmin; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: oauthaccessdata; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: oauthapps; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: oauthauthdata; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: outgoingwebhooks; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: persistentnotifications; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: pluginkeyvaluestore; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.pluginkeyvaluestore VALUES ('com.mattermost.nps', 'ServerUpgrade-9.0.0', '\x7b227365727665725f76657273696f6e223a22392e302e30222c22757067726164655f6174223a22323032332d31302d32365431313a34333a30322e3735323732333133315a227d', 0); +INSERT INTO public.pluginkeyvaluestore VALUES ('com.mattermost.nps', 'WelcomeFeedbackMigration', '\x7b224372656174654174223a22323032332d31302d32365431313a34333a30322e3735323732333133315a227d', 0); +INSERT INTO public.pluginkeyvaluestore VALUES ('com.mattermost.nps', 'Survey-9.0.0', '\x7b227365727665725f76657273696f6e223a22392e302e30222c226372656174655f6174223a22323032332d31302d32365431313a34333a30322e3735323732333133315a222c2273746172745f6174223a22323032332d31322d31305431313a34333a30322e3735323732333133315a227d', 0); +INSERT INTO public.pluginkeyvaluestore VALUES ('com.mattermost.nps', 'LastAdminNotice', '\x22323032332d31302d32365431313a34333a30322e3735323732333133315a22', 0); +INSERT INTO public.pluginkeyvaluestore VALUES ('playbooks', 'mmi_botid', '\x6d7433667138316d726262796472656673733168397a66786877', 0); +INSERT INTO public.pluginkeyvaluestore VALUES ('com.mattermost.calls', 'mmi_botid', '\x71696366616e6a747a62677366387168387a6b6f736471393665', 0); + + +-- +-- Data for Name: postacknowledgements; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: postreminders; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.posts VALUES ('tncer1pq7brn5gx3cp9pmoaqtw', 1698320784773, 1698320784773, 0, '5md7bsji6pbijpxitu8bwezaqy', 'wjcp9j9mjfbe3f8t3mp5544y1w', '', '', 'admin joined the team.', 'system_join_team', '{"username": "admin"}', '', '[]', '[]', false, 0, false, NULL); +INSERT INTO public.posts VALUES ('apr119z86fg1tbuub5x6u6pune', 1698320784805, 1698320784805, 0, '5md7bsji6pbijpxitu8bwezaqy', 'g44m7cnnkjn6tbqsica1ste4jw', '', '', 'admin joined the channel.', 'system_join_channel', '{"username": "admin"}', '', '[]', '[]', false, 0, false, NULL); +INSERT INTO public.posts VALUES ('33p1sunyyb8cmxbqwrxotgyuqe', 1698321288325, 1698321288325, 0, 'w7uyhzuo7fnfueen6og9cxmn9h', '686m6w41q3bidjcxrsuymudgba', '', '', 'Please add me to teams and channels you want me to interact in. To do this, use the browser or Mattermost Desktop App.', 'add_bot_teams_channels', '{"from_bot": "true"}', '', '[]', '[]', false, 0, false, NULL); +INSERT INTO public.posts VALUES ('okcnrhyu638furtk9x7s6z9dnc', 1698321691911, 1698321691911, 0, '5md7bsji6pbijpxitu8bwezaqy', 'wjcp9j9mjfbe3f8t3mp5544y1w', '', '', 'nautobot added to the team by admin.', 'system_add_to_team', '{"userId": "5md7bsji6pbijpxitu8bwezaqy", "username": "admin", "addedUserId": "w7uyhzuo7fnfueen6og9cxmn9h", "addedUsername": "nautobot"}', '', '[]', '[]', false, 0, false, NULL); +INSERT INTO public.posts VALUES ('tn88sqa4cbbnig5wu1hgj6rb7w', 1698321691939, 1698321691939, 0, '5md7bsji6pbijpxitu8bwezaqy', 'g44m7cnnkjn6tbqsica1ste4jw', '', '', 'nautobot added to the channel by admin.', 'system_add_to_channel', '{"userId": "5md7bsji6pbijpxitu8bwezaqy", "username": "admin", "addedUserId": "w7uyhzuo7fnfueen6og9cxmn9h", "addedUsername": "nautobot"}', '', '[]', '[]', false, 0, false, NULL); +INSERT INTO public.posts VALUES ('3e3uz4acwt8h3cxu4xs83zcyzc', 1698322063240, 1698322063240, 0, 'w7uyhzuo7fnfueen6og9cxmn9h', 'wjcp9j9mjfbe3f8t3mp5544y1w', '', '', '', '', '{"from_bot": "true", "attachments": [{"id": 0, "ts": null, "text": "More Chat commands can be found at [Nautobot Apps](https://www.networktocode.com/nautobot/apps/)", "color": "", "title": "", "fields": null, "footer": "", "pretext": "", "fallback": "", "image_url": "", "thumb_url": "", "title_link": "", "author_icon": "", "author_link": "", "author_name": "", "footer_icon": ""}]}', '', '[]', '[]', false, 0, false, NULL); + + +-- +-- Data for Name: postspriority; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: preferences; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'tutorial_step', '5md7bsji6pbijpxitu8bwezaqy', '0'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'recommended_next_steps', 'hide', 'true'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'onboarding_task_list', 'onboarding_task_list_show', 'false'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'onboarding_task_list', 'onboarding_task_list_open', 'false'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'touched', 'add_channels_cta', 'true'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'channel_approximate_view_time', 'wjcp9j9mjfbe3f8t3mp5544y1w', '1698321177534'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'direct_channel_show', 'w7uyhzuo7fnfueen6og9cxmn9h', 'true'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'channel_open_time', '686m6w41q3bidjcxrsuymudgba', '1698321657708'); +INSERT INTO public.preferences VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'drafts', 'drafts_tour_tip_showed', '{"drafts_tour_tip_showed":true}'); + + +-- +-- Data for Name: productnoticeviewstate; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'gfycat_deprecation_7.8', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'gif_deprecation_7.9_7.10', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'gfycat_deprecation_8.0', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'gfycat_deprecation_8.1', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'boards_deprecations', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'boards_deprecations_user_2', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'desktop_upgrade_v5.5', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'server_upgrade_v9.1', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'crt-admin-disabled', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'crt-admin-default_off', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'crt-user-default-on', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'crt-user-always-on', 1, 1698320750); +INSERT INTO public.productnoticeviewstate VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'unsupported-server-v5.37', 1, 1698320750); + + +-- +-- Data for Name: publicchannels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.publicchannels VALUES ('wjcp9j9mjfbe3f8t3mp5544y1w', 0, 'rkpuunm3rp8fffhzkjxw63usyc', 'Town Square', 'town-square', '', ''); +INSERT INTO public.publicchannels VALUES ('g44m7cnnkjn6tbqsica1ste4jw', 0, 'rkpuunm3rp8fffhzkjxw63usyc', 'Off-Topic', 'off-topic', '', ''); + + +-- +-- Data for Name: reactions; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: recentsearches; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: remoteclusters; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: retentionpolicies; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: retentionpolicieschannels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: retentionpoliciesteams; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: roles; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.roles VALUES ('9pr4dapegp8p5rrwf8xwyuwudw', 'team_admin', 'authentication.roles.team_admin.name', 'authentication.roles.team_admin.description', 1698320577304, 1698320582267, 0, ' convert_public_channel_to_private use_group_mentions delete_others_posts manage_slash_commands manage_private_channel_members manage_others_outgoing_webhooks use_channel_mentions create_post manage_team_roles manage_incoming_webhooks playbook_public_manage_roles add_reaction manage_public_channel_members remove_reaction playbook_private_manage_roles manage_others_slash_commands import_team delete_post remove_user_from_team convert_private_channel_to_public read_private_channel_groups manage_channel_roles manage_outgoing_webhooks read_public_channel_groups manage_others_incoming_webhooks manage_team', true, true); +INSERT INTO public.roles VALUES ('w6wassz9nfd6jfkfou79njg5kr', 'system_post_all_public', 'authentication.roles.system_post_all_public.name', 'authentication.roles.system_post_all_public.description', 1698320577261, 1698320582223, 0, ' create_post_public use_channel_mentions use_group_mentions', false, true); +INSERT INTO public.roles VALUES ('4tg91kitxbr45k11ia1rfp9dsw', 'system_user_access_token', 'authentication.roles.system_user_access_token.name', 'authentication.roles.system_user_access_token.description', 1698320577267, 1698320582229, 0, ' revoke_user_access_token create_user_access_token read_user_access_token', false, true); +INSERT INTO public.roles VALUES ('bqrqkffoqpgt3yru89wr8p3ihh', 'channel_user', 'authentication.roles.channel_user.name', 'authentication.roles.channel_user.description', 1698320577285, 1698320582248, 0, ' edit_post read_public_channel_groups delete_public_channel add_reaction read_private_channel_groups manage_public_channel_properties read_channel_content use_group_mentions delete_post upload_file use_channel_mentions manage_public_channel_members manage_private_channel_members read_channel remove_reaction create_post manage_private_channel_properties get_public_link delete_private_channel', true, true); +INSERT INTO public.roles VALUES ('eg9aoait5pgy5yd5upto6fr5bh', 'custom_group_user', 'authentication.roles.custom_group_user.name', 'authentication.roles.custom_group_user.description', 1698320577310, 1698320582273, 0, '', false, false); +INSERT INTO public.roles VALUES ('zorc97yr9igdp8dgifag5u64tw', 'team_user', 'authentication.roles.team_user.name', 'authentication.roles.team_user.description', 1698320577291, 1698320582254, 0, ' invite_user list_team_channels create_private_channel playbook_private_create playbook_public_create join_public_channels create_public_channel view_team read_public_channel add_user_to_team', true, true); +INSERT INTO public.roles VALUES ('mjokx7qp3jdd7eidqhsx4td6ec', 'playbook_member', 'authentication.roles.playbook_member.name', 'authentication.roles.playbook_member.description', 1698320577316, 1698320582279, 0, ' playbook_public_view playbook_public_manage_members playbook_public_manage_properties playbook_private_view playbook_private_manage_members playbook_private_manage_properties run_create', true, true); +INSERT INTO public.roles VALUES ('p8mkk11gqbfquxr45q4cknakya', 'channel_admin', 'authentication.roles.channel_admin.name', 'authentication.roles.channel_admin.description', 1698320577338, 1698320582291, 0, ' use_channel_mentions add_reaction use_group_mentions manage_channel_roles manage_private_channel_members create_post read_public_channel_groups remove_reaction manage_public_channel_members read_private_channel_groups', true, true); +INSERT INTO public.roles VALUES ('qe1epqnnwinz9m15dhdowkbaqh', 'team_guest', 'authentication.roles.team_guest.name', 'authentication.roles.team_guest.description', 1698320577344, 1698320582298, 0, ' view_team', true, true); +INSERT INTO public.roles VALUES ('dbtf1b6357n7db1h9raanwjzse', 'run_member', 'authentication.roles.run_member.name', 'authentication.roles.run_member.description', 1698320577350, 1698320582304, 0, ' run_view', true, true); +INSERT INTO public.roles VALUES ('oe6ongueziywtgmqo4d9c4igjo', 'team_post_all', 'authentication.roles.team_post_all.name', 'authentication.roles.team_post_all.description', 1698320577297, 1698320582261, 0, ' use_channel_mentions use_group_mentions create_post', false, true); +INSERT INTO public.roles VALUES ('aomdi3k85fr1bdnmmt5hcgzj7a', 'playbook_admin', 'authentication.roles.playbook_admin.name', 'authentication.roles.playbook_admin.description', 1698320577332, 1698320582285, 0, ' playbook_private_manage_members playbook_private_manage_roles playbook_private_manage_properties playbook_public_make_private playbook_public_manage_members playbook_public_manage_roles playbook_public_manage_properties', true, true); +INSERT INTO public.roles VALUES ('9t14j3hzmbndfbkpsoh9arngbr', 'system_guest', 'authentication.roles.global_guest.name', 'authentication.roles.global_guest.description', 1698320577356, 1698320582310, 0, ' create_direct_channel create_group_channel', true, true); +INSERT INTO public.roles VALUES ('9h3q73uhopdfmgu1yi88gc99do', 'system_post_all', 'authentication.roles.system_post_all.name', 'authentication.roles.system_post_all.description', 1698320577369, 1698320582316, 0, ' use_channel_mentions create_post use_group_mentions', false, true); +INSERT INTO public.roles VALUES ('6kfpmc99fjgotg88k6qkr853dr', 'system_admin', 'authentication.roles.global_admin.name', 'authentication.roles.global_admin.description', 1698320577322, 1698320582322, 0, ' manage_team sysconsole_read_environment_rate_limiting use_slash_commands sysconsole_read_site_notices remove_others_reactions test_s3 sysconsole_read_site_file_sharing_and_downloads sysconsole_write_site_posts create_group_channel manage_others_slash_commands sysconsole_read_user_management_permissions sysconsole_read_authentication_saml manage_team_roles promote_guest add_saml_public_cert create_post sysconsole_read_authentication_signup sysconsole_write_authentication_email create_post_bleve_indexes_job create_user_access_token playbook_public_manage_roles sysconsole_write_reporting_server_logs manage_system_wide_oauth sysconsole_read_user_management_users read_audits sysconsole_write_environment_push_notification_server manage_jobs list_public_teams get_saml_cert_status test_elasticsearch sysconsole_read_user_management_teams add_saml_idp_cert reload_config manage_roles sysconsole_write_experimental_features manage_shared_channels create_post_public sysconsole_write_site_announcement_banner sysconsole_read_site_announcement_banner sysconsole_write_compliance_data_retention_policy convert_public_channel_to_private list_private_teams playbook_private_manage_properties sysconsole_read_environment_image_proxy create_direct_channel create_elasticsearch_post_aggregation_job sysconsole_read_environment_session_lengths sysconsole_read_compliance_data_retention_policy test_ldap view_members recycle_database_connections edit_post sysconsole_write_user_management_teams playbook_private_manage_members create_private_channel sysconsole_read_site_emoji playbook_private_manage_roles manage_private_channel_properties read_jobs import_team read_other_users_teams sysconsole_write_integrations_integration_management read_private_channel_groups manage_public_channel_members sysconsole_read_integrations_gif sysconsole_write_user_management_system_roles remove_ldap_private_cert sysconsole_read_integrations_integration_management sysconsole_read_authentication_mfa use_group_mentions assign_system_admin_role sysconsole_write_authentication_saml sysconsole_read_environment_elasticsearch add_ldap_private_cert sysconsole_read_products_boards sysconsole_read_user_management_groups sysconsole_write_site_users_and_teams delete_post delete_custom_group remove_user_from_team read_bots sysconsole_write_environment_database playbook_private_make_public sysconsole_read_authentication_ldap join_public_teams playbook_public_manage_properties read_elasticsearch_post_aggregation_job read_others_bots edit_others_posts sysconsole_write_site_customization sysconsole_read_billing revoke_user_access_token playbook_private_view sysconsole_write_environment_developer sysconsole_write_compliance_compliance_export sysconsole_read_compliance_custom_terms_of_service manage_others_incoming_webhooks sysconsole_read_integrations_bot_accounts get_public_link sysconsole_write_site_public_links edit_other_users create_bot sysconsole_write_environment_image_proxy read_public_channel_groups sysconsole_read_environment_database sysconsole_read_reporting_site_statistics join_public_channels manage_bots create_post_ephemeral sysconsole_write_integrations_gif invalidate_email_invite sysconsole_read_authentication_openid delete_private_channel sysconsole_write_experimental_feature_flags add_ldap_public_cert run_manage_members sysconsole_read_experimental_feature_flags sysconsole_write_billing sysconsole_write_environment_high_availability sysconsole_write_environment_rate_limiting sysconsole_read_site_users_and_teams sysconsole_write_reporting_team_statistics manage_private_channel_members read_elasticsearch_post_indexing_job read_data_retention_job sysconsole_read_environment_developer invalidate_caches get_analytics create_compliance_export_job create_team invite_guest remove_saml_idp_cert manage_incoming_webhooks sysconsole_read_site_customization playbook_public_make_private run_view sysconsole_read_compliance_compliance_monitoring sysconsole_read_environment_push_notification_server manage_channel_roles assign_bot delete_emojis sysconsole_read_about_edition_and_license read_channel delete_public_channel sysconsole_read_site_public_links read_user_access_token playbook_public_view view_team sysconsole_write_environment_performance_monitoring add_saml_private_cert manage_outgoing_webhooks sysconsole_write_authentication_mfa sysconsole_read_environment_performance_monitoring run_create manage_slash_commands sysconsole_write_authentication_ldap create_emojis delete_others_posts manage_others_outgoing_webhooks upload_file sysconsole_write_site_emoji sysconsole_write_authentication_password playbook_private_create run_manage_properties sysconsole_read_experimental_features get_saml_metadata_from_idp sysconsole_write_environment_file_storage sysconsole_read_reporting_server_logs sysconsole_write_site_notifications sysconsole_read_experimental_bleve sysconsole_write_user_management_groups read_channel_content join_private_teams sysconsole_read_user_management_system_roles sysconsole_write_integrations_cors playbook_public_create sysconsole_read_site_notifications add_reaction sysconsole_write_integrations_bot_accounts sysconsole_write_about_edition_and_license sysconsole_read_site_localization remove_saml_private_cert read_deleted_posts sysconsole_read_user_management_channels manage_license_information playbook_public_manage_members sysconsole_write_site_file_sharing_and_downloads read_ldap_sync_job sysconsole_write_authentication_openid manage_custom_group_members sysconsole_read_environment_web_server add_user_to_team delete_others_emojis remove_reaction restore_custom_group edit_brand sysconsole_write_environment_logging manage_public_channel_properties sysconsole_read_compliance_compliance_export sysconsole_read_plugins invite_user sysconsole_read_environment_high_availability remove_ldap_public_cert sysconsole_write_authentication_signup sysconsole_read_environment_logging list_team_channels manage_others_bots sysconsole_write_user_management_channels create_ldap_sync_job read_compliance_export_job sysconsole_read_reporting_team_statistics list_users_without_team sysconsole_write_compliance_custom_terms_of_service read_public_channel sysconsole_read_environment_smtp sysconsole_write_environment_web_server manage_system sysconsole_read_authentication_guest_access sysconsole_read_site_posts sysconsole_write_user_management_users sysconsole_write_plugins test_email create_elasticsearch_post_indexing_job create_data_retention_job manage_oauth remove_saml_public_cert sysconsole_write_reporting_site_statistics sysconsole_write_environment_smtp demote_to_guest sysconsole_write_environment_session_lengths create_public_channel sysconsole_write_products_boards download_compliance_export_result sysconsole_write_site_notices manage_secure_connections read_license_information sysconsole_write_user_management_permissions sysconsole_read_integrations_cors use_channel_mentions purge_bleve_indexes sysconsole_write_environment_elasticsearch sysconsole_write_authentication_guest_access test_site_url sysconsole_read_authentication_password sysconsole_write_compliance_compliance_monitoring sysconsole_read_environment_file_storage edit_custom_group create_custom_group sysconsole_write_site_localization get_logs purge_elasticsearch_indexes convert_private_channel_to_public sysconsole_read_authentication_email sysconsole_write_experimental_bleve', true, true); +INSERT INTO public.roles VALUES ('rmjt5xak738gmcx5afckhkr47r', 'team_post_all_public', 'authentication.roles.team_post_all_public.name', 'authentication.roles.team_post_all_public.description', 1698320577243, 1698320582211, 0, ' use_channel_mentions create_post_public use_group_mentions', false, true); +INSERT INTO public.roles VALUES ('b9ef3k1qefgkmxhkpi4rsp9q8h', 'run_admin', 'authentication.roles.run_admin.name', 'authentication.roles.run_admin.description', 1698320577249, 1698320582217, 0, ' run_manage_members run_manage_properties', true, true); +INSERT INTO public.roles VALUES ('afhpw8yxipymzn7694us6pj43o', 'system_read_only_admin', 'authentication.roles.system_read_only_admin.name', 'authentication.roles.system_read_only_admin.description', 1698320577273, 1698320582236, 0, ' sysconsole_read_environment_logging list_private_teams sysconsole_read_about_edition_and_license sysconsole_read_authentication_password read_private_channel_groups sysconsole_read_environment_web_server sysconsole_read_environment_session_lengths sysconsole_read_environment_push_notification_server read_elasticsearch_post_aggregation_job sysconsole_read_environment_performance_monitoring sysconsole_read_compliance_data_retention_policy sysconsole_read_integrations_gif read_data_retention_job sysconsole_read_reporting_site_statistics sysconsole_read_environment_high_availability sysconsole_read_site_emoji sysconsole_read_experimental_feature_flags sysconsole_read_site_localization view_team download_compliance_export_result sysconsole_read_reporting_team_statistics test_ldap read_elasticsearch_post_indexing_job sysconsole_read_user_management_users sysconsole_read_authentication_ldap read_public_channel sysconsole_read_plugins read_compliance_export_job sysconsole_read_environment_smtp read_license_information sysconsole_read_site_file_sharing_and_downloads sysconsole_read_integrations_integration_management list_public_teams sysconsole_read_reporting_server_logs sysconsole_read_site_public_links sysconsole_read_user_management_channels sysconsole_read_site_announcement_banner sysconsole_read_authentication_mfa read_other_users_teams sysconsole_read_user_management_permissions sysconsole_read_authentication_guest_access sysconsole_read_integrations_cors sysconsole_read_site_users_and_teams sysconsole_read_user_management_groups sysconsole_read_site_posts sysconsole_read_user_management_teams sysconsole_read_compliance_compliance_export sysconsole_read_site_notices sysconsole_read_authentication_signup sysconsole_read_authentication_email read_ldap_sync_job sysconsole_read_environment_file_storage get_analytics sysconsole_read_environment_elasticsearch sysconsole_read_experimental_bleve sysconsole_read_environment_database sysconsole_read_products_boards sysconsole_read_environment_image_proxy sysconsole_read_site_notifications sysconsole_read_site_customization read_public_channel_groups sysconsole_read_compliance_custom_terms_of_service read_channel sysconsole_read_experimental_features sysconsole_read_environment_developer sysconsole_read_authentication_saml sysconsole_read_integrations_bot_accounts read_audits sysconsole_read_authentication_openid get_logs sysconsole_read_compliance_compliance_monitoring sysconsole_read_environment_rate_limiting', false, true); +INSERT INTO public.roles VALUES ('rdgehgkxwidixmkboktwgd5m5e', 'channel_guest', 'authentication.roles.channel_guest.name', 'authentication.roles.channel_guest.description', 1698320577381, 1698320582335, 0, ' add_reaction remove_reaction upload_file edit_post create_post use_channel_mentions read_channel read_channel_content', true, true); +INSERT INTO public.roles VALUES ('k6f5zc76mjbuucmb1t3bedkano', 'system_custom_group_admin', 'authentication.roles.system_custom_group_admin.name', 'authentication.roles.system_custom_group_admin.description', 1698320577387, 1698320582341, 0, ' delete_custom_group restore_custom_group manage_custom_group_members create_custom_group edit_custom_group', false, true); +INSERT INTO public.roles VALUES ('hfzk9bc7gf8wp8af8b3gtncb6c', 'system_user', 'authentication.roles.global_user.name', 'authentication.roles.global_user.description', 1698320577363, 1698320582347, 0, ' delete_emojis create_team restore_custom_group create_custom_group create_emojis delete_custom_group create_direct_channel view_members list_public_teams edit_custom_group join_public_teams manage_custom_group_members create_group_channel', true, true); +INSERT INTO public.roles VALUES ('fe3n8qmbrb8hupsnsayok1x5by', 'system_manager', 'authentication.roles.system_manager.name', 'authentication.roles.system_manager.description', 1698320577279, 1698320582242, 0, ' sysconsole_write_site_emoji sysconsole_write_environment_session_lengths read_license_information sysconsole_write_site_file_sharing_and_downloads sysconsole_read_plugins sysconsole_write_user_management_permissions read_public_channel_groups sysconsole_write_integrations_cors sysconsole_read_environment_file_storage test_elasticsearch create_elasticsearch_post_indexing_job test_site_url read_public_channel read_elasticsearch_post_aggregation_job sysconsole_read_authentication_mfa sysconsole_read_environment_smtp sysconsole_read_site_announcement_banner sysconsole_write_user_management_teams read_ldap_sync_job sysconsole_read_user_management_teams sysconsole_read_environment_high_availability sysconsole_write_environment_high_availability sysconsole_write_products_boards sysconsole_read_authentication_openid sysconsole_write_environment_web_server reload_config sysconsole_write_site_public_links sysconsole_read_site_customization remove_user_from_team add_user_to_team sysconsole_write_integrations_gif sysconsole_read_environment_developer sysconsole_write_site_localization get_logs sysconsole_read_integrations_integration_management sysconsole_read_environment_web_server sysconsole_read_authentication_ldap sysconsole_read_user_management_permissions sysconsole_read_environment_push_notification_server recycle_database_connections test_s3 purge_elasticsearch_indexes manage_team_roles edit_brand delete_public_channel join_public_teams sysconsole_read_authentication_password manage_private_channel_members sysconsole_read_environment_database list_public_teams manage_public_channel_properties sysconsole_write_site_notices sysconsole_read_site_notices sysconsole_read_site_posts sysconsole_write_environment_push_notification_server sysconsole_read_environment_session_lengths sysconsole_read_site_localization sysconsole_write_site_announcement_banner sysconsole_read_products_boards sysconsole_write_site_customization sysconsole_write_site_users_and_teams sysconsole_write_user_management_channels read_elasticsearch_post_indexing_job sysconsole_read_environment_elasticsearch invalidate_caches sysconsole_read_integrations_gif sysconsole_write_user_management_groups get_analytics sysconsole_write_site_posts read_channel sysconsole_read_site_notifications sysconsole_read_site_file_sharing_and_downloads sysconsole_read_reporting_site_statistics sysconsole_write_environment_file_storage manage_private_channel_properties sysconsole_read_environment_image_proxy sysconsole_write_environment_logging join_private_teams sysconsole_read_site_users_and_teams sysconsole_read_authentication_signup sysconsole_write_environment_image_proxy sysconsole_write_environment_database delete_private_channel sysconsole_write_environment_performance_monitoring read_private_channel_groups sysconsole_read_authentication_saml sysconsole_read_user_management_groups sysconsole_read_site_public_links sysconsole_read_reporting_team_statistics sysconsole_read_integrations_bot_accounts sysconsole_write_environment_elasticsearch sysconsole_read_authentication_guest_access list_private_teams sysconsole_write_environment_rate_limiting sysconsole_read_user_management_channels sysconsole_read_environment_rate_limiting create_elasticsearch_post_aggregation_job view_team sysconsole_read_integrations_cors sysconsole_write_environment_developer convert_public_channel_to_private manage_team manage_channel_roles sysconsole_read_reporting_server_logs sysconsole_write_site_notifications test_ldap sysconsole_read_about_edition_and_license sysconsole_read_authentication_email sysconsole_write_integrations_bot_accounts convert_private_channel_to_public sysconsole_read_site_emoji manage_public_channel_members sysconsole_write_integrations_integration_management sysconsole_read_environment_performance_monitoring sysconsole_write_environment_smtp sysconsole_read_environment_logging test_email', false, true); +INSERT INTO public.roles VALUES ('fr37w1fkii87bnt9f8j1y1wdzw', 'system_user_manager', 'authentication.roles.system_user_manager.name', 'authentication.roles.system_user_manager.description', 1698320577375, 1698320582328, 0, ' manage_public_channel_properties test_ldap manage_team_roles read_public_channel manage_private_channel_properties sysconsole_read_authentication_guest_access sysconsole_read_authentication_email list_private_teams join_private_teams add_user_to_team sysconsole_write_user_management_teams read_ldap_sync_job sysconsole_read_authentication_signup sysconsole_read_authentication_ldap sysconsole_read_user_management_permissions join_public_teams convert_private_channel_to_public sysconsole_write_user_management_channels sysconsole_write_user_management_groups read_private_channel_groups sysconsole_read_user_management_teams sysconsole_read_authentication_saml list_public_teams read_channel sysconsole_read_authentication_openid sysconsole_read_user_management_channels manage_team delete_private_channel view_team manage_private_channel_members sysconsole_read_user_management_groups remove_user_from_team manage_public_channel_members read_public_channel_groups convert_public_channel_to_private sysconsole_read_authentication_password delete_public_channel manage_channel_roles sysconsole_read_authentication_mfa', false, true); + + +-- +-- Data for Name: schemes; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: sessions; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.sessions VALUES ('ugcm3rkgaig7tntdiwka6bp79r', 'ji7mf5m9dfnyjmu4gcnwt31xne', 1698320583554, 0, 1698320583554, 'qicfanjtzbgsf8qh8zkosdq96e', '', '', false, '{}', false); +INSERT INTO public.sessions VALUES ('tccpu59ortge9bdfunua675bcy', 'nsutx44ibbd69r5hjjmd3hx4sw', 1698321933089, 4851921933089, 1698321933089, 'w7uyhzuo7fnfueen6og9cxmn9h', '', 'system_user system_admin', false, '{"type": "UserAccessToken", "is_bot": "true", "is_guest": "false", "user_access_token_id": "7xnejgyhj7nxtmq6t95iah7n7c"}', false); +INSERT INTO public.sessions VALUES ('xprkr99nfirmb8j4pdfzqhhtar', 'gocaadsyk3bo5qwqf9tks47wko', 1698320751063, 1700912751063, 1698322855604, '5md7bsji6pbijpxitu8bwezaqy', '', 'system_admin system_user', false, '{"os": "Linux", "csrf": "wzkjmmqeaifz3qaa6dz57m614w", "isSaml": "false", "browser": "Chrome/118.0", "isMobile": "false", "is_guest": "false", "platform": "Linux", "isOAuthUser": "false"}', false); +INSERT INTO public.sessions VALUES ('bbs5ngiidbrticjza5sfs679ac', 'gsxpu5po9fnxmncgcbgkgcfo7a', 1698324524225, 0, 1698324524225, 'qicfanjtzbgsf8qh8zkosdq96e', '', '', false, '{}', false); + + +-- +-- Data for Name: sharedchannelattachments; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: sharedchannelremotes; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: sharedchannels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: sharedchannelusers; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: sidebarcategories; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.sidebarcategories VALUES ('favorites_5md7bsji6pbijpxitu8bwezaqy_rkpuunm3rp8fffhzkjxw63usyc', '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 0, '', 'favorites', 'Favorites', false, false); +INSERT INTO public.sidebarcategories VALUES ('channels_5md7bsji6pbijpxitu8bwezaqy_rkpuunm3rp8fffhzkjxw63usyc', '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 10, '', 'channels', 'Channels', false, false); +INSERT INTO public.sidebarcategories VALUES ('direct_messages_5md7bsji6pbijpxitu8bwezaqy_rkpuunm3rp8fffhzkjxw63usyc', '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 20, 'recent', 'direct_messages', 'Direct Messages', false, false); +INSERT INTO public.sidebarcategories VALUES ('favorites_w7uyhzuo7fnfueen6og9cxmn9h_rkpuunm3rp8fffhzkjxw63usyc', 'w7uyhzuo7fnfueen6og9cxmn9h', 'rkpuunm3rp8fffhzkjxw63usyc', 0, '', 'favorites', 'Favorites', false, false); +INSERT INTO public.sidebarcategories VALUES ('channels_w7uyhzuo7fnfueen6og9cxmn9h_rkpuunm3rp8fffhzkjxw63usyc', 'w7uyhzuo7fnfueen6og9cxmn9h', 'rkpuunm3rp8fffhzkjxw63usyc', 10, '', 'channels', 'Channels', false, false); +INSERT INTO public.sidebarcategories VALUES ('direct_messages_w7uyhzuo7fnfueen6og9cxmn9h_rkpuunm3rp8fffhzkjxw63usyc', 'w7uyhzuo7fnfueen6og9cxmn9h', 'rkpuunm3rp8fffhzkjxw63usyc', 20, 'recent', 'direct_messages', 'Direct Messages', false, false); + + +-- +-- Data for Name: sidebarchannels; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: status; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.status VALUES ('w7uyhzuo7fnfueen6og9cxmn9h', 'offline', false, 1698322063254, 0, ''); +INSERT INTO public.status VALUES ('5md7bsji6pbijpxitu8bwezaqy', 'offline', false, 1698323059687, 0, ''); + + +-- +-- Data for Name: systems; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.systems VALUES ('CRTChannelMembershipCountsMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('CRTThreadCountsAndUnreadsMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('AsymmetricSigningKey', '{"ecdsa_key":{"curve":"P-256","x":93265069825403552412139318495871668021796740157055378512852007170438861396546,"y":59624988667333768029494324774170511219568387297490421502531189241744540499512,"d":109950753027899581247934453758674695621655017250419947179614439678360020797909}}'); +INSERT INTO public.systems VALUES ('DiagnosticId', 'x5xrikiotffufxawscso75zwue'); +INSERT INTO public.systems VALUES ('LastSecurityTime', '1698320577245'); +INSERT INTO public.systems VALUES ('FirstServerRunTimestamp', '1698320577245'); +INSERT INTO public.systems VALUES ('AdvancedPermissionsMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('EmojisPermissionsMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('GuestRolesCreationMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('SystemConsoleRolesCreationMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('CustomGroupAdminRoleCreationMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('emoji_permissions_split', 'true'); +INSERT INTO public.systems VALUES ('webhook_permissions_split', 'true'); +INSERT INTO public.systems VALUES ('list_join_public_private_teams', 'true'); +INSERT INTO public.systems VALUES ('remove_permanent_delete_user', 'true'); +INSERT INTO public.systems VALUES ('add_bot_permissions', 'true'); +INSERT INTO public.systems VALUES ('apply_channel_manage_delete_to_channel_user', 'true'); +INSERT INTO public.systems VALUES ('remove_channel_manage_delete_from_team_user', 'true'); +INSERT INTO public.systems VALUES ('view_members_new_permission', 'true'); +INSERT INTO public.systems VALUES ('add_manage_guests_permissions', 'true'); +INSERT INTO public.systems VALUES ('channel_moderations_permissions', 'true'); +INSERT INTO public.systems VALUES ('add_use_group_mentions_permission', 'true'); +INSERT INTO public.systems VALUES ('add_system_console_permissions', 'true'); +INSERT INTO public.systems VALUES ('add_convert_channel_permissions', 'true'); +INSERT INTO public.systems VALUES ('manage_shared_channel_permissions', 'true'); +INSERT INTO public.systems VALUES ('manage_secure_connections_permissions', 'true'); +INSERT INTO public.systems VALUES ('add_system_roles_permissions', 'true'); +INSERT INTO public.systems VALUES ('add_billing_permissions', 'true'); +INSERT INTO public.systems VALUES ('download_compliance_export_results', 'true'); +INSERT INTO public.systems VALUES ('experimental_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('authentication_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('integrations_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('site_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('compliance_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('environment_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('about_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('reporting_subsection_permissions', 'true'); +INSERT INTO public.systems VALUES ('test_email_ancillary_permission', 'true'); +INSERT INTO public.systems VALUES ('playbooks_permissions', 'true'); +INSERT INTO public.systems VALUES ('custom_groups_permissions', 'true'); +INSERT INTO public.systems VALUES ('playbooks_manage_roles', 'true'); +INSERT INTO public.systems VALUES ('products_boards', 'true'); +INSERT INTO public.systems VALUES ('custom_groups_permission_restore', 'true'); +INSERT INTO public.systems VALUES ('read_channel_content_permissions', 'true'); +INSERT INTO public.systems VALUES ('ContentExtractionConfigDefaultTrueMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('PlaybookRolesCreationMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('RemainingSchemaMigrations', 'true'); +INSERT INTO public.systems VALUES ('PostPriorityConfigDefaultTrueMigrationComplete', 'true'); +INSERT INTO public.systems VALUES ('PostActionCookieSecret', '{"key":"ixkFbhBo6vjg/slqcncUU4xI8QjzAUk62i5NrW5mShQ="}'); +INSERT INTO public.systems VALUES ('InstallationDate', '1698320582714'); +INSERT INTO public.systems VALUES ('migration_advanced_permissions_phase_2', 'true'); +INSERT INTO public.systems VALUES ('OrganizationName', 'Network To Code LLC'); +INSERT INTO public.systems VALUES ('FirstAdminSetupComplete', 'true'); + + +-- +-- Data for Name: teammembers; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.teammembers VALUES ('rkpuunm3rp8fffhzkjxw63usyc', '5md7bsji6pbijpxitu8bwezaqy', '', 0, true, true, false, 1698320784737); +INSERT INTO public.teammembers VALUES ('rkpuunm3rp8fffhzkjxw63usyc', 'w7uyhzuo7fnfueen6og9cxmn9h', '', 0, true, false, false, 1698321691864); + + +-- +-- Data for Name: teams; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.teams VALUES ('rkpuunm3rp8fffhzkjxw63usyc', 1698320784707, 1698320784707, 0, 'Network To Code LLC', 'network-to-code-llc', '', 'admin@example.com', 'O', '', '', '68tc1nu46i8yif7w13qmndumih', '', false, 0, false, false); + + +-- +-- Data for Name: termsofservice; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: threadmemberships; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: threads; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: tokens; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: trueupreviewhistory; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: uploadsessions; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: useraccesstokens; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.useraccesstokens VALUES ('7xnejgyhj7nxtmq6t95iah7n7c', 'nsutx44ibbd69r5hjjmd3hx4sw', 'w7uyhzuo7fnfueen6og9cxmn9h', 'Default Token', true); + + +-- +-- Data for Name: usergroups; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + +INSERT INTO public.users VALUES ('jmcgoiar5brr9nx8s7g3394c8e', 1698320582714, 1698320582739, 0, 'feedbackbot', '', NULL, '', 'feedbackbot@localhost', false, '', 'Feedbackbot', '', 'system_user', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698320582714, 1698320582739, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); +INSERT INTO public.users VALUES ('qicfanjtzbgsf8qh8zkosdq96e', 1698320583519, 1698320583519, 0, 'calls', '', NULL, '', 'calls@localhost', false, '', 'Calls', '', 'system_user', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698320583519, 0, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); +INSERT INTO public.users VALUES ('5md7bsji6pbijpxitu8bwezaqy', 1698320750878, 1698320784745, 0, 'admin', '$2a$10$fXSIHTK.8qvMjMZV0dNbH.0ialIcCVDywEog0BpF.NgXIrO4muYIS', NULL, '', 'admin@example.com', false, '', '', '', 'system_admin system_user', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698320750878, 0, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); +INSERT INTO public.users VALUES ('dnyqmp4u5tgetr9or6in55xobr', 1698321000002, 1698321000002, 0, 'system-bot', '', NULL, '', 'system-bot@localhost', false, '', 'System', '', 'system_user', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698321000002, 0, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); +INSERT INTO public.users VALUES ('w7uyhzuo7fnfueen6og9cxmn9h', 1698321288273, 1698321691881, 0, 'nautobot', '', NULL, '', 'nautobot@localhost', false, '', 'Nautobot', '', 'system_user system_admin', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698321288273, -1698321288413, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); +INSERT INTO public.users VALUES ('mt3fq81mrbbydrefss1h9zfxhw', 1698320583260, 1698324524015, 0, 'playbooks', '', NULL, '', 'playbooks@localhost', false, '', 'Playbooks', '', 'system_user', false, '{}', '{"push": "mention", "email": "true", "channel": "true", "desktop": "mention", "comments": "never", "first_name": "false", "push_status": "away", "mention_keys": "", "push_threads": "all", "desktop_sound": "true", "email_threads": "all", "desktop_threads": "all"}', 1698320583260, 1698324524015, 0, 'en', false, '', '', '{"manualTimezone": "", "automaticTimezone": "", "useAutomaticTimezone": "true"}', NULL); + + +-- +-- Data for Name: usertermsofservice; Type: TABLE DATA; Schema: public; Owner: mmuser +-- + + + +-- +-- Name: audits audits_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.audits + ADD CONSTRAINT audits_pkey PRIMARY KEY (id); + + +-- +-- Name: bots bots_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.bots + ADD CONSTRAINT bots_pkey PRIMARY KEY (userid); + + +-- +-- Name: channelmemberhistory channelmemberhistory_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.channelmemberhistory + ADD CONSTRAINT channelmemberhistory_pkey PRIMARY KEY (channelid, userid, jointime); + + +-- +-- Name: channelmembers channelmembers_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.channelmembers + ADD CONSTRAINT channelmembers_pkey PRIMARY KEY (channelid, userid); + + +-- +-- Name: channels channels_name_teamid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.channels + ADD CONSTRAINT channels_name_teamid_key UNIQUE (name, teamid); + + +-- +-- Name: channels channels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.channels + ADD CONSTRAINT channels_pkey PRIMARY KEY (id); + + +-- +-- Name: clusterdiscovery clusterdiscovery_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.clusterdiscovery + ADD CONSTRAINT clusterdiscovery_pkey PRIMARY KEY (id); + + +-- +-- Name: commands commands_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.commands + ADD CONSTRAINT commands_pkey PRIMARY KEY (id); + + +-- +-- Name: commandwebhooks commandwebhooks_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.commandwebhooks + ADD CONSTRAINT commandwebhooks_pkey PRIMARY KEY (id); + + +-- +-- Name: compliances compliances_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.compliances + ADD CONSTRAINT compliances_pkey PRIMARY KEY (id); + + +-- +-- Name: db_lock db_lock_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.db_lock + ADD CONSTRAINT db_lock_pkey PRIMARY KEY (id); + + +-- +-- Name: db_migrations db_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.db_migrations + ADD CONSTRAINT db_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: drafts drafts_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.drafts + ADD CONSTRAINT drafts_pkey PRIMARY KEY (userid, channelid, rootid); + + +-- +-- Name: emoji emoji_name_deleteat_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.emoji + ADD CONSTRAINT emoji_name_deleteat_key UNIQUE (name, deleteat); + + +-- +-- Name: emoji emoji_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.emoji + ADD CONSTRAINT emoji_pkey PRIMARY KEY (id); + + +-- +-- Name: fileinfo fileinfo_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.fileinfo + ADD CONSTRAINT fileinfo_pkey PRIMARY KEY (id); + + +-- +-- Name: groupchannels groupchannels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.groupchannels + ADD CONSTRAINT groupchannels_pkey PRIMARY KEY (groupid, channelid); + + +-- +-- Name: groupmembers groupmembers_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.groupmembers + ADD CONSTRAINT groupmembers_pkey PRIMARY KEY (groupid, userid); + + +-- +-- Name: groupteams groupteams_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.groupteams + ADD CONSTRAINT groupteams_pkey PRIMARY KEY (groupid, teamid); + + +-- +-- Name: incomingwebhooks incomingwebhooks_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.incomingwebhooks + ADD CONSTRAINT incomingwebhooks_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_category_item ir_category_item_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_category_item + ADD CONSTRAINT ir_category_item_pkey PRIMARY KEY (categoryid, itemid, type); + + +-- +-- Name: ir_category ir_category_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_category + ADD CONSTRAINT ir_category_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_channelaction ir_channelaction_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_channelaction + ADD CONSTRAINT ir_channelaction_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_incident ir_incident_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_incident + ADD CONSTRAINT ir_incident_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_metric ir_metric_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_metric + ADD CONSTRAINT ir_metric_pkey PRIMARY KEY (incidentid, metricconfigid); + + +-- +-- Name: ir_metricconfig ir_metricconfig_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_metricconfig + ADD CONSTRAINT ir_metricconfig_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_playbook ir_playbook_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbook + ADD CONSTRAINT ir_playbook_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_playbookautofollow ir_playbookautofollow_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbookautofollow + ADD CONSTRAINT ir_playbookautofollow_pkey PRIMARY KEY (playbookid, userid); + + +-- +-- Name: ir_playbookmember ir_playbookmember_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbookmember + ADD CONSTRAINT ir_playbookmember_pkey PRIMARY KEY (memberid, playbookid); + + +-- +-- Name: ir_playbookmember ir_playbookmember_playbookid_memberid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbookmember + ADD CONSTRAINT ir_playbookmember_playbookid_memberid_key UNIQUE (playbookid, memberid); + + +-- +-- Name: ir_run_participants ir_run_participants_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_run_participants + ADD CONSTRAINT ir_run_participants_pkey PRIMARY KEY (incidentid, userid); + + +-- +-- Name: ir_statusposts ir_statusposts_incidentid_postid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_statusposts + ADD CONSTRAINT ir_statusposts_incidentid_postid_key UNIQUE (incidentid, postid); + + +-- +-- Name: ir_statusposts ir_statusposts_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_statusposts + ADD CONSTRAINT ir_statusposts_pkey PRIMARY KEY (incidentid, postid); + + +-- +-- Name: ir_system ir_system_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_system + ADD CONSTRAINT ir_system_pkey PRIMARY KEY (skey); + + +-- +-- Name: ir_timelineevent ir_timelineevent_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_timelineevent + ADD CONSTRAINT ir_timelineevent_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_userinfo ir_userinfo_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_userinfo + ADD CONSTRAINT ir_userinfo_pkey PRIMARY KEY (id); + + +-- +-- Name: ir_viewedchannel ir_viewedchannel_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_viewedchannel + ADD CONSTRAINT ir_viewedchannel_pkey PRIMARY KEY (channelid, userid); + + +-- +-- Name: jobs jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.jobs + ADD CONSTRAINT jobs_pkey PRIMARY KEY (id); + + +-- +-- Name: licenses licenses_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.licenses + ADD CONSTRAINT licenses_pkey PRIMARY KEY (id); + + +-- +-- Name: linkmetadata linkmetadata_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.linkmetadata + ADD CONSTRAINT linkmetadata_pkey PRIMARY KEY (hash); + + +-- +-- Name: notifyadmin notifyadmin_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.notifyadmin + ADD CONSTRAINT notifyadmin_pkey PRIMARY KEY (userid, requiredfeature, requiredplan); + + +-- +-- Name: oauthaccessdata oauthaccessdata_clientid_userid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.oauthaccessdata + ADD CONSTRAINT oauthaccessdata_clientid_userid_key UNIQUE (clientid, userid); + + +-- +-- Name: oauthaccessdata oauthaccessdata_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.oauthaccessdata + ADD CONSTRAINT oauthaccessdata_pkey PRIMARY KEY (token); + + +-- +-- Name: oauthapps oauthapps_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.oauthapps + ADD CONSTRAINT oauthapps_pkey PRIMARY KEY (id); + + +-- +-- Name: oauthauthdata oauthauthdata_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.oauthauthdata + ADD CONSTRAINT oauthauthdata_pkey PRIMARY KEY (code); + + +-- +-- Name: outgoingwebhooks outgoingwebhooks_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.outgoingwebhooks + ADD CONSTRAINT outgoingwebhooks_pkey PRIMARY KEY (id); + + +-- +-- Name: persistentnotifications persistentnotifications_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.persistentnotifications + ADD CONSTRAINT persistentnotifications_pkey PRIMARY KEY (postid); + + +-- +-- Name: pluginkeyvaluestore pluginkeyvaluestore_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.pluginkeyvaluestore + ADD CONSTRAINT pluginkeyvaluestore_pkey PRIMARY KEY (pluginid, pkey); + + +-- +-- Name: postacknowledgements postacknowledgements_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.postacknowledgements + ADD CONSTRAINT postacknowledgements_pkey PRIMARY KEY (postid, userid); + + +-- +-- Name: postreminders postreminders_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.postreminders + ADD CONSTRAINT postreminders_pkey PRIMARY KEY (postid, userid); + + +-- +-- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.posts + ADD CONSTRAINT posts_pkey PRIMARY KEY (id); + + +-- +-- Name: postspriority postspriority_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.postspriority + ADD CONSTRAINT postspriority_pkey PRIMARY KEY (postid); + + +-- +-- Name: preferences preferences_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.preferences + ADD CONSTRAINT preferences_pkey PRIMARY KEY (userid, category, name); + + +-- +-- Name: productnoticeviewstate productnoticeviewstate_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.productnoticeviewstate + ADD CONSTRAINT productnoticeviewstate_pkey PRIMARY KEY (userid, noticeid); + + +-- +-- Name: publicchannels publicchannels_name_teamid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.publicchannels + ADD CONSTRAINT publicchannels_name_teamid_key UNIQUE (name, teamid); + + +-- +-- Name: publicchannels publicchannels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.publicchannels + ADD CONSTRAINT publicchannels_pkey PRIMARY KEY (id); + + +-- +-- Name: reactions reactions_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.reactions + ADD CONSTRAINT reactions_pkey PRIMARY KEY (postid, userid, emojiname); + + +-- +-- Name: recentsearches recentsearches_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.recentsearches + ADD CONSTRAINT recentsearches_pkey PRIMARY KEY (userid, searchpointer); + + +-- +-- Name: remoteclusters remoteclusters_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.remoteclusters + ADD CONSTRAINT remoteclusters_pkey PRIMARY KEY (remoteid, name); + + +-- +-- Name: retentionpolicies retentionpolicies_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.retentionpolicies + ADD CONSTRAINT retentionpolicies_pkey PRIMARY KEY (id); + + +-- +-- Name: retentionpolicieschannels retentionpolicieschannels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.retentionpolicieschannels + ADD CONSTRAINT retentionpolicieschannels_pkey PRIMARY KEY (channelid); + + +-- +-- Name: retentionpoliciesteams retentionpoliciesteams_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.retentionpoliciesteams + ADD CONSTRAINT retentionpoliciesteams_pkey PRIMARY KEY (teamid); + + +-- +-- Name: roles roles_name_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_name_key UNIQUE (name); + + +-- +-- Name: roles roles_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_pkey PRIMARY KEY (id); + + +-- +-- Name: schemes schemes_name_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.schemes + ADD CONSTRAINT schemes_name_key UNIQUE (name); + + +-- +-- Name: schemes schemes_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.schemes + ADD CONSTRAINT schemes_pkey PRIMARY KEY (id); + + +-- +-- Name: sessions sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sessions + ADD CONSTRAINT sessions_pkey PRIMARY KEY (id); + + +-- +-- Name: sharedchannelattachments sharedchannelattachments_fileid_remoteid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelattachments + ADD CONSTRAINT sharedchannelattachments_fileid_remoteid_key UNIQUE (fileid, remoteid); + + +-- +-- Name: sharedchannelattachments sharedchannelattachments_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelattachments + ADD CONSTRAINT sharedchannelattachments_pkey PRIMARY KEY (id); + + +-- +-- Name: sharedchannelremotes sharedchannelremotes_channelid_remoteid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelremotes + ADD CONSTRAINT sharedchannelremotes_channelid_remoteid_key UNIQUE (channelid, remoteid); + + +-- +-- Name: sharedchannelremotes sharedchannelremotes_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelremotes + ADD CONSTRAINT sharedchannelremotes_pkey PRIMARY KEY (id, channelid); + + +-- +-- Name: sharedchannels sharedchannels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannels + ADD CONSTRAINT sharedchannels_pkey PRIMARY KEY (channelid); + + +-- +-- Name: sharedchannels sharedchannels_sharename_teamid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannels + ADD CONSTRAINT sharedchannels_sharename_teamid_key UNIQUE (sharename, teamid); + + +-- +-- Name: sharedchannelusers sharedchannelusers_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelusers + ADD CONSTRAINT sharedchannelusers_pkey PRIMARY KEY (id); + + +-- +-- Name: sharedchannelusers sharedchannelusers_userid_channelid_remoteid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sharedchannelusers + ADD CONSTRAINT sharedchannelusers_userid_channelid_remoteid_key UNIQUE (userid, channelid, remoteid); + + +-- +-- Name: sidebarcategories sidebarcategories_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sidebarcategories + ADD CONSTRAINT sidebarcategories_pkey PRIMARY KEY (id); + + +-- +-- Name: sidebarchannels sidebarchannels_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.sidebarchannels + ADD CONSTRAINT sidebarchannels_pkey PRIMARY KEY (channelid, userid, categoryid); + + +-- +-- Name: status status_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.status + ADD CONSTRAINT status_pkey PRIMARY KEY (userid); + + +-- +-- Name: systems systems_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.systems + ADD CONSTRAINT systems_pkey PRIMARY KEY (name); + + +-- +-- Name: teammembers teammembers_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.teammembers + ADD CONSTRAINT teammembers_pkey PRIMARY KEY (teamid, userid); + + +-- +-- Name: teams teams_name_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.teams + ADD CONSTRAINT teams_name_key UNIQUE (name); + + +-- +-- Name: teams teams_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.teams + ADD CONSTRAINT teams_pkey PRIMARY KEY (id); + + +-- +-- Name: termsofservice termsofservice_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.termsofservice + ADD CONSTRAINT termsofservice_pkey PRIMARY KEY (id); + + +-- +-- Name: threadmemberships threadmemberships_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.threadmemberships + ADD CONSTRAINT threadmemberships_pkey PRIMARY KEY (postid, userid); + + +-- +-- Name: threads threads_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.threads + ADD CONSTRAINT threads_pkey PRIMARY KEY (postid); + + +-- +-- Name: tokens tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.tokens + ADD CONSTRAINT tokens_pkey PRIMARY KEY (token); + + +-- +-- Name: trueupreviewhistory trueupreviewhistory_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.trueupreviewhistory + ADD CONSTRAINT trueupreviewhistory_pkey PRIMARY KEY (duedate); + + +-- +-- Name: uploadsessions uploadsessions_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.uploadsessions + ADD CONSTRAINT uploadsessions_pkey PRIMARY KEY (id); + + +-- +-- Name: useraccesstokens useraccesstokens_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.useraccesstokens + ADD CONSTRAINT useraccesstokens_pkey PRIMARY KEY (id); + + +-- +-- Name: useraccesstokens useraccesstokens_token_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.useraccesstokens + ADD CONSTRAINT useraccesstokens_token_key UNIQUE (token); + + +-- +-- Name: usergroups usergroups_name_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.usergroups + ADD CONSTRAINT usergroups_name_key UNIQUE (name); + + +-- +-- Name: usergroups usergroups_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.usergroups + ADD CONSTRAINT usergroups_pkey PRIMARY KEY (id); + + +-- +-- Name: usergroups usergroups_source_remoteid_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.usergroups + ADD CONSTRAINT usergroups_source_remoteid_key UNIQUE (source, remoteid); + + +-- +-- Name: users users_authdata_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_authdata_key UNIQUE (authdata); + + +-- +-- Name: users users_email_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_email_key UNIQUE (email); + + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: users users_username_key; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_username_key UNIQUE (username); + + +-- +-- Name: usertermsofservice usertermsofservice_pkey; Type: CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.usertermsofservice + ADD CONSTRAINT usertermsofservice_pkey PRIMARY KEY (userid); + + +-- +-- Name: idx_audits_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_audits_user_id ON public.audits USING btree (userid); + + +-- +-- Name: idx_channel_search_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channel_search_txt ON public.channels USING gin (to_tsvector('english'::regconfig, (((((name)::text || ' '::text) || (displayname)::text) || ' '::text) || (purpose)::text))); + + +-- +-- Name: idx_channelmembers_channel_id_scheme_guest_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channelmembers_channel_id_scheme_guest_user_id ON public.channelmembers USING btree (channelid, schemeguest, userid); + + +-- +-- Name: idx_channelmembers_user_id_channel_id_last_viewed_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channelmembers_user_id_channel_id_last_viewed_at ON public.channelmembers USING btree (userid, channelid, lastviewedat); + + +-- +-- Name: idx_channels_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_create_at ON public.channels USING btree (createat); + + +-- +-- Name: idx_channels_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_delete_at ON public.channels USING btree (deleteat); + + +-- +-- Name: idx_channels_displayname_lower; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_displayname_lower ON public.channels USING btree (lower((displayname)::text)); + + +-- +-- Name: idx_channels_name_lower; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_name_lower ON public.channels USING btree (lower((name)::text)); + + +-- +-- Name: idx_channels_scheme_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_scheme_id ON public.channels USING btree (schemeid); + + +-- +-- Name: idx_channels_team_id_display_name; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_team_id_display_name ON public.channels USING btree (teamid, displayname); + + +-- +-- Name: idx_channels_team_id_type; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_team_id_type ON public.channels USING btree (teamid, type); + + +-- +-- Name: idx_channels_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_channels_update_at ON public.channels USING btree (updateat); + + +-- +-- Name: idx_command_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_command_create_at ON public.commands USING btree (createat); + + +-- +-- Name: idx_command_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_command_delete_at ON public.commands USING btree (deleteat); + + +-- +-- Name: idx_command_team_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_command_team_id ON public.commands USING btree (teamid); + + +-- +-- Name: idx_command_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_command_update_at ON public.commands USING btree (updateat); + + +-- +-- Name: idx_command_webhook_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_command_webhook_create_at ON public.commandwebhooks USING btree (createat); + + +-- +-- Name: idx_emoji_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_emoji_create_at ON public.emoji USING btree (createat); + + +-- +-- Name: idx_emoji_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_emoji_delete_at ON public.emoji USING btree (deleteat); + + +-- +-- Name: idx_emoji_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_emoji_update_at ON public.emoji USING btree (updateat); + + +-- +-- Name: idx_fileinfo_channel_id_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_channel_id_create_at ON public.fileinfo USING btree (channelid, createat); + + +-- +-- Name: idx_fileinfo_content_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_content_txt ON public.fileinfo USING gin (to_tsvector('english'::regconfig, content)); + + +-- +-- Name: idx_fileinfo_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_create_at ON public.fileinfo USING btree (createat); + + +-- +-- Name: idx_fileinfo_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_delete_at ON public.fileinfo USING btree (deleteat); + + +-- +-- Name: idx_fileinfo_extension_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_extension_at ON public.fileinfo USING btree (extension); + + +-- +-- Name: idx_fileinfo_name_splitted; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_name_splitted ON public.fileinfo USING gin (to_tsvector('english'::regconfig, translate((name)::text, '.,-'::text, ' '::text))); + + +-- +-- Name: idx_fileinfo_name_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_name_txt ON public.fileinfo USING gin (to_tsvector('english'::regconfig, (name)::text)); + + +-- +-- Name: idx_fileinfo_postid_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_postid_at ON public.fileinfo USING btree (postid); + + +-- +-- Name: idx_fileinfo_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_fileinfo_update_at ON public.fileinfo USING btree (updateat); + + +-- +-- Name: idx_groupchannels_channelid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_groupchannels_channelid ON public.groupchannels USING btree (channelid); + + +-- +-- Name: idx_groupchannels_schemeadmin; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_groupchannels_schemeadmin ON public.groupchannels USING btree (schemeadmin); + + +-- +-- Name: idx_groupmembers_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_groupmembers_create_at ON public.groupmembers USING btree (createat); + + +-- +-- Name: idx_groupteams_schemeadmin; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_groupteams_schemeadmin ON public.groupteams USING btree (schemeadmin); + + +-- +-- Name: idx_groupteams_teamid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_groupteams_teamid ON public.groupteams USING btree (teamid); + + +-- +-- Name: idx_incoming_webhook_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_incoming_webhook_create_at ON public.incomingwebhooks USING btree (createat); + + +-- +-- Name: idx_incoming_webhook_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_incoming_webhook_delete_at ON public.incomingwebhooks USING btree (deleteat); + + +-- +-- Name: idx_incoming_webhook_team_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_incoming_webhook_team_id ON public.incomingwebhooks USING btree (teamid); + + +-- +-- Name: idx_incoming_webhook_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_incoming_webhook_update_at ON public.incomingwebhooks USING btree (updateat); + + +-- +-- Name: idx_incoming_webhook_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_incoming_webhook_user_id ON public.incomingwebhooks USING btree (userid); + + +-- +-- Name: idx_jobs_status_type; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_jobs_status_type ON public.jobs USING btree (status, type); + + +-- +-- Name: idx_jobs_type; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_jobs_type ON public.jobs USING btree (type); + + +-- +-- Name: idx_link_metadata_url_timestamp; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_link_metadata_url_timestamp ON public.linkmetadata USING btree (url, "timestamp"); + + +-- +-- Name: idx_notice_views_notice_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_notice_views_notice_id ON public.productnoticeviewstate USING btree (noticeid); + + +-- +-- Name: idx_notice_views_timestamp; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_notice_views_timestamp ON public.productnoticeviewstate USING btree ("timestamp"); + + +-- +-- Name: idx_oauthaccessdata_refresh_token; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_oauthaccessdata_refresh_token ON public.oauthaccessdata USING btree (refreshtoken); + + +-- +-- Name: idx_oauthaccessdata_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_oauthaccessdata_user_id ON public.oauthaccessdata USING btree (userid); + + +-- +-- Name: idx_oauthapps_creator_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_oauthapps_creator_id ON public.oauthapps USING btree (creatorid); + + +-- +-- Name: idx_outgoing_webhook_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_outgoing_webhook_create_at ON public.outgoingwebhooks USING btree (createat); + + +-- +-- Name: idx_outgoing_webhook_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_outgoing_webhook_delete_at ON public.outgoingwebhooks USING btree (deleteat); + + +-- +-- Name: idx_outgoing_webhook_team_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_outgoing_webhook_team_id ON public.outgoingwebhooks USING btree (teamid); + + +-- +-- Name: idx_outgoing_webhook_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_outgoing_webhook_update_at ON public.outgoingwebhooks USING btree (updateat); + + +-- +-- Name: idx_postreminders_targettime; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_postreminders_targettime ON public.postreminders USING btree (targettime); + + +-- +-- Name: idx_posts_channel_id_delete_at_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_channel_id_delete_at_create_at ON public.posts USING btree (channelid, deleteat, createat); + + +-- +-- Name: idx_posts_channel_id_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_channel_id_update_at ON public.posts USING btree (channelid, updateat); + + +-- +-- Name: idx_posts_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_create_at ON public.posts USING btree (createat); + + +-- +-- Name: idx_posts_create_at_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_create_at_id ON public.posts USING btree (createat, id); + + +-- +-- Name: idx_posts_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_delete_at ON public.posts USING btree (deleteat); + + +-- +-- Name: idx_posts_hashtags_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_hashtags_txt ON public.posts USING gin (to_tsvector('english'::regconfig, (hashtags)::text)); + + +-- +-- Name: idx_posts_is_pinned; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_is_pinned ON public.posts USING btree (ispinned); + + +-- +-- Name: idx_posts_message_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_message_txt ON public.posts USING gin (to_tsvector('english'::regconfig, (message)::text)); + + +-- +-- Name: idx_posts_original_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_original_id ON public.posts USING btree (originalid); + + +-- +-- Name: idx_posts_root_id_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_root_id_delete_at ON public.posts USING btree (rootid, deleteat); + + +-- +-- Name: idx_posts_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_update_at ON public.posts USING btree (updateat); + + +-- +-- Name: idx_posts_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_posts_user_id ON public.posts USING btree (userid); + + +-- +-- Name: idx_preferences_category; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_preferences_category ON public.preferences USING btree (category); + + +-- +-- Name: idx_preferences_name; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_preferences_name ON public.preferences USING btree (name); + + +-- +-- Name: idx_publicchannels_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_publicchannels_delete_at ON public.publicchannels USING btree (deleteat); + + +-- +-- Name: idx_publicchannels_displayname_lower; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_publicchannels_displayname_lower ON public.publicchannels USING btree (lower((displayname)::text)); + + +-- +-- Name: idx_publicchannels_name_lower; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_publicchannels_name_lower ON public.publicchannels USING btree (lower((name)::text)); + + +-- +-- Name: idx_publicchannels_search_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_publicchannels_search_txt ON public.publicchannels USING gin (to_tsvector('english'::regconfig, (((((name)::text || ' '::text) || (displayname)::text) || ' '::text) || (purpose)::text))); + + +-- +-- Name: idx_publicchannels_team_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_publicchannels_team_id ON public.publicchannels USING btree (teamid); + + +-- +-- Name: idx_reactions_channel_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_reactions_channel_id ON public.reactions USING btree (channelid); + + +-- +-- Name: idx_retentionpolicies_displayname; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_retentionpolicies_displayname ON public.retentionpolicies USING btree (displayname); + + +-- +-- Name: idx_retentionpolicieschannels_policyid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_retentionpolicieschannels_policyid ON public.retentionpolicieschannels USING btree (policyid); + + +-- +-- Name: idx_retentionpoliciesteams_policyid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_retentionpoliciesteams_policyid ON public.retentionpoliciesteams USING btree (policyid); + + +-- +-- Name: idx_schemes_channel_admin_role; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_schemes_channel_admin_role ON public.schemes USING btree (defaultchanneladminrole); + + +-- +-- Name: idx_schemes_channel_guest_role; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_schemes_channel_guest_role ON public.schemes USING btree (defaultchannelguestrole); + + +-- +-- Name: idx_schemes_channel_user_role; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_schemes_channel_user_role ON public.schemes USING btree (defaultchanneluserrole); + + +-- +-- Name: idx_sessions_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sessions_create_at ON public.sessions USING btree (createat); + + +-- +-- Name: idx_sessions_expires_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sessions_expires_at ON public.sessions USING btree (expiresat); + + +-- +-- Name: idx_sessions_last_activity_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sessions_last_activity_at ON public.sessions USING btree (lastactivityat); + + +-- +-- Name: idx_sessions_token; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sessions_token ON public.sessions USING btree (token); + + +-- +-- Name: idx_sessions_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sessions_user_id ON public.sessions USING btree (userid); + + +-- +-- Name: idx_sharedchannelusers_remote_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sharedchannelusers_remote_id ON public.sharedchannelusers USING btree (remoteid); + + +-- +-- Name: idx_sidebarcategories_userid_teamid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_sidebarcategories_userid_teamid ON public.sidebarcategories USING btree (userid, teamid); + + +-- +-- Name: idx_status_status_dndendtime; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_status_status_dndendtime ON public.status USING btree (status, dndendtime); + + +-- +-- Name: idx_teammembers_createat; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teammembers_createat ON public.teammembers USING btree (createat); + + +-- +-- Name: idx_teammembers_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teammembers_delete_at ON public.teammembers USING btree (deleteat); + + +-- +-- Name: idx_teammembers_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teammembers_user_id ON public.teammembers USING btree (userid); + + +-- +-- Name: idx_teams_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teams_create_at ON public.teams USING btree (createat); + + +-- +-- Name: idx_teams_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teams_delete_at ON public.teams USING btree (deleteat); + + +-- +-- Name: idx_teams_invite_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teams_invite_id ON public.teams USING btree (inviteid); + + +-- +-- Name: idx_teams_scheme_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teams_scheme_id ON public.teams USING btree (schemeid); + + +-- +-- Name: idx_teams_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_teams_update_at ON public.teams USING btree (updateat); + + +-- +-- Name: idx_thread_memberships_last_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_thread_memberships_last_update_at ON public.threadmemberships USING btree (lastupdated); + + +-- +-- Name: idx_thread_memberships_last_view_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_thread_memberships_last_view_at ON public.threadmemberships USING btree (lastviewed); + + +-- +-- Name: idx_thread_memberships_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_thread_memberships_user_id ON public.threadmemberships USING btree (userid); + + +-- +-- Name: idx_threads_channel_id_last_reply_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_threads_channel_id_last_reply_at ON public.threads USING btree (channelid, lastreplyat); + + +-- +-- Name: idx_uploadsessions_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_uploadsessions_create_at ON public.uploadsessions USING btree (createat); + + +-- +-- Name: idx_uploadsessions_type; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_uploadsessions_type ON public.uploadsessions USING btree (type); + + +-- +-- Name: idx_uploadsessions_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_uploadsessions_user_id ON public.uploadsessions USING btree (userid); + + +-- +-- Name: idx_user_access_tokens_user_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_user_access_tokens_user_id ON public.useraccesstokens USING btree (userid); + + +-- +-- Name: idx_usergroups_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_usergroups_delete_at ON public.usergroups USING btree (deleteat); + + +-- +-- Name: idx_usergroups_displayname; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_usergroups_displayname ON public.usergroups USING btree (displayname); + + +-- +-- Name: idx_usergroups_remote_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_usergroups_remote_id ON public.usergroups USING btree (remoteid); + + +-- +-- Name: idx_users_all_no_full_name_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_all_no_full_name_txt ON public.users USING gin (to_tsvector('english'::regconfig, (((((username)::text || ' '::text) || (nickname)::text) || ' '::text) || (email)::text))); + + +-- +-- Name: idx_users_all_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_all_txt ON public.users USING gin (to_tsvector('english'::regconfig, (((((((((username)::text || ' '::text) || (firstname)::text) || ' '::text) || (lastname)::text) || ' '::text) || (nickname)::text) || ' '::text) || (email)::text))); + + +-- +-- Name: idx_users_create_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_create_at ON public.users USING btree (createat); + + +-- +-- Name: idx_users_delete_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_delete_at ON public.users USING btree (deleteat); + + +-- +-- Name: idx_users_email_lower_textpattern; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_email_lower_textpattern ON public.users USING btree (lower((email)::text) text_pattern_ops); + + +-- +-- Name: idx_users_firstname_lower_textpattern; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_firstname_lower_textpattern ON public.users USING btree (lower((firstname)::text) text_pattern_ops); + + +-- +-- Name: idx_users_lastname_lower_textpattern; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_lastname_lower_textpattern ON public.users USING btree (lower((lastname)::text) text_pattern_ops); + + +-- +-- Name: idx_users_names_no_full_name_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_names_no_full_name_txt ON public.users USING gin (to_tsvector('english'::regconfig, (((username)::text || ' '::text) || (nickname)::text))); + + +-- +-- Name: idx_users_names_txt; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_names_txt ON public.users USING gin (to_tsvector('english'::regconfig, (((((((username)::text || ' '::text) || (firstname)::text) || ' '::text) || (lastname)::text) || ' '::text) || (nickname)::text))); + + +-- +-- Name: idx_users_nickname_lower_textpattern; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_nickname_lower_textpattern ON public.users USING btree (lower((nickname)::text) text_pattern_ops); + + +-- +-- Name: idx_users_update_at; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_update_at ON public.users USING btree (updateat); + + +-- +-- Name: idx_users_username_lower_textpattern; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX idx_users_username_lower_textpattern ON public.users USING btree (lower((username)::text) text_pattern_ops); + + +-- +-- Name: ir_category_item_categoryid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_category_item_categoryid ON public.ir_category_item USING btree (categoryid); + + +-- +-- Name: ir_category_teamid_userid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_category_teamid_userid ON public.ir_category USING btree (teamid, userid); + + +-- +-- Name: ir_channelaction_channelid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_channelaction_channelid ON public.ir_channelaction USING btree (channelid); + + +-- +-- Name: ir_incident_channelid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_incident_channelid ON public.ir_incident USING btree (channelid); + + +-- +-- Name: ir_incident_teamid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_incident_teamid ON public.ir_incident USING btree (teamid); + + +-- +-- Name: ir_incident_teamid_commanderuserid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_incident_teamid_commanderuserid ON public.ir_incident USING btree (teamid, commanderuserid); + + +-- +-- Name: ir_metric_incidentid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_metric_incidentid ON public.ir_metric USING btree (incidentid); + + +-- +-- Name: ir_metric_metricconfigid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_metric_metricconfigid ON public.ir_metric USING btree (metricconfigid); + + +-- +-- Name: ir_metricconfig_playbookid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_metricconfig_playbookid ON public.ir_metricconfig USING btree (playbookid); + + +-- +-- Name: ir_playbook_teamid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_playbook_teamid ON public.ir_playbook USING btree (teamid); + + +-- +-- Name: ir_playbook_updateat; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_playbook_updateat ON public.ir_playbook USING btree (updateat); + + +-- +-- Name: ir_playbookmember_memberid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_playbookmember_memberid ON public.ir_playbookmember USING btree (memberid); + + +-- +-- Name: ir_playbookmember_playbookid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_playbookmember_playbookid ON public.ir_playbookmember USING btree (playbookid); + + +-- +-- Name: ir_run_participants_incidentid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_run_participants_incidentid ON public.ir_run_participants USING btree (incidentid); + + +-- +-- Name: ir_run_participants_userid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_run_participants_userid ON public.ir_run_participants USING btree (userid); + + +-- +-- Name: ir_statusposts_incidentid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_statusposts_incidentid ON public.ir_statusposts USING btree (incidentid); + + +-- +-- Name: ir_statusposts_postid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_statusposts_postid ON public.ir_statusposts USING btree (postid); + + +-- +-- Name: ir_timelineevent_id; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_timelineevent_id ON public.ir_timelineevent USING btree (id); + + +-- +-- Name: ir_timelineevent_incidentid; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE INDEX ir_timelineevent_incidentid ON public.ir_timelineevent USING btree (incidentid); + + +-- +-- Name: remote_clusters_site_url_unique; Type: INDEX; Schema: public; Owner: mmuser +-- + +CREATE UNIQUE INDEX remote_clusters_site_url_unique ON public.remoteclusters USING btree (siteurl, remoteteamid); + + +-- +-- Name: retentionpolicieschannels fk_retentionpolicieschannels_retentionpolicies; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.retentionpolicieschannels + ADD CONSTRAINT fk_retentionpolicieschannels_retentionpolicies FOREIGN KEY (policyid) REFERENCES public.retentionpolicies(id) ON DELETE CASCADE; + + +-- +-- Name: retentionpoliciesteams fk_retentionpoliciesteams_retentionpolicies; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.retentionpoliciesteams + ADD CONSTRAINT fk_retentionpoliciesteams_retentionpolicies FOREIGN KEY (policyid) REFERENCES public.retentionpolicies(id) ON DELETE CASCADE; + + +-- +-- Name: ir_category_item ir_category_item_categoryid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_category_item + ADD CONSTRAINT ir_category_item_categoryid_fkey FOREIGN KEY (categoryid) REFERENCES public.ir_category(id); + + +-- +-- Name: ir_metric ir_metric_incidentid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_metric + ADD CONSTRAINT ir_metric_incidentid_fkey FOREIGN KEY (incidentid) REFERENCES public.ir_incident(id); + + +-- +-- Name: ir_metric ir_metric_metricconfigid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_metric + ADD CONSTRAINT ir_metric_metricconfigid_fkey FOREIGN KEY (metricconfigid) REFERENCES public.ir_metricconfig(id); + + +-- +-- Name: ir_metricconfig ir_metricconfig_playbookid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_metricconfig + ADD CONSTRAINT ir_metricconfig_playbookid_fkey FOREIGN KEY (playbookid) REFERENCES public.ir_playbook(id); + + +-- +-- Name: ir_playbookautofollow ir_playbookautofollow_playbookid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbookautofollow + ADD CONSTRAINT ir_playbookautofollow_playbookid_fkey FOREIGN KEY (playbookid) REFERENCES public.ir_playbook(id); + + +-- +-- Name: ir_playbookmember ir_playbookmember_playbookid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_playbookmember + ADD CONSTRAINT ir_playbookmember_playbookid_fkey FOREIGN KEY (playbookid) REFERENCES public.ir_playbook(id); + + +-- +-- Name: ir_run_participants ir_run_participants_incidentid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_run_participants + ADD CONSTRAINT ir_run_participants_incidentid_fkey FOREIGN KEY (incidentid) REFERENCES public.ir_incident(id); + + +-- +-- Name: ir_statusposts ir_statusposts_incidentid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_statusposts + ADD CONSTRAINT ir_statusposts_incidentid_fkey FOREIGN KEY (incidentid) REFERENCES public.ir_incident(id); + + +-- +-- Name: ir_timelineevent ir_timelineevent_incidentid_fkey; Type: FK CONSTRAINT; Schema: public; Owner: mmuser +-- + +ALTER TABLE ONLY public.ir_timelineevent + ADD CONSTRAINT ir_timelineevent_incidentid_fkey FOREIGN KEY (incidentid) REFERENCES public.ir_incident(id); + + +-- +-- PostgreSQL database dump complete +-- -/*!40000 DROP DATABASE IF EXISTS `mattermost_test`*/; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mattermost_test` /*!40100 DEFAULT CHARACTER SET latin1 */; - -USE `mattermost_test`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Audits` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `Action` text, - `ExtraInfo` text, - `IpAddress` varchar(64) DEFAULT NULL, - `SessionId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_audits_user_id` (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Bots` ( - `UserId` varchar(26) NOT NULL, - `Description` text, - `OwnerId` varchar(190) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `LastIconUpdate` bigint(20) DEFAULT NULL, - PRIMARY KEY (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ChannelMemberHistory` ( - `ChannelId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `JoinTime` bigint(20) NOT NULL, - `LeaveTime` bigint(20) DEFAULT NULL, - PRIMARY KEY (`ChannelId`,`UserId`,`JoinTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ChannelMembers` ( - `ChannelId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `Roles` text, - `LastViewedAt` bigint(20) DEFAULT NULL, - `MsgCount` bigint(20) DEFAULT NULL, - `MentionCount` bigint(20) DEFAULT NULL, - `NotifyProps` json DEFAULT NULL, - `LastUpdateAt` bigint(20) DEFAULT NULL, - `SchemeUser` tinyint(4) DEFAULT NULL, - `SchemeAdmin` tinyint(4) DEFAULT NULL, - `SchemeGuest` tinyint(4) DEFAULT NULL, - `MentionCountRoot` bigint(20) DEFAULT NULL, - `MsgCountRoot` bigint(20) DEFAULT NULL, - `UrgentMentionCount` bigint(20) DEFAULT NULL, - PRIMARY KEY (`ChannelId`,`UserId`), - KEY `idx_channelmembers_user_id_channel_id_last_viewed_at` (`UserId`,`ChannelId`,`LastViewedAt`), - KEY `idx_channelmembers_channel_id_scheme_guest_user_id` (`ChannelId`,`SchemeGuest`,`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Channels` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `Type` enum('D','O','G','P') DEFAULT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `Name` varchar(64) DEFAULT NULL, - `Header` text, - `Purpose` varchar(250) DEFAULT NULL, - `LastPostAt` bigint(20) DEFAULT NULL, - `TotalMsgCount` bigint(20) DEFAULT NULL, - `ExtraUpdateAt` bigint(20) DEFAULT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `SchemeId` varchar(26) DEFAULT NULL, - `GroupConstrained` tinyint(1) DEFAULT NULL, - `Shared` tinyint(1) DEFAULT NULL, - `TotalMsgCountRoot` bigint(20) DEFAULT NULL, - `LastRootPostAt` bigint(20) DEFAULT '0', - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`,`TeamId`), - KEY `idx_channels_update_at` (`UpdateAt`), - KEY `idx_channels_create_at` (`CreateAt`), - KEY `idx_channels_delete_at` (`DeleteAt`), - KEY `idx_channels_scheme_id` (`SchemeId`), - KEY `idx_channels_team_id_display_name` (`TeamId`,`DisplayName`), - KEY `idx_channels_team_id_type` (`TeamId`,`Type`), - FULLTEXT KEY `idx_channel_search_txt` (`Name`,`DisplayName`,`Purpose`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ClusterDiscovery` ( - `Id` varchar(26) NOT NULL, - `Type` varchar(64) DEFAULT NULL, - `ClusterName` varchar(64) DEFAULT NULL, - `Hostname` text, - `GossipPort` int(11) DEFAULT NULL, - `Port` int(11) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `LastPingAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `CommandWebhooks` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `CommandId` varchar(26) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `RootId` varchar(26) DEFAULT NULL, - `UseCount` int(11) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_command_webhook_create_at` (`CreateAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Commands` ( - `Id` varchar(26) NOT NULL, - `Token` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `Trigger` varchar(128) DEFAULT NULL, - `Method` varchar(1) DEFAULT NULL, - `Username` varchar(64) DEFAULT NULL, - `IconURL` text, - `AutoComplete` tinyint(1) DEFAULT NULL, - `AutoCompleteDesc` text, - `AutoCompleteHint` text, - `DisplayName` varchar(64) DEFAULT NULL, - `Description` varchar(128) DEFAULT NULL, - `URL` text, - `PluginId` varchar(190) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_command_team_id` (`TeamId`), - KEY `idx_command_update_at` (`UpdateAt`), - KEY `idx_command_create_at` (`CreateAt`), - KEY `idx_command_delete_at` (`DeleteAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Compliances` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `Status` varchar(64) DEFAULT NULL, - `Count` int(11) DEFAULT NULL, - `Desc` text, - `Type` varchar(64) DEFAULT NULL, - `StartAt` bigint(20) DEFAULT NULL, - `EndAt` bigint(20) DEFAULT NULL, - `Keywords` text, - `Emails` text, - PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Drafts` ( - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) NOT NULL, - `ChannelId` varchar(26) NOT NULL, - `RootId` varchar(26) NOT NULL DEFAULT '', - `Message` text, - `Props` text, - `FileIds` text, - `Priority` text, - PRIMARY KEY (`UserId`,`ChannelId`,`RootId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Emoji` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `Name` varchar(64) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`,`DeleteAt`), - KEY `idx_emoji_update_at` (`UpdateAt`), - KEY `idx_emoji_create_at` (`CreateAt`), - KEY `idx_emoji_delete_at` (`DeleteAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `FileInfo` ( - `Id` varchar(26) NOT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `PostId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `Path` text, - `ThumbnailPath` text, - `PreviewPath` text, - `Name` text, - `Extension` varchar(64) DEFAULT NULL, - `Size` bigint(20) DEFAULT NULL, - `MimeType` text, - `Width` int(11) DEFAULT NULL, - `Height` int(11) DEFAULT NULL, - `HasPreviewImage` tinyint(1) DEFAULT NULL, - `MiniPreview` mediumblob, - `Content` longtext, - `RemoteId` varchar(26) DEFAULT NULL, - `Archived` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`Id`), - KEY `idx_fileinfo_update_at` (`UpdateAt`), - KEY `idx_fileinfo_create_at` (`CreateAt`), - KEY `idx_fileinfo_delete_at` (`DeleteAt`), - KEY `idx_fileinfo_postid_at` (`PostId`), - KEY `idx_fileinfo_extension_at` (`Extension`), - FULLTEXT KEY `idx_fileinfo_name_txt` (`Name`), - FULLTEXT KEY `idx_fileinfo_content_txt` (`Content`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `GroupChannels` ( - `GroupId` varchar(26) NOT NULL, - `AutoAdd` tinyint(1) DEFAULT NULL, - `SchemeAdmin` tinyint(1) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `ChannelId` varchar(26) NOT NULL, - PRIMARY KEY (`GroupId`,`ChannelId`), - KEY `idx_groupchannels_schemeadmin` (`SchemeAdmin`), - KEY `idx_groupchannels_channelid` (`ChannelId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `GroupMembers` ( - `GroupId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`GroupId`,`UserId`), - KEY `idx_groupmembers_create_at` (`CreateAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `GroupTeams` ( - `GroupId` varchar(26) NOT NULL, - `AutoAdd` tinyint(1) DEFAULT NULL, - `SchemeAdmin` tinyint(1) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `TeamId` varchar(26) NOT NULL, - PRIMARY KEY (`GroupId`,`TeamId`), - KEY `idx_groupteams_schemeadmin` (`SchemeAdmin`), - KEY `idx_groupteams_teamid` (`TeamId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Category` ( - `ID` varchar(26) NOT NULL, - `Name` varchar(512) NOT NULL, - `TeamID` varchar(26) NOT NULL, - `UserID` varchar(26) NOT NULL, - `Collapsed` tinyint(1) DEFAULT '0', - `CreateAt` bigint(20) NOT NULL, - `UpdateAt` bigint(20) NOT NULL DEFAULT '0', - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`), - KEY `IR_Category_TeamID_UserID` (`TeamID`,`UserID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Category_Item` ( - `Type` varchar(1) NOT NULL, - `CategoryID` varchar(26) NOT NULL, - `ItemID` varchar(26) NOT NULL, - PRIMARY KEY (`CategoryID`,`ItemID`,`Type`), - KEY `IR_Category_Item_CategoryID` (`CategoryID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_ChannelAction` ( - `ID` varchar(26) NOT NULL, - `ChannelID` varchar(26) DEFAULT NULL, - `Enabled` tinyint(1) DEFAULT '0', - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - `ActionType` text NOT NULL, - `TriggerType` text NOT NULL, - `Payload` json NOT NULL, - PRIMARY KEY (`ID`), - KEY `IR_ChannelAction_ChannelID` (`ChannelID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Incident` ( - `ID` varchar(26) NOT NULL, - `Name` varchar(1024) NOT NULL, - `Description` varchar(4096) NOT NULL, - `IsActive` tinyint(1) NOT NULL, - `CommanderUserID` varchar(26) NOT NULL, - `TeamID` varchar(26) NOT NULL, - `ChannelID` varchar(26) NOT NULL, - `CreateAt` bigint(20) NOT NULL, - `EndAt` bigint(20) NOT NULL DEFAULT '0', - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - `ActiveStage` bigint(20) NOT NULL, - `PostID` varchar(26) NOT NULL DEFAULT '', - `PlaybookID` varchar(26) NOT NULL DEFAULT '', - `ChecklistsJSON` text NOT NULL, - `ActiveStageTitle` varchar(1024) DEFAULT '', - `ReminderPostID` varchar(26) DEFAULT NULL, - `BroadcastChannelID` varchar(26) DEFAULT '', - `PreviousReminder` bigint(20) NOT NULL DEFAULT '0', - `ReminderMessageTemplate` text, - `CurrentStatus` varchar(1024) NOT NULL DEFAULT 'Active', - `ReporterUserID` varchar(26) NOT NULL DEFAULT '', - `ConcatenatedInvitedUserIDs` text, - `DefaultCommanderID` varchar(26) DEFAULT '', - `AnnouncementChannelID` varchar(26) DEFAULT '', - `ConcatenatedWebhookOnCreationURLs` text, - `ConcatenatedInvitedGroupIDs` text, - `Retrospective` text, - `MessageOnJoin` text, - `RetrospectivePublishedAt` bigint(20) NOT NULL DEFAULT '0', - `RetrospectiveReminderIntervalSeconds` bigint(20) NOT NULL DEFAULT '0', - `RetrospectiveWasCanceled` tinyint(1) DEFAULT '0', - `ConcatenatedWebhookOnStatusUpdateURLs` text, - `LastStatusUpdateAt` bigint(20) DEFAULT '0', - `ExportChannelOnFinishedEnabled` tinyint(1) NOT NULL DEFAULT '0', - `CategorizeChannelEnabled` tinyint(1) DEFAULT '0', - `CategoryName` text, - `ConcatenatedBroadcastChannelIds` text, - `ChannelIDToRootID` text, - `ReminderTimerDefaultSeconds` bigint(20) NOT NULL DEFAULT '0', - `StatusUpdateEnabled` tinyint(1) DEFAULT '1', - `RetrospectiveEnabled` tinyint(1) DEFAULT '1', - `StatusUpdateBroadcastChannelsEnabled` tinyint(1) DEFAULT '0', - `StatusUpdateBroadcastWebhooksEnabled` tinyint(1) DEFAULT '0', - `SummaryModifiedAt` bigint(20) NOT NULL DEFAULT '0', - `CreateChannelMemberOnNewParticipant` tinyint(1) DEFAULT '1', - `RemoveChannelMemberOnRemovedParticipant` tinyint(1) DEFAULT '1', - `RunType` varchar(32) DEFAULT 'playbook', - `WebhookOnCreationURL` text, - `WebhookOnStatusUpdateURL` text, - `ExportChannelOnArchiveEnabled` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`), - KEY `IR_Incident_TeamID` (`TeamID`), - KEY `IR_Incident_TeamID_CommanderUserID` (`TeamID`,`CommanderUserID`), - KEY `IR_Incident_ChannelID` (`ChannelID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Metric` ( - `IncidentID` varchar(26) NOT NULL, - `MetricConfigID` varchar(26) NOT NULL, - `Value` bigint(20) DEFAULT NULL, - `Published` tinyint(1) NOT NULL, - PRIMARY KEY (`IncidentID`,`MetricConfigID`), - KEY `IR_Metric_IncidentID` (`IncidentID`), - KEY `IR_Metric_MetricConfigID` (`MetricConfigID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_MetricConfig` ( - `ID` varchar(26) NOT NULL, - `PlaybookID` varchar(26) NOT NULL, - `Title` varchar(512) NOT NULL, - `Description` varchar(4096) NOT NULL, - `Type` varchar(32) NOT NULL, - `Target` bigint(20) DEFAULT NULL, - `Ordering` tinyint(4) NOT NULL DEFAULT '0', - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`), - KEY `IR_MetricConfig_PlaybookID` (`PlaybookID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Playbook` ( - `ID` varchar(26) NOT NULL, - `Title` varchar(1024) NOT NULL, - `Description` varchar(4096) NOT NULL, - `TeamID` varchar(26) NOT NULL, - `CreatePublicIncident` tinyint(1) NOT NULL, - `CreateAt` bigint(20) NOT NULL, - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - `ChecklistsJSON` text NOT NULL, - `NumStages` bigint(20) NOT NULL DEFAULT '0', - `NumSteps` bigint(20) NOT NULL DEFAULT '0', - `BroadcastChannelID` varchar(26) DEFAULT '', - `ReminderMessageTemplate` text, - `ReminderTimerDefaultSeconds` bigint(20) NOT NULL DEFAULT '0', - `ConcatenatedInvitedUserIDs` text, - `InviteUsersEnabled` tinyint(1) DEFAULT '0', - `DefaultCommanderID` varchar(26) DEFAULT '', - `DefaultCommanderEnabled` tinyint(1) DEFAULT '0', - `AnnouncementChannelID` varchar(26) DEFAULT '', - `AnnouncementChannelEnabled` tinyint(1) DEFAULT '0', - `ConcatenatedWebhookOnCreationURLs` text, - `WebhookOnCreationEnabled` tinyint(1) DEFAULT '0', - `ConcatenatedInvitedGroupIDs` text, - `MessageOnJoin` text, - `MessageOnJoinEnabled` tinyint(1) DEFAULT '0', - `RetrospectiveReminderIntervalSeconds` bigint(20) NOT NULL DEFAULT '0', - `RetrospectiveTemplate` text, - `ConcatenatedWebhookOnStatusUpdateURLs` text, - `WebhookOnStatusUpdateEnabled` tinyint(1) DEFAULT '0', - `ConcatenatedSignalAnyKeywords` text, - `SignalAnyKeywordsEnabled` tinyint(1) DEFAULT '0', - `UpdateAt` bigint(20) NOT NULL DEFAULT '0', - `ExportChannelOnFinishedEnabled` tinyint(1) NOT NULL DEFAULT '0', - `CategorizeChannelEnabled` tinyint(1) DEFAULT '0', - `CategoryName` text, - `ConcatenatedBroadcastChannelIds` text, - `BroadcastEnabled` tinyint(1) DEFAULT '0', - `RunSummaryTemplate` text, - `ChannelNameTemplate` text, - `StatusUpdateEnabled` tinyint(1) DEFAULT '1', - `RetrospectiveEnabled` tinyint(1) DEFAULT '1', - `Public` tinyint(1) DEFAULT '0', - `RunSummaryTemplateEnabled` tinyint(1) DEFAULT '1', - `CreateChannelMemberOnNewParticipant` tinyint(1) DEFAULT '1', - `RemoveChannelMemberOnRemovedParticipant` tinyint(1) DEFAULT '1', - `ChannelID` varchar(26) DEFAULT '', - `ChannelMode` varchar(32) DEFAULT 'create_new_channel', - `WebhookOnCreationURL` text, - `WebhookOnStatusUpdateURL` text, - `ExportChannelOnArchiveEnabled` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`), - KEY `IR_Playbook_TeamID` (`TeamID`), - KEY `IR_PlaybookMember_PlaybookID` (`ID`), - KEY `IR_Playbook_UpdateAt` (`UpdateAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_PlaybookAutoFollow` ( - `PlaybookID` varchar(26) NOT NULL, - `UserID` varchar(26) NOT NULL, - PRIMARY KEY (`PlaybookID`,`UserID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_PlaybookMember` ( - `PlaybookID` varchar(26) NOT NULL, - `MemberID` varchar(26) NOT NULL, - `Roles` text, - PRIMARY KEY (`MemberID`,`PlaybookID`), - KEY `IR_PlaybookMember_PlaybookID` (`PlaybookID`), - KEY `IR_PlaybookMember_MemberID` (`MemberID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_Run_Participants` ( - `IncidentID` varchar(26) NOT NULL, - `UserID` varchar(26) NOT NULL, - `IsFollower` tinyint(1) NOT NULL DEFAULT '0', - `IsParticipant` tinyint(1) DEFAULT '0', - PRIMARY KEY (`IncidentID`,`UserID`), - KEY `IR_Run_Participants_UserID` (`UserID`), - KEY `IR_Run_Participants_IncidentID` (`IncidentID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_StatusPosts` ( - `IncidentID` varchar(26) NOT NULL, - `PostID` varchar(26) NOT NULL, - PRIMARY KEY (`IncidentID`,`PostID`), - KEY `IR_StatusPosts_IncidentID` (`IncidentID`), - KEY `IR_StatusPosts_PostID` (`PostID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_System` ( - `SKey` varchar(64) NOT NULL, - `SValue` varchar(1024) DEFAULT NULL, - PRIMARY KEY (`SKey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_TimelineEvent` ( - `ID` varchar(26) NOT NULL, - `IncidentID` varchar(26) NOT NULL, - `CreateAt` bigint(20) NOT NULL, - `DeleteAt` bigint(20) NOT NULL DEFAULT '0', - `EventAt` bigint(20) NOT NULL, - `EventType` varchar(32) NOT NULL DEFAULT '', - `Summary` varchar(256) NOT NULL DEFAULT '', - `Details` varchar(4096) NOT NULL DEFAULT '', - `PostID` varchar(26) NOT NULL DEFAULT '', - `SubjectUserID` varchar(26) NOT NULL DEFAULT '', - `CreatorUserID` varchar(26) NOT NULL DEFAULT '', - PRIMARY KEY (`ID`), - KEY `IR_TimelineEvent_ID` (`ID`), - KEY `IR_TimelineEvent_IncidentID` (`IncidentID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_UserInfo` ( - `ID` varchar(26) NOT NULL, - `LastDailyTodoDMAt` bigint(20) DEFAULT NULL, - `DigestNotificationSettingsJSON` json DEFAULT NULL, - PRIMARY KEY (`ID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IR_ViewedChannel` ( - `ChannelID` varchar(26) NOT NULL, - `UserID` varchar(26) NOT NULL, - PRIMARY KEY (`ChannelID`,`UserID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `IncomingWebhooks` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `Description` text, - `Username` varchar(255) DEFAULT NULL, - `IconURL` text, - `ChannelLocked` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_incoming_webhook_user_id` (`UserId`), - KEY `idx_incoming_webhook_team_id` (`TeamId`), - KEY `idx_incoming_webhook_update_at` (`UpdateAt`), - KEY `idx_incoming_webhook_create_at` (`CreateAt`), - KEY `idx_incoming_webhook_delete_at` (`DeleteAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Jobs` ( - `Id` varchar(26) NOT NULL, - `Type` varchar(32) DEFAULT NULL, - `Priority` bigint(20) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `StartAt` bigint(20) DEFAULT NULL, - `LastActivityAt` bigint(20) DEFAULT NULL, - `Status` varchar(32) DEFAULT NULL, - `Progress` bigint(20) DEFAULT NULL, - `Data` json DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_jobs_type` (`Type`), - KEY `idx_jobs_status_type` (`Status`,`Type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Licenses` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `Bytes` text, - PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `LinkMetadata` ( - `Hash` bigint(20) NOT NULL, - `URL` text, - `Timestamp` bigint(20) DEFAULT NULL, - `Type` varchar(16) DEFAULT NULL, - `Data` json DEFAULT NULL, - PRIMARY KEY (`Hash`), - KEY `idx_link_metadata_url_timestamp` (`URL`(512),`Timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `NotifyAdmin` ( - `UserId` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `RequiredPlan` varchar(100) NOT NULL, - `RequiredFeature` varchar(255) NOT NULL, - `Trial` tinyint(1) NOT NULL, - `SentAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`UserId`,`RequiredFeature`,`RequiredPlan`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `OAuthAccessData` ( - `Token` varchar(26) NOT NULL, - `RefreshToken` varchar(26) DEFAULT NULL, - `RedirectUri` text, - `ClientId` varchar(26) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `ExpiresAt` bigint(20) DEFAULT NULL, - `Scope` varchar(128) DEFAULT NULL, - PRIMARY KEY (`Token`), - UNIQUE KEY `ClientId` (`ClientId`,`UserId`), - KEY `idx_oauthaccessdata_user_id` (`UserId`), - KEY `idx_oauthaccessdata_refresh_token` (`RefreshToken`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `OAuthApps` ( - `Id` varchar(26) NOT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `ClientSecret` varchar(128) DEFAULT NULL, - `Name` varchar(64) DEFAULT NULL, - `Description` text, - `CallbackUrls` text, - `Homepage` text, - `IsTrusted` tinyint(1) DEFAULT NULL, - `IconURL` text, - `MattermostAppID` varchar(32) NOT NULL DEFAULT '', - PRIMARY KEY (`Id`), - KEY `idx_oauthapps_creator_id` (`CreatorId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `OAuthAuthData` ( - `ClientId` varchar(26) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `Code` varchar(128) NOT NULL, - `ExpiresIn` int(11) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `RedirectUri` text, - `State` text, - `Scope` varchar(128) DEFAULT NULL, - PRIMARY KEY (`Code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `OutgoingWebhooks` ( - `Id` varchar(26) NOT NULL, - `Token` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `TriggerWords` text, - `CallbackURLs` text, - `DisplayName` varchar(64) DEFAULT NULL, - `ContentType` varchar(128) DEFAULT NULL, - `TriggerWhen` int(11) DEFAULT NULL, - `Username` varchar(64) DEFAULT NULL, - `IconURL` text, - `Description` text, - PRIMARY KEY (`Id`), - KEY `idx_outgoing_webhook_team_id` (`TeamId`), - KEY `idx_outgoing_webhook_update_at` (`UpdateAt`), - KEY `idx_outgoing_webhook_create_at` (`CreateAt`), - KEY `idx_outgoing_webhook_delete_at` (`DeleteAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `PluginKeyValueStore` ( - `PluginId` varchar(190) NOT NULL, - `PKey` varchar(150) NOT NULL, - `PValue` mediumblob, - `ExpireAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`PluginId`,`PKey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `PostAcknowledgements` ( - `PostId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `AcknowledgedAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`PostId`,`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `PostReminders` ( - `PostId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `TargetTime` bigint(20) DEFAULT NULL, - PRIMARY KEY (`PostId`,`UserId`), - KEY `idx_postreminders_targettime` (`TargetTime`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Posts` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `RootId` varchar(26) DEFAULT NULL, - `OriginalId` varchar(26) DEFAULT NULL, - `Message` text, - `Type` varchar(26) DEFAULT NULL, - `Props` json DEFAULT NULL, - `Hashtags` text, - `Filenames` text, - `FileIds` text, - `HasReactions` tinyint(1) DEFAULT NULL, - `EditAt` bigint(20) DEFAULT NULL, - `IsPinned` tinyint(1) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_posts_update_at` (`UpdateAt`), - KEY `idx_posts_create_at` (`CreateAt`), - KEY `idx_posts_delete_at` (`DeleteAt`), - KEY `idx_posts_user_id` (`UserId`), - KEY `idx_posts_is_pinned` (`IsPinned`), - KEY `idx_posts_channel_id_update_at` (`ChannelId`,`UpdateAt`), - KEY `idx_posts_channel_id_delete_at_create_at` (`ChannelId`,`DeleteAt`,`CreateAt`), - KEY `idx_posts_root_id_delete_at` (`RootId`,`DeleteAt`), - KEY `idx_posts_create_at_id` (`CreateAt`,`Id`), - KEY `idx_posts_original_id` (`OriginalId`), - FULLTEXT KEY `idx_posts_message_txt` (`Message`), - FULLTEXT KEY `idx_posts_hashtags_txt` (`Hashtags`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `PostsPriority` ( - `PostId` varchar(26) NOT NULL, - `ChannelId` varchar(26) NOT NULL, - `Priority` varchar(32) NOT NULL, - `RequestedAck` tinyint(1) DEFAULT NULL, - `PersistentNotifications` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`PostId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Preferences` ( - `UserId` varchar(26) NOT NULL, - `Category` varchar(32) NOT NULL, - `Name` varchar(32) NOT NULL, - `Value` text, - PRIMARY KEY (`UserId`,`Category`,`Name`), - KEY `idx_preferences_category` (`Category`), - KEY `idx_preferences_name` (`Name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ProductNoticeViewState` ( - `UserId` varchar(26) NOT NULL, - `NoticeId` varchar(26) NOT NULL, - `Viewed` int(11) DEFAULT NULL, - `Timestamp` bigint(20) DEFAULT NULL, - PRIMARY KEY (`UserId`,`NoticeId`), - KEY `idx_notice_views_timestamp` (`Timestamp`), - KEY `idx_notice_views_notice_id` (`NoticeId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `PublicChannels` ( - `Id` varchar(26) NOT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `Name` varchar(64) DEFAULT NULL, - `Header` text, - `Purpose` varchar(250) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`,`TeamId`), - KEY `idx_publicchannels_team_id` (`TeamId`), - KEY `idx_publicchannels_delete_at` (`DeleteAt`), - FULLTEXT KEY `idx_publicchannels_search_txt` (`Name`,`DisplayName`,`Purpose`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Reactions` ( - `UserId` varchar(26) NOT NULL, - `PostId` varchar(26) NOT NULL, - `EmojiName` varchar(64) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) NOT NULL DEFAULT '', - PRIMARY KEY (`PostId`,`UserId`,`EmojiName`), - KEY `idx_reactions_channel_id` (`ChannelId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `RecentSearches` ( - `UserId` char(26) NOT NULL, - `SearchPointer` int(11) NOT NULL, - `Query` json DEFAULT NULL, - `CreateAt` bigint(20) NOT NULL, - PRIMARY KEY (`UserId`,`SearchPointer`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `RemoteClusters` ( - `RemoteId` varchar(26) NOT NULL, - `RemoteTeamId` varchar(26) DEFAULT NULL, - `Name` varchar(64) NOT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `SiteURL` text, - `CreateAt` bigint(20) DEFAULT NULL, - `LastPingAt` bigint(20) DEFAULT NULL, - `Token` varchar(26) DEFAULT NULL, - `RemoteToken` varchar(26) DEFAULT NULL, - `Topics` text, - `CreatorId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`RemoteId`,`Name`), - UNIQUE KEY `remote_clusters_site_url_unique` (`RemoteTeamId`,`SiteURL`(168)) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `RetentionPolicies` ( - `Id` varchar(26) NOT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `PostDuration` bigint(20) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `IDX_RetentionPolicies_DisplayName` (`DisplayName`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `RetentionPoliciesChannels` ( - `PolicyId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) NOT NULL, - PRIMARY KEY (`ChannelId`), - KEY `IDX_RetentionPoliciesChannels_PolicyId` (`PolicyId`), - CONSTRAINT `FK_RetentionPoliciesChannels_RetentionPolicies` FOREIGN KEY (`PolicyId`) REFERENCES `RetentionPolicies` (`Id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `RetentionPoliciesTeams` ( - `PolicyId` varchar(26) DEFAULT NULL, - `TeamId` varchar(26) NOT NULL, - PRIMARY KEY (`TeamId`), - KEY `IDX_RetentionPoliciesTeams_PolicyId` (`PolicyId`), - CONSTRAINT `FK_RetentionPoliciesTeams_RetentionPolicies` FOREIGN KEY (`PolicyId`) REFERENCES `RetentionPolicies` (`Id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Roles` ( - `Id` varchar(26) NOT NULL, - `Name` varchar(64) DEFAULT NULL, - `DisplayName` varchar(128) DEFAULT NULL, - `Description` text, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `Permissions` longtext, - `SchemeManaged` tinyint(1) DEFAULT NULL, - `BuiltIn` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Schemes` ( - `Id` varchar(26) NOT NULL, - `Name` varchar(64) DEFAULT NULL, - `DisplayName` varchar(128) DEFAULT NULL, - `Description` text, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `Scope` varchar(32) DEFAULT NULL, - `DefaultTeamAdminRole` varchar(64) DEFAULT NULL, - `DefaultTeamUserRole` varchar(64) DEFAULT NULL, - `DefaultChannelAdminRole` varchar(64) DEFAULT NULL, - `DefaultChannelUserRole` varchar(64) DEFAULT NULL, - `DefaultTeamGuestRole` varchar(64) DEFAULT NULL, - `DefaultChannelGuestRole` varchar(64) DEFAULT NULL, - `DefaultPlaybookAdminRole` varchar(64) DEFAULT '', - `DefaultPlaybookMemberRole` varchar(64) DEFAULT '', - `DefaultRunAdminRole` varchar(64) DEFAULT '', - `DefaultRunMemberRole` varchar(64) DEFAULT '', - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`), - KEY `idx_schemes_channel_guest_role` (`DefaultChannelGuestRole`), - KEY `idx_schemes_channel_user_role` (`DefaultChannelUserRole`), - KEY `idx_schemes_channel_admin_role` (`DefaultChannelAdminRole`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Sessions` ( - `Id` varchar(26) NOT NULL, - `Token` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `ExpiresAt` bigint(20) DEFAULT NULL, - `LastActivityAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `DeviceId` text, - `Roles` text, - `IsOAuth` tinyint(1) DEFAULT NULL, - `Props` json DEFAULT NULL, - `ExpiredNotify` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_sessions_user_id` (`UserId`), - KEY `idx_sessions_token` (`Token`), - KEY `idx_sessions_expires_at` (`ExpiresAt`), - KEY `idx_sessions_create_at` (`CreateAt`), - KEY `idx_sessions_last_activity_at` (`LastActivityAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SharedChannelAttachments` ( - `Id` varchar(26) NOT NULL, - `FileId` varchar(26) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `LastSyncAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `FileId` (`FileId`,`RemoteId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SharedChannelRemotes` ( - `Id` varchar(26) NOT NULL, - `ChannelId` varchar(26) NOT NULL, - `CreatorId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `IsInviteAccepted` tinyint(1) DEFAULT NULL, - `IsInviteConfirmed` tinyint(1) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - `LastPostUpdateAt` bigint(20) DEFAULT NULL, - `LastPostId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`,`ChannelId`), - UNIQUE KEY `ChannelId` (`ChannelId`,`RemoteId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SharedChannelUsers` ( - `Id` varchar(26) NOT NULL, - `UserId` varchar(26) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `LastSyncAt` bigint(20) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `UserId` (`UserId`,`ChannelId`,`RemoteId`), - KEY `idx_sharedchannelusers_remote_id` (`RemoteId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SharedChannels` ( - `ChannelId` varchar(26) NOT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `Home` tinyint(1) DEFAULT NULL, - `ReadOnly` tinyint(1) DEFAULT NULL, - `ShareName` varchar(64) DEFAULT NULL, - `ShareDisplayName` varchar(64) DEFAULT NULL, - `SharePurpose` varchar(250) DEFAULT NULL, - `ShareHeader` text, - `CreatorId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`ChannelId`), - UNIQUE KEY `ShareName` (`ShareName`,`TeamId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SidebarCategories` ( - `Id` varchar(128) NOT NULL, - `UserId` varchar(26) DEFAULT NULL, - `TeamId` varchar(26) DEFAULT NULL, - `SortOrder` bigint(20) DEFAULT NULL, - `Sorting` varchar(64) DEFAULT NULL, - `Type` varchar(64) DEFAULT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `Muted` tinyint(1) DEFAULT NULL, - `Collapsed` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_sidebarcategories_userid_teamid` (`UserId`,`TeamId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SidebarChannels` ( - `ChannelId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `CategoryId` varchar(128) NOT NULL, - `SortOrder` bigint(20) DEFAULT NULL, - PRIMARY KEY (`ChannelId`,`UserId`,`CategoryId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Status` ( - `UserId` varchar(26) NOT NULL, - `Status` varchar(32) DEFAULT NULL, - `Manual` tinyint(1) DEFAULT NULL, - `LastActivityAt` bigint(20) DEFAULT NULL, - `DNDEndTime` bigint(20) DEFAULT NULL, - `PrevStatus` varchar(32) DEFAULT NULL, - PRIMARY KEY (`UserId`), - KEY `idx_status_status_dndendtime` (`Status`,`DNDEndTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Systems` ( - `Name` varchar(64) NOT NULL, - `Value` text, - PRIMARY KEY (`Name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `TeamMembers` ( - `TeamId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `Roles` text, - `DeleteAt` bigint(20) DEFAULT NULL, - `SchemeUser` tinyint(4) DEFAULT NULL, - `SchemeAdmin` tinyint(4) DEFAULT NULL, - `SchemeGuest` tinyint(4) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT '0', - PRIMARY KEY (`TeamId`,`UserId`), - KEY `idx_teammembers_user_id` (`UserId`), - KEY `idx_teammembers_delete_at` (`DeleteAt`), - KEY `idx_teammembers_createat` (`CreateAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Teams` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `DisplayName` varchar(64) DEFAULT NULL, - `Name` varchar(64) DEFAULT NULL, - `Description` varchar(255) DEFAULT NULL, - `Email` varchar(128) DEFAULT NULL, - `Type` enum('I','O') DEFAULT NULL, - `CompanyName` varchar(64) DEFAULT NULL, - `AllowedDomains` text, - `InviteId` varchar(32) DEFAULT NULL, - `SchemeId` varchar(26) DEFAULT NULL, - `AllowOpenInvite` tinyint(1) DEFAULT NULL, - `LastTeamIconUpdate` bigint(20) DEFAULT NULL, - `GroupConstrained` tinyint(1) DEFAULT NULL, - `CloudLimitsArchived` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`), - KEY `idx_teams_invite_id` (`InviteId`), - KEY `idx_teams_update_at` (`UpdateAt`), - KEY `idx_teams_create_at` (`CreateAt`), - KEY `idx_teams_delete_at` (`DeleteAt`), - KEY `idx_teams_scheme_id` (`SchemeId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `TermsOfService` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `Text` text, - PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ThreadMemberships` ( - `PostId` varchar(26) NOT NULL, - `UserId` varchar(26) NOT NULL, - `Following` tinyint(1) DEFAULT NULL, - `LastViewed` bigint(20) DEFAULT NULL, - `LastUpdated` bigint(20) DEFAULT NULL, - `UnreadMentions` bigint(20) DEFAULT NULL, - PRIMARY KEY (`PostId`,`UserId`), - KEY `idx_thread_memberships_last_update_at` (`LastUpdated`), - KEY `idx_thread_memberships_last_view_at` (`LastViewed`), - KEY `idx_thread_memberships_user_id` (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Threads` ( - `PostId` varchar(26) NOT NULL, - `ReplyCount` bigint(20) DEFAULT NULL, - `LastReplyAt` bigint(20) DEFAULT NULL, - `Participants` json DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `ThreadDeleteAt` bigint(20) DEFAULT NULL, - `ThreadTeamId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`PostId`), - KEY `idx_threads_channel_id_last_reply_at` (`ChannelId`,`LastReplyAt`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Tokens` ( - `Token` varchar(64) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `Type` varchar(64) DEFAULT NULL, - `Extra` text, - PRIMARY KEY (`Token`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `TrueUpReviewHistory` ( - `DueDate` bigint(20) NOT NULL, - `Completed` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`DueDate`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `UploadSessions` ( - `Id` varchar(26) NOT NULL, - `Type` enum('attachment','import') DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `ChannelId` varchar(26) DEFAULT NULL, - `Filename` text, - `Path` text, - `FileSize` bigint(20) DEFAULT NULL, - `FileOffset` bigint(20) DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - `ReqFileId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`), - KEY `idx_uploadsessions_user_id` (`UserId`), - KEY `idx_uploadsessions_create_at` (`CreateAt`), - KEY `idx_uploadsessions_type` (`Type`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `UserAccessTokens` ( - `Id` varchar(26) NOT NULL, - `Token` varchar(26) DEFAULT NULL, - `UserId` varchar(26) DEFAULT NULL, - `Description` text, - `IsActive` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Token` (`Token`), - KEY `idx_user_access_tokens_user_id` (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `UserGroups` ( - `Id` varchar(26) NOT NULL, - `Name` varchar(64) DEFAULT NULL, - `DisplayName` varchar(128) DEFAULT NULL, - `Description` text, - `Source` varchar(64) DEFAULT NULL, - `RemoteId` varchar(48) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `AllowReference` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Name` (`Name`), - UNIQUE KEY `Source` (`Source`,`RemoteId`), - KEY `idx_usergroups_remote_id` (`RemoteId`), - KEY `idx_usergroups_delete_at` (`DeleteAt`), - KEY `idx_usergroups_displayname` (`DisplayName`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `UserTermsOfService` ( - `UserId` varchar(26) NOT NULL, - `TermsOfServiceId` varchar(26) DEFAULT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `Users` ( - `Id` varchar(26) NOT NULL, - `CreateAt` bigint(20) DEFAULT NULL, - `UpdateAt` bigint(20) DEFAULT NULL, - `DeleteAt` bigint(20) DEFAULT NULL, - `Username` varchar(64) DEFAULT NULL, - `Password` varchar(128) DEFAULT NULL, - `AuthData` varchar(128) DEFAULT NULL, - `AuthService` varchar(32) DEFAULT NULL, - `Email` varchar(128) DEFAULT NULL, - `EmailVerified` tinyint(1) DEFAULT NULL, - `Nickname` varchar(64) DEFAULT NULL, - `FirstName` varchar(64) DEFAULT NULL, - `LastName` varchar(64) DEFAULT NULL, - `Roles` text, - `AllowMarketing` tinyint(1) DEFAULT NULL, - `Props` json DEFAULT NULL, - `NotifyProps` json DEFAULT NULL, - `LastPasswordUpdate` bigint(20) DEFAULT NULL, - `LastPictureUpdate` bigint(20) DEFAULT NULL, - `FailedAttempts` int(11) DEFAULT NULL, - `Locale` varchar(5) DEFAULT NULL, - `MfaActive` tinyint(1) DEFAULT NULL, - `MfaSecret` varchar(128) DEFAULT NULL, - `Position` varchar(128) DEFAULT NULL, - `Timezone` json DEFAULT NULL, - `RemoteId` varchar(26) DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `Username` (`Username`), - UNIQUE KEY `AuthData` (`AuthData`), - UNIQUE KEY `Email` (`Email`), - KEY `idx_users_update_at` (`UpdateAt`), - KEY `idx_users_create_at` (`CreateAt`), - KEY `idx_users_delete_at` (`DeleteAt`), - FULLTEXT KEY `idx_users_all_txt` (`Username`,`FirstName`,`LastName`,`Nickname`,`Email`), - FULLTEXT KEY `idx_users_all_no_full_name_txt` (`Username`,`Nickname`,`Email`), - FULLTEXT KEY `idx_users_names_txt` (`Username`,`FirstName`,`LastName`,`Nickname`), - FULLTEXT KEY `idx_users_names_no_full_name_txt` (`Username`,`Nickname`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `db_lock` ( - `Id` varchar(64) NOT NULL, - `ExpireAt` bigint(20) NOT NULL, - PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `db_migrations` ( - `Version` bigint(20) NOT NULL, - `Name` varchar(64) NOT NULL, - PRIMARY KEY (`Version`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_blocks` ( - `id` varchar(36) NOT NULL, - `insert_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), - `parent_id` varchar(36) DEFAULT NULL, - `schema` bigint(20) DEFAULT NULL, - `type` text, - `title` text, - `fields` text, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `root_id` varchar(36) DEFAULT NULL, - `modified_by` varchar(36) NOT NULL, - `channel_id` varchar(36) NOT NULL, - `created_by` varchar(36) NOT NULL, - `board_id` varchar(36) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `idx_blocks_board_id_parent_id` (`board_id`,`parent_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_blocks_history` ( - `id` varchar(36) NOT NULL, - `insert_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), - `parent_id` varchar(36) DEFAULT NULL, - `schema` bigint(20) DEFAULT NULL, - `type` text, - `title` text, - `fields` text, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `root_id` varchar(36) DEFAULT NULL, - `modified_by` varchar(36) DEFAULT NULL, - `channel_id` varchar(36) DEFAULT NULL, - `created_by` varchar(36) DEFAULT NULL, - `board_id` varchar(36) DEFAULT NULL, - PRIMARY KEY (`id`,`insert_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_board_members` ( - `board_id` varchar(36) NOT NULL, - `user_id` varchar(36) NOT NULL, - `roles` varchar(64) DEFAULT NULL, - `scheme_admin` tinyint(1) DEFAULT NULL, - `scheme_editor` tinyint(1) DEFAULT NULL, - `scheme_commenter` tinyint(1) DEFAULT NULL, - `scheme_viewer` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`board_id`,`user_id`), - KEY `idx_board_members_user_id` (`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_board_members_history` ( - `board_id` varchar(36) NOT NULL, - `user_id` varchar(36) NOT NULL, - `action` varchar(10) DEFAULT NULL, - `insert_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), - PRIMARY KEY (`board_id`,`user_id`,`insert_at`), - KEY `idx_board_members_history_user_id` (`user_id`), - KEY `idx_board_members_history_board_id_user_id` (`board_id`,`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_boards` ( - `id` varchar(36) NOT NULL, - `insert_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), - `team_id` varchar(36) NOT NULL, - `channel_id` varchar(36) DEFAULT NULL, - `created_by` varchar(36) DEFAULT NULL, - `modified_by` varchar(36) DEFAULT NULL, - `type` varchar(1) NOT NULL, - `title` text NOT NULL, - `description` text, - `icon` varchar(256) DEFAULT NULL, - `show_description` tinyint(1) DEFAULT NULL, - `is_template` tinyint(1) DEFAULT NULL, - `template_version` int(11) DEFAULT '0', - `properties` json DEFAULT NULL, - `card_properties` json DEFAULT NULL, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `minimum_role` varchar(36) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `idx_boards_team_id_is_template` (`team_id`,`is_template`), - KEY `idx_boards_channel_id` (`channel_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_boards_history` ( - `id` varchar(36) NOT NULL, - `insert_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), - `team_id` varchar(36) NOT NULL, - `channel_id` varchar(36) DEFAULT NULL, - `created_by` varchar(36) DEFAULT NULL, - `modified_by` varchar(36) DEFAULT NULL, - `type` varchar(1) NOT NULL, - `title` text NOT NULL, - `description` text, - `icon` varchar(256) DEFAULT NULL, - `show_description` tinyint(1) DEFAULT NULL, - `is_template` tinyint(1) DEFAULT NULL, - `template_version` int(11) DEFAULT '0', - `properties` json DEFAULT NULL, - `card_properties` json DEFAULT NULL, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `minimum_role` varchar(36) NOT NULL DEFAULT '', - PRIMARY KEY (`id`,`insert_at`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_categories` ( - `id` varchar(36) NOT NULL, - `name` varchar(100) NOT NULL, - `user_id` varchar(36) NOT NULL, - `team_id` varchar(36) NOT NULL, - `channel_id` varchar(36) DEFAULT NULL, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `collapsed` tinyint(1) DEFAULT '0', - `type` varchar(64) DEFAULT NULL, - `sort_order` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `idx_categories_user_id_team_id` (`user_id`,`team_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_category_boards` ( - `id` varchar(36) NOT NULL, - `user_id` varchar(36) NOT NULL, - `category_id` varchar(36) NOT NULL, - `board_id` varchar(36) NOT NULL, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `sort_order` bigint(20) DEFAULT NULL, - `hidden` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_user_category_board` (`user_id`,`board_id`), - KEY `idx_category_boards_category_id` (`category_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_file_info` ( - `id` varchar(26) NOT NULL, - `create_at` bigint(20) NOT NULL, - `delete_at` bigint(20) DEFAULT NULL, - `name` text NOT NULL, - `extension` varchar(50) NOT NULL, - `size` bigint(20) NOT NULL, - `archived` tinyint(1) DEFAULT NULL, - `path` varchar(512) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_notification_hints` ( - `block_type` varchar(10) DEFAULT NULL, - `block_id` varchar(36) NOT NULL, - `workspace_id` varchar(36) DEFAULT NULL, - `modified_by_id` varchar(36) DEFAULT NULL, - `create_at` bigint(20) DEFAULT NULL, - `notify_at` bigint(20) DEFAULT NULL, - PRIMARY KEY (`block_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_preferences` ( - `userid` varchar(36) NOT NULL, - `category` varchar(32) NOT NULL, - `name` varchar(32) NOT NULL, - `value` text, - PRIMARY KEY (`userid`,`category`,`name`), - KEY `idx_preferences_category` (`category`), - KEY `idx_preferences_name` (`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_schema_migrations` ( - `Version` bigint(20) NOT NULL, - `Name` varchar(64) NOT NULL, - PRIMARY KEY (`Version`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_sessions` ( - `id` varchar(100) NOT NULL, - `token` varchar(100) DEFAULT NULL, - `user_id` varchar(100) DEFAULT NULL, - `props` text, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `auth_service` varchar(20) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_sharing` ( - `id` varchar(36) NOT NULL, - `enabled` tinyint(1) DEFAULT NULL, - `token` varchar(100) DEFAULT NULL, - `modified_by` varchar(36) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `workspace_id` varchar(36) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_subscriptions` ( - `block_type` varchar(10) DEFAULT NULL, - `block_id` varchar(36) NOT NULL, - `workspace_id` varchar(36) DEFAULT NULL, - `subscriber_type` varchar(10) DEFAULT NULL, - `subscriber_id` varchar(36) NOT NULL, - `notified_at` bigint(20) DEFAULT NULL, - `create_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - PRIMARY KEY (`block_id`,`subscriber_id`), - KEY `idx_subscriptions_subscriber_id` (`subscriber_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_system_settings` ( - `id` varchar(100) NOT NULL, - `value` text, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_teams` ( - `id` varchar(36) NOT NULL, - `signup_token` varchar(100) NOT NULL, - `settings` text, - `modified_by` varchar(36) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_users` ( - `id` varchar(100) NOT NULL, - `username` varchar(100) DEFAULT NULL, - `email` varchar(255) DEFAULT NULL, - `password` varchar(100) DEFAULT NULL, - `mfa_secret` varchar(100) DEFAULT NULL, - `auth_service` varchar(20) DEFAULT NULL, - `auth_data` varchar(255) DEFAULT NULL, - `props` text, - `create_at` bigint(20) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - `delete_at` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `focalboard_workspaces` ( - `id` varchar(36) NOT NULL, - `signup_token` varchar(100) NOT NULL, - `settings` text, - `modified_by` varchar(36) DEFAULT NULL, - `update_at` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mattermost_test` /*!40100 DEFAULT CHARACTER SET latin1 */; - -USE `mattermost_test`; -INSERT INTO `Bots` VALUES ('6g9zjk1d7brz8rqiypd9kypn5c','Feedbackbot collects user feedback to improve Mattermost. [Learn more](https://mattermost.com/pl/default-nps).','com.mattermost.nps',1684139058981,1684139058981,0,0); -INSERT INTO `Bots` VALUES ('d6eb3jh8iprzpxim14w9hkopbr','Created by Boards plugin.','focalboard',1684139114835,1684139114835,0,0); -INSERT INTO `Bots` VALUES ('dk8nggnjtt8yipcbmuqem4rfkc','','jactwicuqb8bu8pau8mgjydzeo',1684139700012,1684139700012,0,0); -INSERT INTO `Bots` VALUES ('k8crtspa5bfadc6iu6m93p4orh','Nautobot Test Bot','jactwicuqb8bu8pau8mgjydzeo',1684146025510,1684146025510,0,0); -INSERT INTO `Bots` VALUES ('o113xcgte78kpezuouwcr6abpo','Calls Bot','com.mattermost.calls',1684139059888,1684139059888,0,0); -INSERT INTO `Bots` VALUES ('ozpddc4xxi85tmrwaqsjmgw1kc','Playbooks bot.','playbooks',1684139059822,1684139059822,0,0); -INSERT INTO `Bots` VALUES ('qmaiqbz1e3fo8qz1nsmkhqbznh','Mattermost Apps Registry and API proxy.','com.mattermost.apps',1684139059460,1684139059460,0,0); -INSERT INTO `ChannelMembers` VALUES ('8sz36rga1in69gaunpogq95r1w','jactwicuqb8bu8pau8mgjydzeo','',1684153509947,2,0,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684153509947,1,1,0,0,2,0); -INSERT INTO `ChannelMembers` VALUES ('8sz36rga1in69gaunpogq95r1w','k8crtspa5bfadc6iu6m93p4orh','',0,0,0,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684146863323,1,0,0,0,0,0); -INSERT INTO `ChannelMembers` VALUES ('9g8qo5udpp8dzdud8jex1m6kuh','jactwicuqb8bu8pau8mgjydzeo','',1684146025577,1,0,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684146025577,1,0,0,0,1,0); -INSERT INTO `ChannelMembers` VALUES ('9g8qo5udpp8dzdud8jex1m6kuh','k8crtspa5bfadc6iu6m93p4orh','',0,0,0,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684146025519,1,0,0,0,0,0); -INSERT INTO `ChannelMembers` VALUES ('fi1muawz1bybue4gwu95kni4eh','jactwicuqb8bu8pau8mgjydzeo','',1684139716016,0,0,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684139716016,1,1,0,0,0,0); -INSERT INTO `ChannelMembers` VALUES ('fi1muawz1bybue4gwu95kni4eh','k8crtspa5bfadc6iu6m93p4orh','',0,0,1,'{\"push\": \"default\", \"email\": \"default\", \"desktop\": \"default\", \"mark_unread\": \"all\", \"ignore_channel_mentions\": \"default\"}',1684146863438,1,0,0,1,0,0); -INSERT INTO `Channels` VALUES ('8sz36rga1in69gaunpogq95r1w',1684139715853,1684139715853,0,'35odngbgr7yw3bf13o8kg85ngh','O','Town Square','town-square','','',1684153509947,2,0,'',NULL,NULL,NULL,2,1684153509947); -INSERT INTO `Channels` VALUES ('9g8qo5udpp8dzdud8jex1m6kuh',1684146025517,1684146025517,0,'','D','','jactwicuqb8bu8pau8mgjydzeo__k8crtspa5bfadc6iu6m93p4orh','','',1684146025577,1,0,'k8crtspa5bfadc6iu6m93p4orh',NULL,NULL,0,1,1684146025577); -INSERT INTO `Channels` VALUES ('fi1muawz1bybue4gwu95kni4eh',1684139715866,1684139715866,0,'35odngbgr7yw3bf13o8kg85ngh','O','Off-Topic','off-topic','','',1684146863411,0,0,'',NULL,NULL,NULL,0,1684146863411); -INSERT INTO `Commands` VALUES ('yhepukctj7r1jgr8kappi7mb7e','tc1u8wbh53fwxxdkhswbmu9wsa',1685617546901,1685618110521,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','aci','P','','',0,'','','Cisco ACI','Cisco ACI Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('846xisdqmtro9yd3eg8m45co3o','c7udax974iymjkmoyhi1a11cpy',1685089324429,1685089324429,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','ansible','P','','',0,'','','Ansible','Ansible Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('561dqoomjt8ixqc3td9m53i3mh','p7phuwhpaiddjxqf8c1hnw33yh',1686737880192,1686737880192,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','clear','P','','',0,'','','Clear','Clear Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('z7bmireh6tgpzgkujc4moaaiqe','pxannsh78iyhbm8fumz8mxk9ih',1685442897799,1685442897799,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','cloudvision','P','','',0,'','','Arista CloudVision','Arista CloudVision Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('px7ae4ik6idp7pb51hx5ms4x3w','o1yiadnpifbzddt3umcedeypdr',1684405443321,1684405443321,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','grafana','P','','',0,'','','Grafana','Grafana Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('f74t71u6p7rpbmz7ruebja7ana','uqydyxkx4tykinw5z5u9dany1o',1685099154275,1685099154275,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','ipfabric','P','','',0,'','','IP Fabric','IP Fabric Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('j5pnszdfcpbt3f6yfs63o5bwhw','t9irqwjni3dozf3yx6tzak7k3w',1685532127072,1685532127072,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','meraki','P','','',0,'','','Cisco Meraki','Cisco Meraki Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('d9irq7zuwt84pr77crnteso6da','rmdpfdjhnpg988e7ujzyom4euh',1684146546769,1684152166227,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','nautobot','P','','',0,'','','Nautobot','Nautobot Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Commands` VALUES ('uooffhygyigtfb4454k9yxm81h','6nf5cmz1ft8bdfykz46cs5pofo',1685702889199,1685702889199,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','panorama','P','','',0,'','','Panorama','Panorama Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/',''); -INSERT INTO `Drafts` VALUES (1684146834706,1684335673276,1684335673276,'jactwicuqb8bu8pau8mgjydzeo','8sz36rga1in69gaunpogq95r1w','','/nautobot','{}','[]','null'); -INSERT INTO `IR_System` VALUES ('DatabaseVersion','0.63.0'); -INSERT INTO `IR_UserInfo` VALUES ('jactwicuqb8bu8pau8mgjydzeo',1684387012504,'{\"disable_daily_digest\": false, \"disable_weekly_digest\": false}'); -INSERT INTO `Jobs` VALUES ('kwwq4cbzu3nmxdewywnouh48xo','migrations',0,1684139119925,1684139134240,1684139136273,'success',0,'{\"last_done\": \"{\\\"current_table\\\":\\\"ChannelMembers\\\",\\\"last_team_id\\\":\\\"00000000000000000000000000\\\",\\\"last_channel_id\\\":\\\"00000000000000000000000000\\\",\\\"last_user\\\":\\\"00000000000000000000000000\\\"}\", \"migration_key\": \"migration_advanced_permissions_phase_2\"}'); -INSERT INTO `PluginKeyValueStore` VALUES ('com.mattermost.apps','mmi_botid',_binary 'qmaiqbz1e3fo8qz1nsmkhqbznh',0); -INSERT INTO `PluginKeyValueStore` VALUES ('com.mattermost.calls','mmi_botid',_binary 'o113xcgte78kpezuouwcr6abpo',0); -INSERT INTO `PluginKeyValueStore` VALUES ('com.mattermost.nps','ServerUpgrade-7.10.0',_binary '{\"server_version\":\"7.10.0\",\"upgrade_at\":\"2023-05-15T08:24:19.013024124Z\"}',0); -INSERT INTO `PluginKeyValueStore` VALUES ('com.mattermost.nps','Survey-7.10.0',_binary '{\"server_version\":\"7.10.0\",\"create_at\":\"2023-05-15T08:24:19.013024124Z\",\"start_at\":\"2023-06-29T08:24:19.013024124Z\"}',0); -INSERT INTO `PluginKeyValueStore` VALUES ('com.mattermost.nps','WelcomeFeedbackMigration',_binary '{\"CreateAt\":\"2023-05-15T08:24:19.013024124Z\"}',0); -INSERT INTO `PluginKeyValueStore` VALUES ('focalboard','mmi_botid',_binary 'd6eb3jh8iprzpxim14w9hkopbr',0); -INSERT INTO `PluginKeyValueStore` VALUES ('playbooks','mmi_botid',_binary 'ozpddc4xxi85tmrwaqsjmgw1kc',0); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','channel_approximate_view_time','','1684386592335'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','channel_open_time','9g8qo5udpp8dzdud8jex1m6kuh','1684335914329'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','direct_channel_show','k8crtspa5bfadc6iu6m93p4orh','true'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','drafts','drafts_tour_tip_showed','{\"drafts_tour_tip_showed\":true}'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','insights','insights_tutorial_state','{\"insights_modal_viewed\":true}'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','onboarding_task_list','onboarding_task_list_open','false'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','onboarding_task_list','onboarding_task_list_show','false'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','recommended_next_steps','hide','true'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','touched','invite_members','true'); -INSERT INTO `Preferences` VALUES ('jactwicuqb8bu8pau8mgjydzeo','tutorial_step','jactwicuqb8bu8pau8mgjydzeo','0'); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','crt-admin-default_off',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','crt-admin-disabled',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','crt-user-always-on',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','crt-user-default-on',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','desktop_upgrade_v5.2',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','server_upgrade_v7.9',1,1684139698); -INSERT INTO `ProductNoticeViewState` VALUES ('jactwicuqb8bu8pau8mgjydzeo','unsupported-server-v5.37',1,1684139698); -INSERT INTO `PublicChannels` VALUES ('8sz36rga1in69gaunpogq95r1w',0,'35odngbgr7yw3bf13o8kg85ngh','Town Square','town-square','',''); -INSERT INTO `PublicChannels` VALUES ('fi1muawz1bybue4gwu95kni4eh',0,'35odngbgr7yw3bf13o8kg85ngh','Off-Topic','off-topic','',''); -INSERT INTO `Roles` VALUES ('13bs7grka7f45g6eskmqbuypbw','team_user','authentication.roles.team_user.name','authentication.roles.team_user.description',1684139050819,1684139055707,0,' playbook_public_create list_team_channels join_public_channels playbook_private_create create_private_channel add_user_to_team read_public_channel view_team create_public_channel invite_user',1,1); -INSERT INTO `Roles` VALUES ('1assaqn3tt899xeda1aiop8bky','run_admin','authentication.roles.run_admin.name','authentication.roles.run_admin.description',1684139050763,1684139055713,0,' run_manage_properties run_manage_members',1,1); -INSERT INTO `Roles` VALUES ('7eh3dpufq7g4zfza5ku6zacgdo','run_member','authentication.roles.run_member.name','authentication.roles.run_member.description',1684139050908,1684139055719,0,' run_view',1,1); -INSERT INTO `Roles` VALUES ('99faipwtbf8sbes7ipkdfz348e','system_post_all_public','authentication.roles.system_post_all_public.name','authentication.roles.system_post_all_public.description',1684139050876,1684139055725,0,' use_channel_mentions create_post_public use_group_mentions',0,1); -INSERT INTO `Roles` VALUES ('9wqa3318s3fw781rjkpjwbchaw','team_guest','authentication.roles.team_guest.name','authentication.roles.team_guest.description',1684139050859,1684139055732,0,' view_team',1,1); -INSERT INTO `Roles` VALUES ('a8fy4zx49trbbfi45wexsqmxdy','system_user','authentication.roles.global_user.name','authentication.roles.global_user.description',1684139050913,1684139055739,0,' delete_custom_group delete_emojis view_members create_team edit_custom_group create_group_channel manage_custom_group_members create_direct_channel restore_custom_group list_public_teams create_custom_group join_public_teams create_emojis',1,1); -INSERT INTO `Roles` VALUES ('bb9guastc3f99bqd91szo7dkch','team_post_all','authentication.roles.team_post_all.name','authentication.roles.team_post_all.description',1684139050903,1684139055745,0,' create_post use_channel_mentions use_group_mentions',0,1); -INSERT INTO `Roles` VALUES ('djorm5qfbpdimcdg8b8wdku5na','system_user_manager','authentication.roles.system_user_manager.name','authentication.roles.system_user_manager.description',1684139050798,1684139055752,0,' sysconsole_read_authentication_saml read_ldap_sync_job delete_public_channel sysconsole_read_authentication_ldap test_ldap sysconsole_write_user_management_teams convert_public_channel_to_private join_public_teams add_user_to_team sysconsole_read_user_management_groups manage_public_channel_members sysconsole_write_user_management_channels read_channel view_team manage_channel_roles sysconsole_read_user_management_permissions manage_team_roles read_private_channel_groups sysconsole_read_authentication_password remove_user_from_team join_private_teams sysconsole_read_user_management_channels sysconsole_read_authentication_email sysconsole_read_authentication_signup sysconsole_read_authentication_mfa sysconsole_read_authentication_openid list_private_teams list_public_teams sysconsole_write_user_management_groups delete_private_channel manage_public_channel_properties manage_team read_public_channel convert_private_channel_to_public manage_private_channel_members sysconsole_read_authentication_guest_access sysconsole_read_user_management_teams read_public_channel_groups manage_private_channel_properties',0,1); -INSERT INTO `Roles` VALUES ('jbrz4h5gqt877cuxh57absnc7c','custom_group_user','authentication.roles.custom_group_user.name','authentication.roles.custom_group_user.description',1684139050893,1684139055757,0,'',0,0); -INSERT INTO `Roles` VALUES ('jfuzyuzguiysmcb1fmtfnme6sc','system_admin','authentication.roles.global_admin.name','authentication.roles.global_admin.description',1684139050846,1684139055764,0,' sysconsole_read_experimental_feature_flags run_view import_team delete_emojis playbook_public_manage_members manage_team sysconsole_read_site_posts list_users_without_team get_saml_cert_status sysconsole_write_experimental_features sysconsole_read_user_management_users run_manage_members join_public_channels restore_custom_group remove_others_reactions create_compliance_export_job sysconsole_read_environment_performance_monitoring sysconsole_write_integrations_cors test_elasticsearch remove_reaction read_public_channel manage_roles sysconsole_write_environment_push_notification_server create_custom_group sysconsole_write_environment_database create_ldap_sync_job sysconsole_write_integrations_integration_management sysconsole_write_site_notices create_post_public use_group_mentions sysconsole_write_compliance_custom_terms_of_service create_post_ephemeral sysconsole_read_products_boards sysconsole_write_integrations_gif sysconsole_write_environment_performance_monitoring manage_license_information get_logs read_data_retention_job add_saml_idp_cert sysconsole_write_authentication_signup manage_slash_commands download_compliance_export_result invalidate_email_invite add_saml_public_cert read_other_users_teams use_channel_mentions sysconsole_read_environment_logging sysconsole_read_compliance_compliance_monitoring manage_system assign_bot invalidate_caches manage_bots invite_guest sysconsole_read_compliance_data_retention_policy view_members purge_bleve_indexes sysconsole_read_site_announcement_banner sysconsole_read_user_management_channels create_group_channel sysconsole_read_site_notifications sysconsole_write_authentication_password create_elasticsearch_post_indexing_job playbook_private_make_public sysconsole_read_environment_developer manage_shared_channels sysconsole_read_reporting_server_logs sysconsole_read_compliance_compliance_export manage_others_slash_commands create_direct_channel demote_to_guest read_others_bots manage_team_roles sysconsole_write_about_edition_and_license run_create sysconsole_write_user_management_channels sysconsole_read_plugins delete_public_channel sysconsole_read_reporting_team_statistics playbook_public_make_private add_ldap_public_cert create_team sysconsole_read_authentication_openid create_post edit_brand manage_others_bots delete_others_posts use_slash_commands read_audits edit_post remove_saml_private_cert sysconsole_write_compliance_compliance_monitoring reload_config sysconsole_write_plugins sysconsole_read_user_management_groups playbook_private_view test_email playbook_private_create add_saml_private_cert sysconsole_read_site_users_and_teams manage_private_channel_members remove_ldap_public_cert create_post_bleve_indexes_job manage_public_channel_members promote_guest delete_post playbook_private_manage_properties sysconsole_write_experimental_feature_flags test_site_url manage_others_incoming_webhooks read_private_channel_groups sysconsole_read_site_public_links sysconsole_write_products_boards sysconsole_read_integrations_integration_management playbook_private_manage_roles edit_other_users sysconsole_write_compliance_compliance_export sysconsole_read_authentication_email sysconsole_write_site_public_links sysconsole_write_environment_session_lengths sysconsole_write_site_emoji remove_saml_idp_cert edit_others_posts sysconsole_read_site_notices create_private_channel sysconsole_write_environment_image_proxy list_public_teams sysconsole_read_authentication_password join_public_teams read_jobs sysconsole_write_authentication_email manage_private_channel_properties read_license_information sysconsole_read_authentication_ldap create_data_retention_job manage_oauth assign_system_admin_role remove_saml_public_cert sysconsole_write_environment_elasticsearch list_team_channels list_private_teams sysconsole_read_environment_web_server test_ldap convert_private_channel_to_public create_user_access_token sysconsole_write_user_management_groups read_user_access_token create_bot sysconsole_write_integrations_bot_accounts create_emojis sysconsole_write_reporting_server_logs manage_others_outgoing_webhooks sysconsole_read_user_management_permissions manage_secure_connections sysconsole_write_reporting_team_statistics manage_system_wide_oauth read_channel playbook_public_create playbook_public_manage_roles revoke_user_access_token get_analytics get_public_link sysconsole_write_authentication_mfa sysconsole_write_user_management_permissions read_elasticsearch_post_indexing_job delete_private_channel sysconsole_read_authentication_saml add_reaction sysconsole_write_site_notifications sysconsole_write_site_announcement_banner sysconsole_write_experimental_bleve view_team invite_user sysconsole_read_environment_push_notification_server manage_public_channel_properties sysconsole_read_reporting_site_statistics remove_user_from_team sysconsole_write_authentication_openid playbook_private_manage_members sysconsole_write_environment_rate_limiting sysconsole_write_site_customization sysconsole_read_integrations_cors sysconsole_write_environment_web_server delete_custom_group purge_elasticsearch_indexes add_user_to_team edit_custom_group sysconsole_write_environment_smtp read_public_channel_groups sysconsole_write_environment_logging sysconsole_read_site_emoji sysconsole_read_environment_file_storage sysconsole_write_user_management_users manage_custom_group_members sysconsole_read_about_edition_and_license sysconsole_read_site_file_sharing_and_downloads sysconsole_read_site_localization sysconsole_read_integrations_gif sysconsole_read_environment_elasticsearch sysconsole_write_site_localization sysconsole_read_site_customization remove_ldap_private_cert playbook_public_view read_compliance_export_job sysconsole_write_billing sysconsole_write_user_management_teams join_private_teams sysconsole_write_site_users_and_teams sysconsole_write_site_file_sharing_and_downloads get_saml_metadata_from_idp read_elasticsearch_post_aggregation_job delete_others_emojis run_manage_properties sysconsole_read_environment_high_availability sysconsole_read_environment_rate_limiting create_public_channel sysconsole_read_environment_smtp manage_outgoing_webhooks sysconsole_write_environment_file_storage sysconsole_read_integrations_bot_accounts sysconsole_write_user_management_system_roles manage_jobs sysconsole_read_environment_image_proxy sysconsole_write_authentication_ldap sysconsole_read_environment_session_lengths playbook_public_manage_properties sysconsole_write_reporting_site_statistics upload_file sysconsole_read_environment_database sysconsole_read_experimental_features sysconsole_read_experimental_bleve sysconsole_write_authentication_guest_access read_ldap_sync_job recycle_database_connections sysconsole_read_authentication_mfa sysconsole_read_compliance_custom_terms_of_service manage_incoming_webhooks sysconsole_read_user_management_system_roles create_elasticsearch_post_aggregation_job convert_public_channel_to_private sysconsole_write_authentication_saml sysconsole_read_authentication_signup sysconsole_write_compliance_data_retention_policy read_bots test_s3 sysconsole_write_site_posts add_ldap_private_cert manage_channel_roles sysconsole_read_authentication_guest_access sysconsole_read_billing sysconsole_write_environment_developer sysconsole_read_user_management_teams read_deleted_posts sysconsole_write_environment_high_availability',1,1); -INSERT INTO `Roles` VALUES ('jh5f5efjm38ebdsypjutm1zjzr','system_manager','authentication.roles.system_manager.name','authentication.roles.system_manager.description',1684139050838,1684139055771,0,' sysconsole_write_site_public_links sysconsole_write_integrations_bot_accounts test_elasticsearch sysconsole_write_site_notices sysconsole_write_site_customization sysconsole_read_environment_developer sysconsole_read_authentication_password sysconsole_write_environment_logging sysconsole_write_environment_session_lengths sysconsole_read_products_boards manage_team test_email sysconsole_read_environment_logging sysconsole_write_site_localization get_logs read_ldap_sync_job read_license_information list_public_teams sysconsole_read_environment_rate_limiting sysconsole_write_user_management_groups join_public_teams join_private_teams sysconsole_read_site_emoji manage_team_roles sysconsole_read_user_management_groups sysconsole_write_integrations_gif sysconsole_write_environment_web_server sysconsole_read_site_announcement_banner sysconsole_write_user_management_teams sysconsole_write_site_notifications invalidate_caches sysconsole_write_site_announcement_banner test_site_url sysconsole_read_user_management_teams test_ldap sysconsole_read_site_posts sysconsole_write_site_file_sharing_and_downloads sysconsole_read_authentication_signup view_team recycle_database_connections sysconsole_write_environment_push_notification_server sysconsole_read_environment_session_lengths sysconsole_read_environment_smtp get_analytics sysconsole_read_site_notices sysconsole_read_user_management_permissions sysconsole_read_authentication_email purge_elasticsearch_indexes read_elasticsearch_post_indexing_job sysconsole_write_site_emoji convert_public_channel_to_private manage_private_channel_properties sysconsole_read_reporting_site_statistics read_elasticsearch_post_aggregation_job read_public_channel_groups create_elasticsearch_post_indexing_job sysconsole_write_integrations_cors manage_public_channel_members sysconsole_read_authentication_guest_access create_elasticsearch_post_aggregation_job sysconsole_write_environment_performance_monitoring sysconsole_write_products_boards sysconsole_write_environment_developer sysconsole_read_site_public_links sysconsole_write_user_management_permissions sysconsole_read_environment_push_notification_server sysconsole_write_environment_image_proxy sysconsole_write_site_users_and_teams sysconsole_read_site_file_sharing_and_downloads sysconsole_read_environment_performance_monitoring sysconsole_write_environment_smtp sysconsole_read_environment_elasticsearch delete_private_channel sysconsole_read_plugins sysconsole_read_site_users_and_teams sysconsole_read_environment_file_storage read_private_channel_groups read_public_channel sysconsole_read_site_localization sysconsole_write_environment_high_availability add_user_to_team sysconsole_write_integrations_integration_management sysconsole_read_reporting_team_statistics sysconsole_read_environment_image_proxy manage_private_channel_members sysconsole_read_authentication_mfa sysconsole_write_environment_file_storage reload_config sysconsole_read_authentication_openid sysconsole_write_environment_database sysconsole_read_environment_web_server sysconsole_write_environment_rate_limiting test_s3 remove_user_from_team list_private_teams read_channel sysconsole_read_authentication_saml edit_brand sysconsole_read_integrations_bot_accounts sysconsole_read_site_customization sysconsole_read_environment_database sysconsole_read_integrations_cors sysconsole_read_integrations_integration_management sysconsole_read_reporting_server_logs sysconsole_read_about_edition_and_license sysconsole_read_user_management_channels convert_private_channel_to_public sysconsole_write_site_posts sysconsole_write_environment_elasticsearch sysconsole_read_environment_high_availability sysconsole_read_authentication_ldap manage_public_channel_properties delete_public_channel sysconsole_read_site_notifications sysconsole_read_integrations_gif sysconsole_write_user_management_channels manage_channel_roles',0,1); -INSERT INTO `Roles` VALUES ('jsp8rgiy3tdwi8s3734gqn1t8a','team_admin','authentication.roles.team_admin.name','authentication.roles.team_admin.description',1684139050825,1684139055777,0,' remove_reaction create_post playbook_private_manage_roles read_private_channel_groups manage_team_roles convert_private_channel_to_public import_team read_public_channel_groups delete_others_posts manage_private_channel_members manage_public_channel_members manage_others_slash_commands manage_others_incoming_webhooks manage_incoming_webhooks manage_channel_roles convert_public_channel_to_private add_reaction manage_outgoing_webhooks manage_team use_group_mentions remove_user_from_team manage_others_outgoing_webhooks playbook_public_manage_roles use_channel_mentions manage_slash_commands delete_post',1,1); -INSERT INTO `Roles` VALUES ('jy7kh7nt8pbeuq3y9xnk99ofhy','playbook_admin','authentication.roles.playbook_admin.name','authentication.roles.playbook_admin.description',1684139050831,1684139055783,0,' playbook_private_manage_properties playbook_public_make_private playbook_public_manage_members playbook_public_manage_roles playbook_public_manage_properties playbook_private_manage_members playbook_private_manage_roles',1,1); -INSERT INTO `Roles` VALUES ('kfsh3mwix7gf7nmbz9osxu7w3h','system_user_access_token','authentication.roles.system_user_access_token.name','authentication.roles.system_user_access_token.description',1684139050917,1684139055789,0,' read_user_access_token revoke_user_access_token create_user_access_token',0,1); -INSERT INTO `Roles` VALUES ('mg3ei79rwjbb9cisojazuetrer','channel_admin','authentication.roles.channel_admin.name','authentication.roles.channel_admin.description',1684139050812,1684139055795,0,' remove_reaction read_public_channel_groups add_reaction use_channel_mentions use_group_mentions manage_private_channel_members manage_public_channel_members manage_channel_roles read_private_channel_groups create_post',1,1); -INSERT INTO `Roles` VALUES ('nnt36qb6ebgx9jp4jjstmm4x8c','channel_guest','authentication.roles.channel_guest.name','authentication.roles.channel_guest.description',1684139050898,1684139055801,0,' use_slash_commands read_channel add_reaction remove_reaction upload_file edit_post create_post use_channel_mentions',1,1); -INSERT INTO `Roles` VALUES ('u61ohe941brj9rbwji51s4umpy','team_post_all_public','authentication.roles.team_post_all_public.name','authentication.roles.team_post_all_public.description',1684139050865,1684139055808,0,' create_post_public use_channel_mentions use_group_mentions',0,1); -INSERT INTO `Roles` VALUES ('u74k94nxqtri7q4mrkanrwj4ky','system_custom_group_admin','authentication.roles.system_custom_group_admin.name','authentication.roles.system_custom_group_admin.description',1684139050805,1684139055815,0,' edit_custom_group delete_custom_group restore_custom_group manage_custom_group_members create_custom_group',0,1); -INSERT INTO `Roles` VALUES ('u9kkc9q3hfnbzn7cqh1ekqxxzr','system_post_all','authentication.roles.system_post_all.name','authentication.roles.system_post_all.description',1684139050791,1684139055821,0,' use_channel_mentions use_group_mentions create_post',0,1); -INSERT INTO `Roles` VALUES ('w393gw6mfi8djnr1iak81zsz9e','channel_user','authentication.roles.channel_user.name','authentication.roles.channel_user.description',1684139050853,1684139055827,0,' manage_public_channel_properties remove_reaction use_channel_mentions delete_post manage_public_channel_members read_private_channel_groups delete_private_channel add_reaction use_slash_commands upload_file use_group_mentions read_public_channel_groups get_public_link manage_private_channel_members read_channel manage_private_channel_properties create_post edit_post delete_public_channel',1,1); -INSERT INTO `Roles` VALUES ('ww84ayxwipyg9eyrcz3ikffy9e','system_read_only_admin','authentication.roles.system_read_only_admin.name','authentication.roles.system_read_only_admin.description',1684139050889,1684139055833,0,' sysconsole_read_integrations_gif sysconsole_read_site_users_and_teams read_elasticsearch_post_aggregation_job list_private_teams sysconsole_read_user_management_channels read_channel get_logs sysconsole_read_reporting_site_statistics sysconsole_read_products_boards sysconsole_read_about_edition_and_license sysconsole_read_experimental_feature_flags sysconsole_read_site_customization read_other_users_teams read_license_information sysconsole_read_authentication_password read_audits sysconsole_read_integrations_bot_accounts view_team sysconsole_read_environment_smtp sysconsole_read_site_localization sysconsole_read_experimental_features sysconsole_read_compliance_compliance_export sysconsole_read_authentication_saml test_ldap read_private_channel_groups sysconsole_read_authentication_signup download_compliance_export_result sysconsole_read_compliance_compliance_monitoring sysconsole_read_reporting_server_logs sysconsole_read_authentication_mfa sysconsole_read_integrations_integration_management sysconsole_read_environment_database sysconsole_read_site_file_sharing_and_downloads sysconsole_read_environment_elasticsearch sysconsole_read_user_management_permissions sysconsole_read_site_announcement_banner sysconsole_read_site_posts sysconsole_read_reporting_team_statistics sysconsole_read_authentication_openid sysconsole_read_user_management_teams sysconsole_read_plugins list_public_teams sysconsole_read_experimental_bleve sysconsole_read_integrations_cors sysconsole_read_environment_push_notification_server sysconsole_read_site_notices read_data_retention_job read_public_channel sysconsole_read_compliance_custom_terms_of_service sysconsole_read_authentication_guest_access sysconsole_read_environment_session_lengths sysconsole_read_environment_performance_monitoring sysconsole_read_environment_file_storage sysconsole_read_environment_high_availability sysconsole_read_compliance_data_retention_policy sysconsole_read_site_public_links sysconsole_read_authentication_email sysconsole_read_environment_image_proxy read_ldap_sync_job sysconsole_read_site_notifications read_elasticsearch_post_indexing_job get_analytics sysconsole_read_user_management_users sysconsole_read_environment_web_server sysconsole_read_environment_logging sysconsole_read_site_emoji sysconsole_read_user_management_groups sysconsole_read_environment_developer sysconsole_read_environment_rate_limiting sysconsole_read_authentication_ldap read_public_channel_groups read_compliance_export_job',0,1); -INSERT INTO `Roles` VALUES ('wxi1n6jnp7yt9xxezd6xtg43nh','system_guest','authentication.roles.global_guest.name','authentication.roles.global_guest.description',1684139050871,1684139055839,0,' create_group_channel create_direct_channel',1,1); -INSERT INTO `Roles` VALUES ('zdz95ncqn38ijggoho6h3e4ghr','playbook_member','authentication.roles.playbook_member.name','authentication.roles.playbook_member.description',1684139050738,1684139055845,0,' playbook_private_view playbook_private_manage_members playbook_private_manage_properties run_create playbook_public_view playbook_public_manage_members playbook_public_manage_properties',1,1); -INSERT INTO `SidebarCategories` VALUES ('channels_jactwicuqb8bu8pau8mgjydzeo_35odngbgr7yw3bf13o8kg85ngh','jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh',10,'','channels','Channels',0,0); -INSERT INTO `SidebarCategories` VALUES ('channels_k8crtspa5bfadc6iu6m93p4orh_35odngbgr7yw3bf13o8kg85ngh','k8crtspa5bfadc6iu6m93p4orh','35odngbgr7yw3bf13o8kg85ngh',10,'','channels','Channels',0,0); -INSERT INTO `SidebarCategories` VALUES ('direct_messages_jactwicuqb8bu8pau8mgjydzeo_35odngbgr7yw3bf13o8kg85ngh','jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh',20,'recent','direct_messages','Direct Messages',0,0); -INSERT INTO `SidebarCategories` VALUES ('direct_messages_k8crtspa5bfadc6iu6m93p4orh_35odngbgr7yw3bf13o8kg85ngh','k8crtspa5bfadc6iu6m93p4orh','35odngbgr7yw3bf13o8kg85ngh',20,'recent','direct_messages','Direct Messages',0,0); -INSERT INTO `SidebarCategories` VALUES ('favorites_jactwicuqb8bu8pau8mgjydzeo_35odngbgr7yw3bf13o8kg85ngh','jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh',0,'','favorites','Favorites',0,0); -INSERT INTO `SidebarCategories` VALUES ('favorites_k8crtspa5bfadc6iu6m93p4orh_35odngbgr7yw3bf13o8kg85ngh','k8crtspa5bfadc6iu6m93p4orh','35odngbgr7yw3bf13o8kg85ngh',0,'','favorites','Favorites',0,0); -INSERT INTO `Status` VALUES ('jactwicuqb8bu8pau8mgjydzeo','away',0,1684387416906,0,''); -INSERT INTO `Status` VALUES ('k8crtspa5bfadc6iu6m93p4orh','offline',0,1684153509983,0,''); -INSERT INTO `Systems` VALUES ('about_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('add_billing_permissions','true'); -INSERT INTO `Systems` VALUES ('add_bot_permissions','true'); -INSERT INTO `Systems` VALUES ('add_convert_channel_permissions','true'); -INSERT INTO `Systems` VALUES ('add_manage_guests_permissions','true'); -INSERT INTO `Systems` VALUES ('add_system_console_permissions','true'); -INSERT INTO `Systems` VALUES ('add_system_roles_permissions','true'); -INSERT INTO `Systems` VALUES ('add_use_group_mentions_permission','true'); -INSERT INTO `Systems` VALUES ('AdvancedPermissionsMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('apply_channel_manage_delete_to_channel_user','true'); -INSERT INTO `Systems` VALUES ('AsymmetricSigningKey','{\"ecdsa_key\":{\"curve\":\"P-256\",\"x\":39885688012791743430902392044132023131306318630717482885626462746284368676562,\"y\":56732587617706431314588083882840694296577699304576161589544790090711522351963,\"d\":61158628144358852948138055426802208098608450055237759428816151150343005223320}}'); -INSERT INTO `Systems` VALUES ('authentication_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('channel_moderations_permissions','true'); -INSERT INTO `Systems` VALUES ('compliance_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('ContentExtractionConfigDefaultTrueMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('CRTChannelMembershipCountsMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('CRTThreadCountsAndUnreadsMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('CustomGroupAdminRoleCreationMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('custom_groups_permissions','true'); -INSERT INTO `Systems` VALUES ('custom_groups_permission_restore','true'); -INSERT INTO `Systems` VALUES ('DiagnosticId','6nz6d7fp5tdcbrfui1xnubzr8o'); -INSERT INTO `Systems` VALUES ('download_compliance_export_results','true'); -INSERT INTO `Systems` VALUES ('EmojisPermissionsMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('emoji_permissions_split','true'); -INSERT INTO `Systems` VALUES ('environment_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('experimental_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('FirstServerRunTimestamp','1684139050764'); -INSERT INTO `Systems` VALUES ('GuestRolesCreationMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('InstallationDate','1684139058969'); -INSERT INTO `Systems` VALUES ('integrations_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('LastSecurityTime','1684386571805'); -INSERT INTO `Systems` VALUES ('list_join_public_private_teams','true'); -INSERT INTO `Systems` VALUES ('manage_secure_connections_permissions','true'); -INSERT INTO `Systems` VALUES ('manage_shared_channel_permissions','true'); -INSERT INTO `Systems` VALUES ('migration_advanced_permissions_phase_2','true'); -INSERT INTO `Systems` VALUES ('PlaybookRolesCreationMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('playbooks_manage_roles','true'); -INSERT INTO `Systems` VALUES ('playbooks_permissions','true'); -INSERT INTO `Systems` VALUES ('PostActionCookieSecret','{\"key\":\"YotujW0OeUnuIjCwfomw+BuaoB63KtxoBb6NLLrlzIA=\"}'); -INSERT INTO `Systems` VALUES ('PostPriorityConfigDefaultTrueMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('products_boards','true'); -INSERT INTO `Systems` VALUES ('RemainingSchemaMigrations','true'); -INSERT INTO `Systems` VALUES ('remove_channel_manage_delete_from_team_user','true'); -INSERT INTO `Systems` VALUES ('remove_permanent_delete_user','true'); -INSERT INTO `Systems` VALUES ('reporting_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('site_subsection_permissions','true'); -INSERT INTO `Systems` VALUES ('SystemConsoleRolesCreationMigrationComplete','true'); -INSERT INTO `Systems` VALUES ('test_email_ancillary_permission','true'); -INSERT INTO `Systems` VALUES ('view_members_new_permission','true'); -INSERT INTO `Systems` VALUES ('webhook_permissions_split','true'); -INSERT INTO `TeamMembers` VALUES ('35odngbgr7yw3bf13o8kg85ngh','jactwicuqb8bu8pau8mgjydzeo','',0,1,1,0,1684139715876); -INSERT INTO `TeamMembers` VALUES ('35odngbgr7yw3bf13o8kg85ngh','k8crtspa5bfadc6iu6m93p4orh','',0,1,0,0,1684146863252); -INSERT INTO `Teams` VALUES ('35odngbgr7yw3bf13o8kg85ngh',1684139715847,1684139715847,0,'nautobot-test-team','nautobot-test-team','','admin@example.com','O','','','p6beof3e5fyxzgboo3ana6ra6c',NULL,0,0,NULL,0); -INSERT INTO `UserAccessTokens` VALUES ('pjz3u1ru3jfkt8ib5fz4sraybw','5qsffxoapt883qfdygbdgf17jy','k8crtspa5bfadc6iu6m93p4orh','nautobot',1); -INSERT INTO `Users` VALUES ('6g9zjk1d7brz8rqiypd9kypn5c',1684139058969,1684139059003,0,'feedbackbot','',NULL,'','feedbackbot@localhost',0,'','Feedbackbot','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139058969,1684139059003,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('d6eb3jh8iprzpxim14w9hkopbr',1684139114820,1684139114820,0,'boards','',NULL,'','boards@localhost',0,'','Boards','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139114820,0,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('dk8nggnjtt8yipcbmuqem4rfkc',1684139700005,1684139700005,0,'system-bot','',NULL,'','system-bot@localhost',0,'','System','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139700005,0,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('jactwicuqb8bu8pau8mgjydzeo',1684139698424,1684251561795,0,'admin','$2a$10$FA7sexy5OipYSWLIYaKTQOHrgRCFSUkxoGRA1X4nXvX3oSL2dEMoG',NULL,'','admin@example.com',0,'','','','system_admin system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684251561795,0,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('k8crtspa5bfadc6iu6m93p4orh',1684146025502,1684146863269,0,'nautobot-test-bot','',NULL,'','nautobot-test-bot@localhost',0,'','Nautobot Test Bot','','system_user system_admin',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684146025502,0,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('o113xcgte78kpezuouwcr6abpo',1684139059883,1684139059883,0,'calls','',NULL,'','calls@localhost',0,'','Calls','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139059883,0,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('ozpddc4xxi85tmrwaqsjmgw1kc',1684139059816,1684387226829,0,'playbooks','',NULL,'','playbooks@localhost',0,'','Playbooks','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139059816,1684387226829,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `Users` VALUES ('qmaiqbz1e3fo8qz1nsmkhqbznh',1684139059446,1684387226467,0,'appsbot','',NULL,'','appsbot@localhost',0,'','Mattermost Apps','','system_user',0,'{}','{\"push\": \"mention\", \"email\": \"true\", \"channel\": \"true\", \"desktop\": \"mention\", \"comments\": \"never\", \"first_name\": \"false\", \"push_status\": \"away\", \"mention_keys\": \"\", \"push_threads\": \"all\", \"desktop_sound\": \"true\", \"email_threads\": \"all\", \"desktop_threads\": \"all\"}',1684139059446,1684387226467,0,'en',0,'','','{\"manualTimezone\": \"\", \"automaticTimezone\": \"\", \"useAutomaticTimezone\": \"true\"}',NULL); -INSERT INTO `db_migrations` VALUES (1,'create_teams'); -INSERT INTO `db_migrations` VALUES (2,'create_team_members'); -INSERT INTO `db_migrations` VALUES (3,'create_cluster_discovery'); -INSERT INTO `db_migrations` VALUES (4,'create_command_webhooks'); -INSERT INTO `db_migrations` VALUES (5,'create_compliances'); -INSERT INTO `db_migrations` VALUES (6,'create_emojis'); -INSERT INTO `db_migrations` VALUES (7,'create_user_groups'); -INSERT INTO `db_migrations` VALUES (8,'create_group_members'); -INSERT INTO `db_migrations` VALUES (9,'create_group_teams'); -INSERT INTO `db_migrations` VALUES (10,'create_group_channels'); -INSERT INTO `db_migrations` VALUES (11,'create_link_metadata'); -INSERT INTO `db_migrations` VALUES (12,'create_commands'); -INSERT INTO `db_migrations` VALUES (13,'create_incoming_webhooks'); -INSERT INTO `db_migrations` VALUES (14,'create_outgoing_webhooks'); -INSERT INTO `db_migrations` VALUES (15,'create_systems'); -INSERT INTO `db_migrations` VALUES (16,'create_reactions'); -INSERT INTO `db_migrations` VALUES (17,'create_roles'); -INSERT INTO `db_migrations` VALUES (18,'create_schemes'); -INSERT INTO `db_migrations` VALUES (19,'create_licenses'); -INSERT INTO `db_migrations` VALUES (20,'create_posts'); -INSERT INTO `db_migrations` VALUES (21,'create_product_notice_view_state'); -INSERT INTO `db_migrations` VALUES (22,'create_sessions'); -INSERT INTO `db_migrations` VALUES (23,'create_terms_of_service'); -INSERT INTO `db_migrations` VALUES (24,'create_audits'); -INSERT INTO `db_migrations` VALUES (25,'create_oauth_access_data'); -INSERT INTO `db_migrations` VALUES (26,'create_preferences'); -INSERT INTO `db_migrations` VALUES (27,'create_status'); -INSERT INTO `db_migrations` VALUES (28,'create_tokens'); -INSERT INTO `db_migrations` VALUES (29,'create_bots'); -INSERT INTO `db_migrations` VALUES (30,'create_user_access_tokens'); -INSERT INTO `db_migrations` VALUES (31,'create_remote_clusters'); -INSERT INTO `db_migrations` VALUES (32,'create_sharedchannels'); -INSERT INTO `db_migrations` VALUES (33,'create_sidebar_channels'); -INSERT INTO `db_migrations` VALUES (34,'create_oauthauthdata'); -INSERT INTO `db_migrations` VALUES (35,'create_sharedchannelattachments'); -INSERT INTO `db_migrations` VALUES (36,'create_sharedchannelusers'); -INSERT INTO `db_migrations` VALUES (37,'create_sharedchannelremotes'); -INSERT INTO `db_migrations` VALUES (38,'create_jobs'); -INSERT INTO `db_migrations` VALUES (39,'create_channel_member_history'); -INSERT INTO `db_migrations` VALUES (40,'create_sidebar_categories'); -INSERT INTO `db_migrations` VALUES (41,'create_upload_sessions'); -INSERT INTO `db_migrations` VALUES (42,'create_threads'); -INSERT INTO `db_migrations` VALUES (43,'thread_memberships'); -INSERT INTO `db_migrations` VALUES (44,'create_user_terms_of_service'); -INSERT INTO `db_migrations` VALUES (45,'create_plugin_key_value_store'); -INSERT INTO `db_migrations` VALUES (46,'create_users'); -INSERT INTO `db_migrations` VALUES (47,'create_file_info'); -INSERT INTO `db_migrations` VALUES (48,'create_oauth_apps'); -INSERT INTO `db_migrations` VALUES (49,'create_channels'); -INSERT INTO `db_migrations` VALUES (50,'create_channelmembers'); -INSERT INTO `db_migrations` VALUES (51,'create_msg_root_count'); -INSERT INTO `db_migrations` VALUES (52,'create_public_channels'); -INSERT INTO `db_migrations` VALUES (53,'create_retention_policies'); -INSERT INTO `db_migrations` VALUES (54,'create_crt_channelmembership_count'); -INSERT INTO `db_migrations` VALUES (55,'create_crt_thread_count_and_unreads'); -INSERT INTO `db_migrations` VALUES (56,'upgrade_channels_v6.0'); -INSERT INTO `db_migrations` VALUES (57,'upgrade_command_webhooks_v6.0'); -INSERT INTO `db_migrations` VALUES (58,'upgrade_channelmembers_v6.0'); -INSERT INTO `db_migrations` VALUES (59,'upgrade_users_v6.0'); -INSERT INTO `db_migrations` VALUES (60,'upgrade_jobs_v6.0'); -INSERT INTO `db_migrations` VALUES (61,'upgrade_link_metadata_v6.0'); -INSERT INTO `db_migrations` VALUES (62,'upgrade_sessions_v6.0'); -INSERT INTO `db_migrations` VALUES (63,'upgrade_threads_v6.0'); -INSERT INTO `db_migrations` VALUES (64,'upgrade_status_v6.0'); -INSERT INTO `db_migrations` VALUES (65,'upgrade_groupchannels_v6.0'); -INSERT INTO `db_migrations` VALUES (66,'upgrade_posts_v6.0'); -INSERT INTO `db_migrations` VALUES (67,'upgrade_channelmembers_v6.1'); -INSERT INTO `db_migrations` VALUES (68,'upgrade_teammembers_v6.1'); -INSERT INTO `db_migrations` VALUES (69,'upgrade_jobs_v6.1'); -INSERT INTO `db_migrations` VALUES (70,'upgrade_cte_v6.1'); -INSERT INTO `db_migrations` VALUES (71,'upgrade_sessions_v6.1'); -INSERT INTO `db_migrations` VALUES (72,'upgrade_schemes_v6.3'); -INSERT INTO `db_migrations` VALUES (73,'upgrade_plugin_key_value_store_v6.3'); -INSERT INTO `db_migrations` VALUES (74,'upgrade_users_v6.3'); -INSERT INTO `db_migrations` VALUES (75,'alter_upload_sessions_index'); -INSERT INTO `db_migrations` VALUES (76,'upgrade_lastrootpostat'); -INSERT INTO `db_migrations` VALUES (77,'upgrade_users_v6.5'); -INSERT INTO `db_migrations` VALUES (78,'create_oauth_mattermost_app_id'); -INSERT INTO `db_migrations` VALUES (79,'usergroups_displayname_index'); -INSERT INTO `db_migrations` VALUES (80,'posts_createat_id'); -INSERT INTO `db_migrations` VALUES (81,'threads_deleteat'); -INSERT INTO `db_migrations` VALUES (82,'upgrade_oauth_mattermost_app_id'); -INSERT INTO `db_migrations` VALUES (83,'threads_threaddeleteat'); -INSERT INTO `db_migrations` VALUES (84,'recent_searches'); -INSERT INTO `db_migrations` VALUES (85,'fileinfo_add_archived_column'); -INSERT INTO `db_migrations` VALUES (86,'add_cloud_limits_archived'); -INSERT INTO `db_migrations` VALUES (87,'sidebar_categories_index'); -INSERT INTO `db_migrations` VALUES (88,'remaining_migrations'); -INSERT INTO `db_migrations` VALUES (89,'add-channelid-to-reaction'); -INSERT INTO `db_migrations` VALUES (90,'create_enums'); -INSERT INTO `db_migrations` VALUES (91,'create_post_reminder'); -INSERT INTO `db_migrations` VALUES (92,'add_createat_to_teammembers'); -INSERT INTO `db_migrations` VALUES (93,'notify_admin'); -INSERT INTO `db_migrations` VALUES (94,'threads_teamid'); -INSERT INTO `db_migrations` VALUES (95,'remove_posts_parentid'); -INSERT INTO `db_migrations` VALUES (96,'threads_threadteamid'); -INSERT INTO `db_migrations` VALUES (97,'create_posts_priority'); -INSERT INTO `db_migrations` VALUES (98,'create_post_acknowledgements'); -INSERT INTO `db_migrations` VALUES (99,'create_drafts'); -INSERT INTO `db_migrations` VALUES (100,'add_draft_priority_column'); -INSERT INTO `db_migrations` VALUES (101,'create_true_up_review_history'); -INSERT INTO `db_migrations` VALUES (102,'posts_originalid_index'); -INSERT INTO `db_migrations` VALUES (103,'add_sentat_to_notifyadmin'); -INSERT INTO `db_migrations` VALUES (104,'upgrade_notifyadmin'); -INSERT INTO `db_migrations` VALUES (105,'remove_tokens'); -INSERT INTO `focalboard_schema_migrations` VALUES (1,'init'); -INSERT INTO `focalboard_schema_migrations` VALUES (2,'system_settings_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (3,'blocks_rootid'); -INSERT INTO `focalboard_schema_migrations` VALUES (4,'auth_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (5,'blocks_modifiedby'); -INSERT INTO `focalboard_schema_migrations` VALUES (6,'sharing_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (7,'workspaces_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (8,'teams'); -INSERT INTO `focalboard_schema_migrations` VALUES (9,'blocks_history'); -INSERT INTO `focalboard_schema_migrations` VALUES (10,'blocks_created_by'); -INSERT INTO `focalboard_schema_migrations` VALUES (11,'match_collation'); -INSERT INTO `focalboard_schema_migrations` VALUES (12,'match_column_collation'); -INSERT INTO `focalboard_schema_migrations` VALUES (13,'millisecond_timestamps'); -INSERT INTO `focalboard_schema_migrations` VALUES (14,'add_not_null_constraint'); -INSERT INTO `focalboard_schema_migrations` VALUES (15,'blocks_history_no_nulls'); -INSERT INTO `focalboard_schema_migrations` VALUES (16,'subscriptions_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (17,'add_file_info'); -INSERT INTO `focalboard_schema_migrations` VALUES (18,'add_teams_and_boards'); -INSERT INTO `focalboard_schema_migrations` VALUES (19,'populate_categories'); -INSERT INTO `focalboard_schema_migrations` VALUES (20,'populate_category_blocks'); -INSERT INTO `focalboard_schema_migrations` VALUES (21,'create_boards_members_history'); -INSERT INTO `focalboard_schema_migrations` VALUES (22,'create_default_board_role'); -INSERT INTO `focalboard_schema_migrations` VALUES (23,'persist_category_collapsed_state'); -INSERT INTO `focalboard_schema_migrations` VALUES (24,'mark_existsing_categories_collapsed'); -INSERT INTO `focalboard_schema_migrations` VALUES (25,'indexes_update'); -INSERT INTO `focalboard_schema_migrations` VALUES (26,'create_preferences_table'); -INSERT INTO `focalboard_schema_migrations` VALUES (27,'migrate_user_props_to_preferences'); -INSERT INTO `focalboard_schema_migrations` VALUES (28,'remove_template_channel_link'); -INSERT INTO `focalboard_schema_migrations` VALUES (29,'add_category_type_field'); -INSERT INTO `focalboard_schema_migrations` VALUES (30,'add_category_sort_order'); -INSERT INTO `focalboard_schema_migrations` VALUES (31,'add_category_boards_sort_order'); -INSERT INTO `focalboard_schema_migrations` VALUES (32,'move_boards_category_to_end'); -INSERT INTO `focalboard_system_settings` VALUES ('CategoryUuidIdMigrationComplete','true'); -INSERT INTO `focalboard_system_settings` VALUES ('DeletedMembershipBoardsMigrationComplete','true'); -INSERT INTO `focalboard_system_settings` VALUES ('TeamLessBoardsMigrationComplete','true'); -INSERT INTO `focalboard_system_settings` VALUES ('UniqueIDsMigrationComplete','true'); diff --git a/development/mattermost/nautobot_bootstrap.py b/development/mattermost/nautobot_bootstrap.py index ee0b79e9..bdd6462c 100644 --- a/development/mattermost/nautobot_bootstrap.py +++ b/development/mattermost/nautobot_bootstrap.py @@ -27,15 +27,16 @@ # The following tokens are for the development only and safe to store in the repo. _COMMAND_TOKENS = { - "aci": "tc1u8wbh53fwxxdkhswbmu9wsa", # nosec - "ansible": "c7udax974iymjkmoyhi1a11cpy", # nosec - "clear": "p7phuwhpaiddjxqf8c1hnw33yh", # nosec - "cloudvision": "pxannsh78iyhbm8fumz8mxk9ih", # nosec - "grafana": "o1yiadnpifbzddt3umcedeypdr", # nosec - "ipfabric": "uqydyxkx4tykinw5z5u9dany1o", # nosec - "meraki": "t9irqwjni3dozf3yx6tzak7k3w", # nosec - "nautobot": "rmdpfdjhnpg988e7ujzyom4euh", # nosec - "panorama": "6nf5cmz1ft8bdfykz46cs5pofo", # nosec + "aci": "b9wrs7paz7fi5ragz9uurwd9fa", # nosec + "ansible": "4hz941bgtpde9g75sesdp7tp1h", # nosec + "clear": "u7p1an973bd1jqg75i3y7pxj7y", # nosec + "cloudvision": "71o3ku7jwjyxup6biu1way1h5y", # nosec + "grafana": "3wxwh3m8mjrzxr11psersqkwue", # nosec + "ipfabric": "ppm316za33ritm3xgpobcmmgre", # nosec + "meraki": "11ix54hycjr4dmxcgw4d77qc4w", # nosec + "nautobot": "ncygprhkt3rrxr4rkytcaa7c9c", # nosec + "panorama": "fh1kbk45xtgm8r48jzr39ru1ww", # nosec + "nso": "j9bcga71hl4lreaczecen7i5dz", # nosec } for command, token in _COMMAND_TOKENS.items(): @@ -48,7 +49,7 @@ with contextlib.suppress(ObjectDoesNotExist): admin = User.objects.get(name="admin") ChatOpsAccountLink.objects.update_or_create( - user_id="jactwicuqb8bu8pau8mgjydzeo", + user_id="w7uyhzuo7fnfueen6og9cxmn9h", platform=PlatformChoices.MATTERMOST, defaults={"nautobot_user": admin}, ) diff --git a/development/nautobot_config.py b/development/nautobot_config.py index c913a18f..825ea553 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -2,9 +2,24 @@ import os import sys -from nautobot.core.settings import * # noqa: F401,F403 pylint: disable=wildcard-import,unused-wildcard-import +from nautobot.core.settings import * # noqa: F403 # pylint: disable=wildcard-import,unused-wildcard-import from nautobot.core.settings_funcs import is_truthy, parse_redis_connection +# +# Debug +# + +DEBUG = is_truthy(os.getenv("NAUTOBOT_DEBUG", False)) +_TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" + +if DEBUG and not _TESTING: + DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: True} + + if "debug_toolbar" not in INSTALLED_APPS: # noqa: F405 + INSTALLED_APPS.append("debug_toolbar") # noqa: F405 + if "debug_toolbar.middleware.DebugToolbarMiddleware" not in MIDDLEWARE: # noqa: F405 + MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware") # noqa: F405 + # # Misc. settings # @@ -12,6 +27,9 @@ ALLOWED_HOSTS = os.getenv("NAUTOBOT_ALLOWED_HOSTS", "").split(" ") SECRET_KEY = os.getenv("NAUTOBOT_SECRET_KEY", "") +# +# Database +# nautobot_db_engine = os.getenv("NAUTOBOT_DB_ENGINE", "django.db.backends.postgresql") default_db_settings = { @@ -41,18 +59,25 @@ DATABASES["default"]["OPTIONS"] = {"charset": "utf8mb4"} # -# Debug +# Redis # -DEBUG = True - -# Django Debug Toolbar -DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} +# The django-redis cache is used to establish concurrent locks using Redis. +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": parse_redis_connection(redis_database=0), + "TIMEOUT": 300, + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + }, + } +} -if DEBUG and "debug_toolbar" not in INSTALLED_APPS: # noqa: F405 - INSTALLED_APPS.append("debug_toolbar") # noqa: F405 -if DEBUG and "debug_toolbar.middleware.DebugToolbarMiddleware" not in MIDDLEWARE: # noqa: F405 - MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware") # noqa: F405 +# +# Celery settings are not defined here because they can be overloaded with +# environment variables. By default they use `CACHES["default"]["LOCATION"]`. +# # # Logging @@ -60,20 +85,18 @@ LOG_LEVEL = "DEBUG" if DEBUG else "INFO" -TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" - # Verbose logging during normal development operation, but quiet logging during unit test execution -if not TESTING: +if not _TESTING: LOGGING = { "version": 1, "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", }, }, @@ -99,44 +122,17 @@ } # -# Redis -# - -# The django-redis cache is used to establish concurrent locks using Redis. The -# django-rq settings will use the same instance/database by default. -# -# This "default" server is now used by RQ_QUEUES. -# >> See: nautobot.core.settings.RQ_QUEUES -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": parse_redis_connection(redis_database=0), - "TIMEOUT": 300, - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - }, - } -} - -# RQ_QUEUES is not set here because it just uses the default that gets imported -# up top via `from nautobot.core.settings import *`. - -# Redis Cacheops -CACHEOPS_REDIS = parse_redis_connection(redis_database=1) - -# -# Celery settings are not defined here because they can be overloaded with -# environment variables. By default they use `CACHES["default"]["LOCATION"]`. +# Apps # -# Enable installed plugins. Add the name of each plugin to the list. +# Enable installed Apps. Add the name of each App to the list. PLUGINS = [ "nautobot_capacity_metrics", "nautobot_chatops", ] -# Plugins configuration settings. These settings are used by various plugins that the user may have installed. -# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings. +# Apps configuration settings. These settings are used by various Apps that the user may have installed. +# Each key in the dictionary is the name of an installed App and its value is a dictionary of settings. PLUGINS_CONFIG = { "nautobot_chatops": { # = Common Settings ================== @@ -209,6 +205,12 @@ "panorama_host": os.environ.get("PANORAMA_HOST"), "panorama_password": os.environ.get("PANORAMA_PASSWORD"), "panorama_user": os.environ.get("PANORAMA_USER"), + # - Cisco NSO ------------------------ + "enable_nso": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_NSO")), + "nso_url": os.environ.get("NSO_URL"), + "nso_username": os.environ.get("NSO_USERNAME"), + "nso_password": os.environ.get("NSO_PASSWORD"), + "nso_request_timeout": os.environ.get("NSO_REQUEST_TIMEOUT", 60), }, } diff --git a/development/towncrier_template.j2 b/development/towncrier_template.j2 index b4d289b2..7010b057 100644 --- a/development/towncrier_template.j2 +++ b/development/towncrier_template.j2 @@ -1,5 +1,6 @@ + {% if render_title %} -## [v{{ versiondata.version }} ({{ versiondata.date }})](https://github.com/nautobot/nautobot-plugin-chatops/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() %} @@ -26,3 +27,4 @@ No significant changes. {% endif %} {% endfor %} + diff --git a/docs/admin/compatibility_matrix.md b/docs/admin/compatibility_matrix.md index bdea453b..c799cf60 100644 --- a/docs/admin/compatibility_matrix.md +++ b/docs/admin/compatibility_matrix.md @@ -4,7 +4,7 @@ Changes to the support of upstream Nautobot releases will be announced 1 minor o The **deprecation policy** will be announced within the [release notes](release_notes/index.md), and updated in the table below. There will be a `stable-.` branch that will be minimally maintained. Any security enhancements or major bugs in that branch will be supported for a limited time. -While that last supported version will not be strictly enforced via the `max_version` setting, any issues with an updated Nautobot supported version in a minor release will require raising a bug and fixing it in Nautobot core, with no fixes expected in this plugin. This allows the Chatops plugin the ability to quickly take advantage of the latest features in Nautobot. +While that last supported version will not be strictly enforced via the `max_version` setting, any issues with an updated Nautobot supported version in a minor release will require raising a bug and fixing it in Nautobot core, with no fixes expected in this app. This allows the Chatops app the ability to quickly take advantage of the latest features in Nautobot. | Chatops Version | Nautobot First Support Version | Nautobot Last Support Version | | --------------- | ------------------------------ | ----------------------------- | diff --git a/docs/admin/install/index.md b/docs/admin/install.md similarity index 79% rename from docs/admin/install/index.md rename to docs/admin/install.md index 4464a804..93e198d9 100644 --- a/docs/admin/install/index.md +++ b/docs/admin/install.md @@ -13,7 +13,7 @@ This guide outlines the process of enabling Nautobot ChatOps, which includes: - [Test Your Chatbot](#test-your-chatbot) - [Integrations Configuration](#integrations-configuration) -{% include-markdown '../../glossary.md' heading-offset=1 %} +{% include-markdown '../glossary.md' heading-offset=1 %} ## Prerequisites @@ -58,10 +58,10 @@ The `nautobot-chatops` package supports multiple chat platforms. Set up your chosen chat platform: -- [Mattermost](./mattermost_setup.md) -- [Microsoft Teams](./microsoft_teams_setup.md) -- [Slack](./slack_setup.md) -- [Cisco Webex](./webex_setup.md) +- [Mattermost](./platforms/mattermost.md) +- [Microsoft Teams](./platforms/microsoft_teams.md) +- [Slack](./platforms/slack.md) +- [Cisco Webex](./platforms/webex.md) ## Installation Guide @@ -71,7 +71,12 @@ 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`: +## 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 @@ -107,9 +112,8 @@ PLUGINS_CONFIG = { } ``` -+++3.0.0 - -Some configuration settings have now been added to the Nautobot Admin Config page. See [Nautobot Admin](https://docs.nautobot.com/projects/core/en/stable/configuration/optional-settings/?h=administr#administratively-configurable-settings) ++++ 3.0.0 + Some configuration settings have now been added to the Nautobot Admin Config page. See [Nautobot Admin](https://docs.nautobot.com/projects/core/en/stable/configuration/optional-settings/?h=administr#administratively-configurable-settings) ## Configuration Guide @@ -126,7 +130,7 @@ Adjust the App's behavior with the following settings: ## Granting Access to the Chat Platform {% - include-markdown '../../models/accessgrant.md' + include-markdown '../models/accessgrant.md' start='' heading-offset=1 %} @@ -134,7 +138,7 @@ Adjust the App's behavior with the following settings: ## Link Nautobot Account {% - include-markdown '../../models/chatopsaccountlink.md' + include-markdown '../models/chatopsaccountlink.md' start='' heading-offset=1 %} @@ -149,10 +153,11 @@ The `nautobot-chatops` package includes multiple integrations. Each requires ext Set up integrations using the specific guides: -- [Cisco ACI](./aci_setup.md) -- [AWX / Ansible Tower](./ansible_setup.md) -- [Arista CloudVision](./aristacv_setup.md) -- [Grafana](./grafana_setup.md) -- [IPFabric](./ipfabric_setup.md) -- [Cisco Meraki](./meraki_setup.md) -- [Palo Alto Panorama](./panorama_setup.md) +- [Cisco ACI](./integrations/aci.md) +- [AWX / Ansible Tower](./integrations/ansible.md) +- [Arista CloudVision](./integrations/aristacv.md) +- [Grafana](./integrations/grafana.md) +- [IPFabric](./integrations/ipfabric.md) +- [Cisco Meraki](./integrations/meraki.md) +- [Cisco NSO](./integrations/nso.md) +- [Palo Alto Panorama](./integrations/panorama.md) diff --git a/docs/admin/install/aci_setup.md b/docs/admin/integrations/aci.md similarity index 91% rename from docs/admin/install/aci_setup.md rename to docs/admin/integrations/aci.md index 80760f9b..9109b8d4 100644 --- a/docs/admin/install/aci_setup.md +++ b/docs/admin/integrations/aci.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up Cisco ACI integration with the Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[aci] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Command Setup -Create a top-level command named `aci` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `aci` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -66,7 +66,7 @@ When executing chat commands, you will be presented with a selection dialog cont ## Upgrading from `nautobot-plugin-chatops-aci` App !!! warning - When upgrading from `nautobot-plugin-chatops-aci` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-aci` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell diff --git a/docs/admin/install/ansible_setup.md b/docs/admin/integrations/ansible.md similarity index 91% rename from docs/admin/install/ansible_setup.md rename to docs/admin/integrations/ansible.md index 34b751b3..8be859e5 100644 --- a/docs/admin/install/ansible_setup.md +++ b/docs/admin/integrations/ansible.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up AWX / Ansible Tower integration Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[ansible] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Command Setup -Create a top-level command named `ansible` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `ansible` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -52,7 +52,7 @@ PLUGINS_CONFIG = { ## Upgrading from `nautobot-plugin-chatops-ansible` App !!! warning - When upgrading from `nautobot-plugin-chatops-ansible` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-ansible` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell diff --git a/docs/admin/install/aristacv_setup.md b/docs/admin/integrations/aristacv.md similarity index 92% rename from docs/admin/install/aristacv_setup.md rename to docs/admin/integrations/aristacv.md index b4d4f7cf..00ecd78e 100644 --- a/docs/admin/install/aristacv_setup.md +++ b/docs/admin/integrations/aristacv.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up Arista CloudVision integration Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[aristacv] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Command Setup -Create a top-level command named `aristacv` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `aristacv` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -22,7 +22,7 @@ You must define the following values in your `nautobot_config.py` file: | Configuration Setting | Mandatory? | Default | Available on Admin Config | | ---------------------- | ---------- | --------------------- | ------------------------- | -| `enable_aristacv` | **Yes** | False | Yes | +| `enable_cloudvision` | **Yes** | False | Yes | | `aristacv_cvaas_url` | No | "www.arista.io:443" | No | | `aristacv_cvaas_token` | No | None | No | | `aristacv_cvp_host` | No | None | No | @@ -39,7 +39,7 @@ PLUGINS = ["nautobot_chatops"] PLUGINS_CONFIG = { "nautobot_chatops": { ... - "enable_aristacv": True, + "enable_cloudvision": True, "aristacv_cvaas_url": os.environ.get("ARISTACV_CVAAS_URL"), "aristacv_cvaas_token": os.environ.get("ARISTACV_CVAAS_TOKEN"), "aristacv_cvp_host": os.environ.get("ARISTACV_CVP_HOST"), @@ -69,7 +69,7 @@ Once you have updated your environment file, restart both nautobot and nautobot- ## Upgrading from `nautobot-plugin-chatops-arista-cloudvision` App !!! warning - When upgrading from `nautobot-plugin-chatops-arista-cloudvision` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-arista-cloudvision` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell @@ -98,7 +98,7 @@ Once you have updated your environment file, restart both nautobot and nautobot- # } "nautobot_chatops": { # Enable Arista CloudVision integration - "enable_aristacv": True, + "enable_cloudvision": True, "aristacv_cvaas_url": os.environ.get("ARISTACV_CVAAS_URL"), "aristacv_cvaas_token": os.environ.get("ARISTACV_CVAAS_TOKEN"), "aristacv_cvp_host": os.environ.get("ARISTACV_CVP_HOST"), diff --git a/docs/admin/install/grafana_setup.md b/docs/admin/integrations/grafana.md similarity index 90% rename from docs/admin/install/grafana_setup.md rename to docs/admin/integrations/grafana.md index 87db5dcf..13f6f563 100644 --- a/docs/admin/install/grafana_setup.md +++ b/docs/admin/integrations/grafana.md @@ -6,18 +6,18 @@ This guide will walk you through steps to set up Grafana integration with the `n Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[grafana] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). - [Grafana](https://grafana.com/docs/grafana/latest/installation/) application installed and configured with dashboards and panels. - [Grafana Image Rendering Service](https://grafana.com/docs/grafana/latest/administration/image_rendering/) installed. -- [Grafana Image Rending Plugin for Grafana](https://grafana.com/grafana/plugins/grafana-image-renderer/) installed in your Grafana application. +- [Grafana Image Rending App for Grafana](https://grafana.com/grafana/plugins/grafana-image-renderer/) installed in your Grafana application. ## Command Setup -Create a top-level command named `grafana` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `grafana` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -62,7 +62,7 @@ PLUGINS_CONFIG = { ## Upgrading from `nautobot-plugin-chatops-grafana` App !!! warning - When upgrading from `nautobot-plugin-chatops-grafana` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-grafana` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell diff --git a/docs/admin/install/ipfabric_setup.md b/docs/admin/integrations/ipfabric.md similarity index 91% rename from docs/admin/install/ipfabric_setup.md rename to docs/admin/integrations/ipfabric.md index 66587436..f1b27bf3 100644 --- a/docs/admin/install/ipfabric_setup.md +++ b/docs/admin/integrations/ipfabric.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up IPFabric integration with the ` Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[ipfabric] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Version Matrix -Here is a compatibility matrix and the minimum versions required to run this plugin: +Here is a compatibility matrix and the minimum versions required to run this app: | IP Fabric | Python | Nautobot | chatops | chatops-ipfabric | [python-ipfabric](https://github.com/community-fabric/python-ipfabric) | [python-ipfabric-diagrams](https://github.com/community-fabric/python-ipfabric-diagrams) | |-----------|--------|----------|---------|------------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------| @@ -25,7 +25,7 @@ Here is a compatibility matrix and the minimum versions required to run this plu ## Command Setup -Create a top-level command named `ipfabric` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `ipfabric` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -59,7 +59,7 @@ PLUGINS_CONFIG = { ## Upgrading from `nautobot-plugin-chatops-ipfabric` App !!! warning - When upgrading from `nautobot-plugin-chatops-ipfabric` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-ipfabric` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell @@ -96,6 +96,6 @@ PLUGINS_CONFIG = { ``` !!! warning - Configuration keys for IPFabric integration are now lowercased, compared to the old plugin. + Configuration keys for IPFabric integration are now lowercased, compared to the old app. Environment variables for this integration are the same for both, old and new configuration. diff --git a/docs/admin/install/meraki_setup.md b/docs/admin/integrations/meraki.md similarity index 88% rename from docs/admin/install/meraki_setup.md rename to docs/admin/integrations/meraki.md index 464f1846..5988a1b2 100644 --- a/docs/admin/install/meraki_setup.md +++ b/docs/admin/integrations/meraki.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up Cisco Meraki integration with t Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[meraki] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Command Setup -Create a top-level command named `meraki` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `meraki` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -46,7 +46,7 @@ The alternative option is to set the environmental variable: ## Upgrading from `nautobot-plugin-chatops-meraki` App !!! warning - When upgrading from `nautobot-plugin-chatops-meraki` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-meraki` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell diff --git a/docs/admin/integrations/nso.md b/docs/admin/integrations/nso.md new file mode 100644 index 00000000..10e7a0e2 --- /dev/null +++ b/docs/admin/integrations/nso.md @@ -0,0 +1,56 @@ +# Cisco NSO Integration Setup + +This guide will walk you through steps to set up Cisco NSO integration with the `nautobot_chatops` App. + +## Prerequisites + +Before configuring the integration, please ensure the following: + +- `nautobot-chatops` App was installed. + ```shell + pip install nautobot-chatops + ``` +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). +- [Cisco NSO](https://developer.cisco.com/docs/nso-guides-6.2/#!installation/installation) application installed and configured. + +## Command Setup + +Create a top-level command named `nso` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). + +## Configuration + +You must define the following values in your `nautobot_config.py` file: + +| Configuration Setting | Mandatory? | Default | Notes | Available on Admin Config | +| --------------------- | ---------- | ------- | ----- | ------------------------- | +| `enable_nso` | **Yes** | False | Enable Cisco NSO integration. | Yes | +| `nso_url` | **Yes** | | Base url that the Cisco NSO application is hosted at. | No | +| `nso_username` | **Yes** | | Cisco NSO username. | No | +| `nso_password` | **Yes** | | Cisco NSO password. | No | +| `nso_request_timeout` | | 60 | Timeout of the API request to Cisco NSO. | No | + +Below is an example snippet from `development/nautobot_config.py` that demonstrates how to enable and configure Cisco NSO integration: + +```python +PLUGINS = ["nautobot_chatops"] + +PLUGINS_CONFIG = { + "nautobot_chatops": { + ... + "enable_nso": True, + "nso_url": os.environ.get("NSO_URL"), + "nso_username": os.environ.get("NSO_USERNAME"), + "nso_password": os.environ.get("NSO_PASSWORD"), + "nso_request_timeout": os.environ.get("NSO_REQUEST_TIMEOUT", 60), + } +} +``` + +## Computed Fields + +Optionally, a computed field might be created to display NSO status on a device details page. Please note, that it might delay the page load depending on NSO response time. + +![Add a new computed field](../../images/nso-07.png) +![Computed fields list](../../images/nso-08.png) +![Device details 1](../../images/nso-09.png) +![Device details 2](../../images/nso-10.png) \ No newline at end of file diff --git a/docs/admin/install/panorama_setup.md b/docs/admin/integrations/panorama.md similarity index 90% rename from docs/admin/install/panorama_setup.md rename to docs/admin/integrations/panorama.md index 202d726c..70be3ff4 100644 --- a/docs/admin/install/panorama_setup.md +++ b/docs/admin/integrations/panorama.md @@ -6,15 +6,15 @@ This guide will walk you through steps to set up Palo Alto Panorama integration Before configuring the integration, please ensure the following: -- `nautobot-chatops` App was [installed with integration extra dependencies](./index.md#installation-guide). +- `nautobot-chatops` App was [installed with integration extra dependencies](../install.md#installation-guide). ```shell pip install nautobot-chatops[panorama] ``` -- `nautobot-chatops` App is set up with at least one [enabled chat platform](./index.md#chat-platforms-configuration) and [tested](./index.md#test-your-chatbot). +- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot). ## Command Setup -Create a top-level command named `panorama` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](./index.md#chat-platforms-configuration). +Create a top-level command named `panorama` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration). ## Configuration @@ -46,7 +46,7 @@ PLUGINS_CONFIG = { ## Upgrading from `nautobot-plugin-chatops-panorama` App !!! warning - When upgrading from `nautobot-plugin-chatops-panorama` App, it's necessary to [avoid conflicts](index.md#potential-apps-conflicts). + When upgrading from `nautobot-plugin-chatops-panorama` App, it's necessary to [avoid conflicts](../install.md#potential-apps-conflicts). - Uninstall the old App: ```shell diff --git a/docs/admin/install/mattermost_setup.md b/docs/admin/platforms/mattermost.md similarity index 93% rename from docs/admin/install/mattermost_setup.md rename to docs/admin/platforms/mattermost.md index d437f6fb..e245a0a0 100644 --- a/docs/admin/install/mattermost_setup.md +++ b/docs/admin/platforms/mattermost.md @@ -25,7 +25,7 @@ - Copy the displayed url matching the Server you want to add the chatbot to. - Make sure to include the `http://` or `https://`. - If shown, make sure to include the port. Ex. `https://example.com:8065` -6. Proceed to the [Install Guide](index.md#Install-Guide) section. +6. Proceed to the [Install Guide](../install.md#Install-Guide) section. **Note:** For every Slash Command created for Mattermost, a separate token will be generated. @@ -39,4 +39,4 @@ ## General Chat Setup Instructions -See [admin_install](index.md) instructions here for general plugin setup instructions. +See [admin_install](../install.md) instructions here for general app setup instructions. diff --git a/docs/admin/install/microsoft_teams_setup.md b/docs/admin/platforms/microsoft_teams.md similarity index 91% rename from docs/admin/install/microsoft_teams_setup.md rename to docs/admin/platforms/microsoft_teams.md index beb16952..21912d60 100644 --- a/docs/admin/install/microsoft_teams_setup.md +++ b/docs/admin/platforms/microsoft_teams.md @@ -25,7 +25,7 @@ ## MS Teams Developer Portal 1. To deploy the bot to your team, log in to the [Microsoft Developer Portal](https://dev.teams.microsoft.com/) and select “Apps” from the left-hand menu. -2. Select "Import app" and upload the Nautobot ChatOps_ms_teams.zip file. It can be found from this directory or downloaded from GitHub [here](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/Nautobot_ms_teams.zip). **NOTE:** If you get an error stating “App package has errors”, you can ignore this and click on “Import” to complete the import. +2. Select "Import app" and upload the Nautobot ChatOps_ms_teams.zip file. It can be found from this directory or downloaded from GitHub [here](https://github.com/nautobot/nautobot-app-chatops/blob/develop/Nautobot_ms_teams.zip). **NOTE:** If you get an error stating “App package has errors”, you can ignore this and click on “Import” to complete the import. 3. Under section “Configure”, select “Basic Information”. Scroll to the bottom. Under “Application (client) ID, type in the value that you took note of above in Azure step 10. 4. Under section “Configure”, select “App features”. Select the triple dots (...) next to the “Bot” tile and select “Edit”. 5. On the Bot Edit page, under section “Identify your bot,” select “Enter a bot ID” and type in the same App ID value used above in step 4. Click Save. @@ -36,7 +36,7 @@ 1. In the Microsoft Teams client, select “Apps” from the sidebar to the left. 2. Select “Built for your org.” 3. Select the tile for the new Nautobot app. Click the blue “Add” button. -4. Proceed to the [Install Guide](index.md#Install-Guide) section. +4. Proceed to the [Install Guide](../install.md#Install-Guide) section. ## Nautobot Config @@ -53,4 +53,4 @@ Reference the [Setting Up Nautobot ChatOps With MSTeams Fall 2022](https://blog. ## General Chat Setup Instructions -See [admin_install](index.md) instructions here for general plugin setup instructions. +See [admin_install](../install.md) instructions here for general app setup instructions. diff --git a/docs/admin/install/slack_setup.md b/docs/admin/platforms/slack.md similarity index 91% rename from docs/admin/install/slack_setup.md rename to docs/admin/platforms/slack.md index 95c62921..5172134c 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/platforms/slack.md @@ -18,7 +18,7 @@ For now, take a mental note that in this section where we are configuring the Sl Example config snippet from `nautobot_config.py` for configuring ChatOps with Slack: ```python -# Enable installed plugins. Add the name of each plugin to the list. +# Enable installed apps. Add the name of each app to the list. PLUGINS = ["nautobot_chatops"] PLUGINS_CONFIG = { @@ -32,13 +32,13 @@ PLUGINS_CONFIG = { !!! info Optional: Logos rely on Slack being able to access the Static URL provided by Nautobot. If you are running - Slack in Socket Mode, Nautobot ChatOps Plugin will need you to specify where the static files are hosted. + Slack in Socket Mode, Nautobot ChatOps App will need you to specify where the static files are hosted. This is helpful for giving Slack access to only the server hosting Nautobot Static Files. To configure the static files host, use `slack_socket_static_host` ex. `slack_socket_static_host: 'https://example.com/static/'`. ## Connecting to Slack -The Nautobot ChatOps plugin supports two methods of communicating with Slack. +The Nautobot ChatOps app supports two methods of communicating with Slack. 1. Incoming Webhooks 2. Socket Mode @@ -48,7 +48,7 @@ The Nautobot ChatOps plugin supports two methods of communicating with Slack. ### Webhooks vs. Socket Mode -With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slack's cloud. The Slack servers then initiate a connection to the ChatOps plugin running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. +With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slack's cloud. The Slack servers then initiate a connection to the ChatOps app running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. ![Chatops Slack Webhooks Mode](../../images/chatops-slack-webhooks-mode.png) @@ -64,7 +64,7 @@ While there are sufficient ways of securing inbound API requests from the public 1. Log in to [https://api.slack.com/apps](https://api.slack.com/apps) and select "Create New App". Select "From an app manifest." 2. Select your preferred Slack workspace for your app. -3. In the window titled "Enter app manifest below," select the "YAML" formatting tab and copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) from this repo. Update the below settings, then click Next. +3. In the window titled "Enter app manifest below," select the "YAML" formatting tab and copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-app-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) from this repo. Update the below settings, then click Next. - On line 5, you can change the name of the Chatbot here. By default it is set to `Nautobot` - If using Socket mode: - On line 34, update `socket_mode_enabled` to `true` @@ -85,7 +85,7 @@ While there are sufficient ways of securing inbound API requests from the public 8. Under Settings --> Install App, copy the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. 9. Continue with below section "Post App-Creation Steps" -> **Optional:** You can configure the App Icon on the General --> Basic Information page. Under `App Icon`, select "Choose File." You can use the supplied icon [nautobot_chatops_icon.png](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_chatops_icon.png). +> **Optional:** You can configure the App Icon on the General --> Basic Information page. Under `App Icon`, select "Choose File." You can use the supplied icon [nautobot_chatops_icon.png](https://github.com/nautobot/nautobot-app-chatops/blob/develop/setup_files/nautobot_chatops_icon.png). ## Post App-Creation Steps @@ -138,7 +138,7 @@ PLUGINS_CONFIG = { ![slack integration invite](../../images/add_nautobot.png) -Once these steps are completed, you can proceed to the [Install Guide](index.md#Install-Guide) section. +Once these steps are completed, you can proceed to the [Install Guide](../install.md#Install-Guide) section. ## Configuring Multiple Chatbots in a Workspace @@ -149,7 +149,7 @@ They will be differentiated in the workspace using the `slack_slash_command_pref Here is an example `nautobot_config.py` for the first Nautobot chatbot implementation in the workspace. This chatbot will be called in the workspace using `/nautobot`. ```python -# Enable installed plugins. Add the name of each plugin to the list. +# Enable installed apps. Add the name of each app to the list. PLUGINS = ["nautobot_chatops"] PLUGINS_CONFIG = { @@ -166,7 +166,7 @@ This configuration explicitly configures the `slack_slash_command_prefix` key/va This chatbot will be called in the workspace using `/network2-nautobot`. ```python -# Enable installed plugins. Add the name of each plugin to the list. +# Enable installed apps. Add the name of each app to the list. PLUGINS = ["nautobot_chatops"] PLUGINS_CONFIG = { @@ -186,7 +186,7 @@ PLUGINS_CONFIG = { ## General Chat Setup Instructions -See [admin_install](index.md) instructions here for general plugin setup instructions. +See [admin_install](../install.md) instructions here for general app setup instructions. ## Startup Slack Sockets (Socket Mode) @@ -277,7 +277,7 @@ While this method is still possible, we recommend using the App Manifest method > `/network2-nautobot` command would have a `slack_slash_command_prefix` of `/network2-` 4. On the "Basic Information" page for your app, under "App Credentials", find the "Signing Secret" and click "Show". - You will need to configure this value for the plugin as the `slack_signing_secret` value, such as through an + You will need to configure this value for the app as the `slack_signing_secret` value, such as through an `.env` file. If this value is not correctly configured, the bot will be unable to validate that inbound notifications it receives have been properly signed by the Slack server. 5. In the sidebar to the left, select "OAuth & Permissions". @@ -295,7 +295,7 @@ While this method is still possible, we recommend using the App Manifest method - `mpim:read` - At the top of this page, select "Install App to Workspace" and confirm it. - There should now be a "Bot User OAuth Access Token" displayed, typically a string starting with `xoxb-`. - You will need to configure this value for the plugin as the `slack_api_token` value, either directly or through an + You will need to configure this value for the app as the `slack_api_token` value, either directly or through an `.env` file. If this value is not properly configured, the bot will be unable to send content to the user. 6. Returning to the "Basic Information" page for your app, under "Display Information", you can specify the name, description, icon, and accent/background color for the app. You can use the `nautobot_logo.png` from this diff --git a/docs/admin/install/webex_setup.md b/docs/admin/platforms/webex.md similarity index 91% rename from docs/admin/install/webex_setup.md rename to docs/admin/platforms/webex.md index 8d816ef3..0ba61e1d 100644 --- a/docs/admin/install/webex_setup.md +++ b/docs/admin/platforms/webex.md @@ -28,11 +28,11 @@ - secret: (enter a secret string that you don't mind having passed around as plaintext) - Change the `resource` to "attachmentActions" and run the API call again to create a second webhook. 4. Configure the `webex_signing_secret` in your `.creds.env` to match the Webhook secret string that you selected above. -5. Proceed to the [Installation Guide](index.md#Install-Guide) section. +5. Proceed to the [Installation Guide](../install.md#Install-Guide) section. ## Deprecation Warning -As of Nautobot ChatOps Plugin v2.0.0, there are the following changes: +As of Nautobot ChatOps App v2.0.0, there are the following changes: - The deprecated URL API path `webex_teams` has been removed. Please use `webex` as a substitute. - The use and deprecation warnings for the obsolete `webex_teams` App configuration entries have been removed. These entries include: @@ -50,7 +50,7 @@ As of Nautobot ChatOps Plugin v2.0.0, there are the following changes: } ``` -As of Nautobot ChatOps Plugin v1.4.0, the PLUGIN_CONFIG settings for Webex has changed to align with the official renaming of `Webex Teams` to `Webex`: +As of Nautobot ChatOps App v1.4.0, the PLUGIN_CONFIG settings for Webex has changed to align with the official renaming of `Webex Teams` to `Webex`: - `enable_webex_teams` is deprecated. Use `enable_webex` instead. - `webex_teams_token` is deprecated. Use `webex_token` instead. @@ -60,4 +60,4 @@ Both settings will currently work, however support for `enable_webex_teams`, `we ## General Chat Setup Instructions -See [admin_install](index.md) instructions here for general plugin setup instructions. +See [admin_install](../install.md) instructions here for general app setup instructions. diff --git a/docs/admin/release_notes/version_1.1.md b/docs/admin/release_notes/version_1.1.md index 4965d501..ba7b8b26 100644 --- a/docs/admin/release_notes/version_1.1.md +++ b/docs/admin/release_notes/version_1.1.md @@ -1,12 +1,12 @@ # v1.1 Release Notes -## [v1.1.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.1.0) +## [v1.1.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.1.0) ### What's New -- Slack handling of list items > 100 items, now including a `next` option in the drop down list to get more options [#10](https://github.com/nautobot/nautobot-plugin-chatops/pull/10) +- Slack handling of list items > 100 items, now including a `next` option in the drop down list to get more options [#10](https://github.com/nautobot/nautobot-app-chatops/pull/10) ### Bug Fixes -- Updated MS Teams Zip File [#29](https://github.com/nautobot/nautobot-plugin-chatops/pull/29) -- Fix connection filter ordering [#23](https://github.com/nautobot/nautobot-plugin-chatops/pull/23) +- Updated MS Teams Zip File [#29](https://github.com/nautobot/nautobot-app-chatops/pull/29) +- Fix connection filter ordering [#23](https://github.com/nautobot/nautobot-app-chatops/pull/23) diff --git a/docs/admin/release_notes/version_1.10.md b/docs/admin/release_notes/version_1.10.md index af7c313e..16037214 100644 --- a/docs/admin/release_notes/version_1.10.md +++ b/docs/admin/release_notes/version_1.10.md @@ -3,11 +3,11 @@ -## [v1.10.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.10.0) +## [v1.10.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.10.0) ### What's Changed * Drop official support for Nautobot <1.3.0 * Add support for Slack Socket Mode. -[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.9.1...v1.10.0) +[**Full Changelog**](https://github.com/nautobot/nautobot-app-chatops/compare/v1.9.1...v1.10.0) diff --git a/docs/admin/release_notes/version_1.11.md b/docs/admin/release_notes/version_1.11.md index 1bd87485..33834515 100644 --- a/docs/admin/release_notes/version_1.11.md +++ b/docs/admin/release_notes/version_1.11.md @@ -2,21 +2,21 @@ # v1.11 Release Notes -## [v1.11.0 (2023-03-11)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.11.0) +## [v1.11.0 (2023-03-11)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.11.0) ### Added -- [#166](https://github.com/nautobot/nautobot-plugin-chatops/issues/166) - Add documentation for contributing WebSocket Platform support. -- [#171](https://github.com/nautobot/nautobot-plugin-chatops/issues/171) - Enable Upstream Testing with Nautobot. -- [#182](https://github.com/nautobot/nautobot-plugin-chatops/issues/182) - Add option to limit Help prompt based on user Access Grants. +- [#166](https://github.com/nautobot/nautobot-app-chatops/issues/166) - Add documentation for contributing WebSocket Platform support. +- [#171](https://github.com/nautobot/nautobot-app-chatops/issues/171) - Enable Upstream Testing with Nautobot. +- [#182](https://github.com/nautobot/nautobot-app-chatops/issues/182) - Add option to limit Help prompt based on user Access Grants. ### Changed -- [#94](https://github.com/nautobot/nautobot-plugin-chatops/issues/94) - Clarified the description of Access Grants for Webex Teams. -- [#147](https://github.com/nautobot/nautobot-plugin-chatops/issues/147) - Left Align Column headers for tables to match the rows. -- [#173](https://github.com/nautobot/nautobot-plugin-chatops/issues/173) - Update App description. -- [#174](https://github.com/nautobot/nautobot-plugin-chatops/issues/174) - Change list views to use generic/object_list.html template. +- [#94](https://github.com/nautobot/nautobot-app-chatops/issues/94) - Clarified the description of Access Grants for Webex Teams. +- [#147](https://github.com/nautobot/nautobot-app-chatops/issues/147) - Left Align Column headers for tables to match the rows. +- [#173](https://github.com/nautobot/nautobot-app-chatops/issues/173) - Update App description. +- [#174](https://github.com/nautobot/nautobot-app-chatops/issues/174) - Change list views to use generic/object_list.html template. ### Removed -- [#138](https://github.com/nautobot/nautobot-plugin-chatops/issues/138) - Remove WEBEX_TOKEN warning when Webex is disabled. +- [#138](https://github.com/nautobot/nautobot-app-chatops/issues/138) - Remove WEBEX_TOKEN warning when Webex is disabled. diff --git a/docs/admin/release_notes/version_1.2.md b/docs/admin/release_notes/version_1.2.md index 14344158..8049818c 100644 --- a/docs/admin/release_notes/version_1.2.md +++ b/docs/admin/release_notes/version_1.2.md @@ -1,10 +1,10 @@ # v1.2 Release Notes -## [v1.2.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.2.0) +## [v1.2.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.2.0) - Replaces Slack client (slack_client) with Slack SDK (https://pypi.org/project/slack-sdk/) - This update does not require any code changes to the bots that leverage Slack. This does require the update of system requirements on installation. ### Fixes -[#2](https://github.com/nautobot/nautobot-plugin-chatops/issues/2) - Cisco WebEx error on content too large +[#2](https://github.com/nautobot/nautobot-app-chatops/issues/2) - Cisco WebEx error on content too large diff --git a/docs/admin/release_notes/version_1.3.md b/docs/admin/release_notes/version_1.3.md index 3e428eb7..3c6f50dd 100644 --- a/docs/admin/release_notes/version_1.3.md +++ b/docs/admin/release_notes/version_1.3.md @@ -1,6 +1,6 @@ # v1.3 Release Notes -## [v1.3.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.3.0) +## [v1.3.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.3.0) Updates to pyjwt to address concerns with other dependencies in the Nautobot ecosystem. @@ -9,8 +9,8 @@ Updates to pyjwt to address concerns with other dependencies in the Nautobot eco Updates pyjwt from 1.7.1 minimum to 2.1 Adds cryptography as separate requirement -## [v1.3.1](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.3.1) +## [v1.3.1](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.3.1) ### Fixes -- [#54)](https://github.com/nautobot/nautobot-plugin-chatops/pull/54) Reverted pinning of cryptography +- [#54)](https://github.com/nautobot/nautobot-app-chatops/pull/54) Reverted pinning of cryptography diff --git a/docs/admin/release_notes/version_1.4.md b/docs/admin/release_notes/version_1.4.md index cdb23dc0..61f9334b 100644 --- a/docs/admin/release_notes/version_1.4.md +++ b/docs/admin/release_notes/version_1.4.md @@ -1,19 +1,19 @@ # v1.4 Release Notes -## [v1.4.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.4.0) +## [v1.4.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.4.0) Updates Nautobot ChatOps name for Webex Teams to Webex. As part of Cisco's renaming of Webex Teams to just Webex, the underlying configuration was updated. ### Fixes -[#68)](https://github.com/nautobot/nautobot-plugin-chatops/pull/68) Correct var names for Nautobot -[#61)](https://github.com/nautobot/nautobot-plugin-chatops/pull/61) Mattermost sending interactive Dialog +[#68)](https://github.com/nautobot/nautobot-app-chatops/pull/68) Correct var names for Nautobot +[#61)](https://github.com/nautobot/nautobot-app-chatops/pull/61) Mattermost sending interactive Dialog ### Updates -[#63)](https://github.com/nautobot/nautobot-plugin-chatops/pull/63) Add additional Breadcrumbs -[#24](https://github.com/nautobot/nautobot-plugin-chatops/issues/24) Rename Webex Teams to Webex +[#63)](https://github.com/nautobot/nautobot-app-chatops/pull/63) Add additional Breadcrumbs +[#24](https://github.com/nautobot/nautobot-app-chatops/issues/24) Rename Webex Teams to Webex -## [v1.4.1](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.4.1) +## [v1.4.1](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.4.1) Minor update to better handle the versioning. This fixes an issue where the version number within Nautobot was not updated alongside the pyproject.toml. diff --git a/docs/admin/release_notes/version_1.5.md b/docs/admin/release_notes/version_1.5.md index 86b23057..d88ead04 100644 --- a/docs/admin/release_notes/version_1.5.md +++ b/docs/admin/release_notes/version_1.5.md @@ -1,7 +1,7 @@ # v1.5 Release Notes -## [v1.5.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.5.0) +## [v1.5.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.5.0) ### Updates @@ -10,10 +10,10 @@ ### Fixes -[#17](https://github.com/nautobot/nautobot-plugin-chatops/issues/17) - Error with filtering by empty regions, no message back +[#17](https://github.com/nautobot/nautobot-app-chatops/issues/17) - Error with filtering by empty regions, no message back -## [v1.5.1](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.5.1) +## [v1.5.1](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.5.1) ### Fixes -[#97](https://github.com/nautobot/nautobot-plugin-chatops/pull/97) Fixes MS Teams Bold markdown. Moves from `****` to `**` to align with guides from Microsoft +[#97](https://github.com/nautobot/nautobot-app-chatops/pull/97) Fixes MS Teams Bold markdown. Moves from `****` to `**` to align with guides from Microsoft diff --git a/docs/admin/release_notes/version_1.6.md b/docs/admin/release_notes/version_1.6.md index fa355432..4cd9f5f2 100644 --- a/docs/admin/release_notes/version_1.6.md +++ b/docs/admin/release_notes/version_1.6.md @@ -1,8 +1,8 @@ # v1.6 Release Notes -## [v1.6.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.6.0) +## [v1.6.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.6.0) ### Additions -[#123](https://github.com/nautobot/nautobot-plugin-chatops/pull/123) Added export button for chat command usage as CSV -[#120](https://github.com/nautobot/nautobot-plugin-chatops/pull/120) Added `send_all_messages_private` setting +[#123](https://github.com/nautobot/nautobot-app-chatops/pull/123) Added export button for chat command usage as CSV +[#120](https://github.com/nautobot/nautobot-app-chatops/pull/120) Added `send_all_messages_private` setting diff --git a/docs/admin/release_notes/version_1.7.md b/docs/admin/release_notes/version_1.7.md index 46c061b2..14a00434 100644 --- a/docs/admin/release_notes/version_1.7.md +++ b/docs/admin/release_notes/version_1.7.md @@ -1,20 +1,20 @@ # v1.7 Release Notes -## [v1.7.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.7.0) +## [v1.7.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.7.0) ### Additions -[#128](https://github.com/nautobot/nautobot-plugin-chatops/pull/128) Adds QOL change for focusing of fields +[#128](https://github.com/nautobot/nautobot-app-chatops/pull/128) Adds QOL change for focusing of fields ### Fixes -[#129](https://github.com/nautobot/nautobot-plugin-chatops/pull/129) Fixes errors on private messages -[#128](https://github.com/nautobot/nautobot-plugin-chatops/pull/128) Access grants updates +[#129](https://github.com/nautobot/nautobot-app-chatops/pull/129) Fixes errors on private messages +[#128](https://github.com/nautobot/nautobot-app-chatops/pull/128) Access grants updates -## [v1.7.1](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.7.1) +## [v1.7.1](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.7.1) ### What's Changed -* Fix slack msg limits by @jvanderaa in [#133](https://github.com/nautobot/nautobot-plugin-chatops/pull/133) +* Fix slack msg limits by @jvanderaa in [#133](https://github.com/nautobot/nautobot-app-chatops/pull/133) -[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.7.0...v1.7.1) \ No newline at end of file +[**Full Changelog**](https://github.com/nautobot/nautobot-app-chatops/compare/v1.7.0...v1.7.1) \ No newline at end of file diff --git a/docs/admin/release_notes/version_1.8.md b/docs/admin/release_notes/version_1.8.md index 7d00bfe0..e15d6c4e 100644 --- a/docs/admin/release_notes/version_1.8.md +++ b/docs/admin/release_notes/version_1.8.md @@ -1,6 +1,6 @@ # v1.8 Release Notes -## [v1.8.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.8.0) +## [v1.8.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.8.0) ### What's Changed @@ -8,4 +8,4 @@ * Drop support for Nautobot <1.1.0 * Drop support for Python3.6 -[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.7.1...v1.8.0) \ No newline at end of file +[**Full Changelog**](https://github.com/nautobot/nautobot-app-chatops/compare/v1.7.1...v1.8.0) \ No newline at end of file diff --git a/docs/admin/release_notes/version_1.9.md b/docs/admin/release_notes/version_1.9.md index 49163547..26af12a5 100644 --- a/docs/admin/release_notes/version_1.9.md +++ b/docs/admin/release_notes/version_1.9.md @@ -1,21 +1,21 @@ # v1.9 Release Notes -## [v1.9.1](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.9.1) +## [v1.9.1](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.9.1) ### What's Changed -* Fix broken docs link [#150](https://github.com/nautobot/nautobot-plugin-chatops/pull/150) and [#151](https://github.com/nautobot/nautobot-plugin-chatops/pull/151) +* Fix broken docs link [#150](https://github.com/nautobot/nautobot-app-chatops/pull/150) and [#151](https://github.com/nautobot/nautobot-app-chatops/pull/151) -[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.9.0...v1.9.1) +[**Full Changelog**](https://github.com/nautobot/nautobot-app-chatops/compare/v1.9.0...v1.9.1) -## [v1.9.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.9.0) +## [v1.9.0](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v1.9.0) ### What's Changed * Add support for Nautobot 1.4.0 * Drop support for Nautobot <1.2.0 -* Remove missing action banner [#140](https://github.com/nautobot/nautobot-plugin-chatops/pull/140) -* Fix Mattermost API MattermostInteractionView request_schema [#144](https://github.com/nautobot/nautobot-plugin-chatops/pull/144) +* Remove missing action banner [#140](https://github.com/nautobot/nautobot-app-chatops/pull/140) +* Fix Mattermost API MattermostInteractionView request_schema [#144](https://github.com/nautobot/nautobot-app-chatops/pull/144) -[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.8.0...v1.9.0) +[**Full Changelog**](https://github.com/nautobot/nautobot-app-chatops/compare/v1.8.0...v1.9.0) diff --git a/docs/admin/release_notes/version_2.0.md b/docs/admin/release_notes/version_2.0.md index 10c7f6ea..329f6735 100644 --- a/docs/admin/release_notes/version_2.0.md +++ b/docs/admin/release_notes/version_2.0.md @@ -2,55 +2,55 @@ # v2.0 Release Notes -## [v2.0.3 (2023-09-22)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.3) +## [v2.0.3 (2023-09-22)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v2.0.3) ### Added -- [#227](https://github.com/nautobot/nautobot-plugin-chatops/issues/227) - Added some tests for VLAN chatops. +- [#227](https://github.com/nautobot/nautobot-app-chatops/issues/227) - Added some tests for VLAN chatops. ### Fixed -- [#227](https://github.com/nautobot/nautobot-plugin-chatops/issues/227) - Fixed parameters that should be set to None if they have not been defined yet by default. -- [#239](https://github.com/nautobot/nautobot-plugin-chatops/issues/239) - Updated IP Fabric Logo. -- [#241](https://github.com/nautobot/nautobot-plugin-chatops/issues/241) - Remove Grafana Navigation and urls if disabled. -- [#253](https://github.com/nautobot/nautobot-plugin-chatops/issues/253) - Sorted the ICMP types from IP Fabric diagrams package. +- [#227](https://github.com/nautobot/nautobot-app-chatops/issues/227) - Fixed parameters that should be set to None if they have not been defined yet by default. +- [#239](https://github.com/nautobot/nautobot-app-chatops/issues/239) - Updated IP Fabric Logo. +- [#241](https://github.com/nautobot/nautobot-app-chatops/issues/241) - Remove Grafana Navigation and urls if disabled. +- [#253](https://github.com/nautobot/nautobot-app-chatops/issues/253) - Sorted the ICMP types from IP Fabric diagrams package. -## [v2.0.2 (2023-08-11)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.2) +## [v2.0.2 (2023-08-11)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v2.0.2) ### Changed -- [#233](https://github.com/nautobot/nautobot-plugin-chatops/pull/233) - Fixed App initialization when `[grafana]` extra is not installed. +- [#233](https://github.com/nautobot/nautobot-app-chatops/pull/233) - Fixed App initialization when `[grafana]` extra is not installed. -## [v2.0.1 (2023-08-08)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.1) +## [v2.0.1 (2023-08-08)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v2.0.1) ### Changed -- [#228](https://github.com/nautobot/nautobot-plugin-chatops/issues/228) - Move Contributing Changelog Fragments higher in documentation +- [#228](https://github.com/nautobot/nautobot-app-chatops/issues/228) - Move Contributing Changelog Fragments higher in documentation -## [v2.0.0 (2023-08-02)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.0) +## [v2.0.0 (2023-08-02)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v2.0.0) ### Added -- [#67](https://github.com/nautobot/nautobot-plugin-chatops/issues/67) - Added the ability within Slack to mention the chat bot by name in a channel and in threads. -- [#194](https://github.com/nautobot/nautobot-plugin-chatops/issues/194) - Added Mattermost container for the development. -- [#194](https://github.com/nautobot/nautobot-plugin-chatops/issues/194) - Improved invoke tasks. -- [#197](https://github.com/nautobot/nautobot-plugin-chatops/issues/197) - Add a try/except block and error logger message when access_token missing from get_token() response. -- [#202](https://github.com/nautobot/nautobot-plugin-chatops/issues/202) - Added Ansible integration from nautobot-plugin-chatops-ansible. -- [#203](https://github.com/nautobot/nautobot-plugin-chatops/issues/203) - Added IP Fabric integration from nautobot-plugin-chatops-ipfabric. -- [#204](https://github.com/nautobot/nautobot-plugin-chatops/issues/204) - Added Arista CloudVision integration from nautobot-plugin-chatops-arista-cloudvision. -- [#205](https://github.com/nautobot/nautobot-plugin-chatops/issues/205) - Added Cisco Meraki integration from nautobot-plugin-chatops-meraki. -- [#206](https://github.com/nautobot/nautobot-plugin-chatops/issues/206) - Added Cisco ACI integration from nautobot-plugin-chatops-aci. -- [#207](https://github.com/nautobot/nautobot-plugin-chatops/issues/207) - Added Panorama integration from nautobot-plugin-chatops-panorama -- [#208](https://github.com/nautobot/nautobot-plugin-chatops/issues/208) - Added Grafana integration from nautobot-plugin-chatops-grafana. +- [#67](https://github.com/nautobot/nautobot-app-chatops/issues/67) - Added the ability within Slack to mention the chat bot by name in a channel and in threads. +- [#194](https://github.com/nautobot/nautobot-app-chatops/issues/194) - Added Mattermost container for the development. +- [#194](https://github.com/nautobot/nautobot-app-chatops/issues/194) - Improved invoke tasks. +- [#197](https://github.com/nautobot/nautobot-app-chatops/issues/197) - Add a try/except block and error logger message when access_token missing from get_token() response. +- [#202](https://github.com/nautobot/nautobot-app-chatops/issues/202) - Added Ansible integration from nautobot-plugin-chatops-ansible. +- [#203](https://github.com/nautobot/nautobot-app-chatops/issues/203) - Added IP Fabric integration from nautobot-plugin-chatops-ipfabric. +- [#204](https://github.com/nautobot/nautobot-app-chatops/issues/204) - Added Arista CloudVision integration from nautobot-plugin-chatops-arista-cloudvision. +- [#205](https://github.com/nautobot/nautobot-app-chatops/issues/205) - Added Cisco Meraki integration from nautobot-plugin-chatops-meraki. +- [#206](https://github.com/nautobot/nautobot-app-chatops/issues/206) - Added Cisco ACI integration from nautobot-plugin-chatops-aci. +- [#207](https://github.com/nautobot/nautobot-app-chatops/issues/207) - Added Panorama integration from nautobot-plugin-chatops-panorama +- [#208](https://github.com/nautobot/nautobot-app-chatops/issues/208) - Added Grafana integration from nautobot-plugin-chatops-grafana. ### Changed -- [#67](https://github.com/nautobot/nautobot-plugin-chatops/issues/67) - Modified the clear command to not work within Slack threads. -- [#196](https://github.com/nautobot/nautobot-plugin-chatops/issues/196) - Update to microsoft IPs and correcting the one in the doc. -- [#218](https://github.com/nautobot/nautobot-plugin-chatops/issues/218) - Added `/clear` command to development Mattermost. -- [#218](https://github.com/nautobot/nautobot-plugin-chatops/issues/218) - Improved integration workers loading. -- [#218](https://github.com/nautobot/nautobot-plugin-chatops/issues/218) - Sorted App config and environment variables. -- [#218](https://github.com/nautobot/nautobot-plugin-chatops/issues/218) - Sorted pyproject configurations. +- [#67](https://github.com/nautobot/nautobot-app-chatops/issues/67) - Modified the clear command to not work within Slack threads. +- [#196](https://github.com/nautobot/nautobot-app-chatops/issues/196) - Update to microsoft IPs and correcting the one in the doc. +- [#218](https://github.com/nautobot/nautobot-app-chatops/issues/218) - Added `/clear` command to development Mattermost. +- [#218](https://github.com/nautobot/nautobot-app-chatops/issues/218) - Improved integration workers loading. +- [#218](https://github.com/nautobot/nautobot-app-chatops/issues/218) - Sorted App config and environment variables. +- [#218](https://github.com/nautobot/nautobot-app-chatops/issues/218) - Sorted pyproject configurations. ### Removed diff --git a/docs/admin/release_notes/version_2.1.md b/docs/admin/release_notes/version_2.1.md index 00cdf009..c8eb5399 100644 --- a/docs/admin/release_notes/version_2.1.md +++ b/docs/admin/release_notes/version_2.1.md @@ -2,8 +2,8 @@ # v2.1 Release Notes -## [v2.1.0 (2023-09-28)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.1.0) +## [v2.1.0 (2023-09-28)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v2.1.0) ### Fixed -- [#273](https://github.com/nautobot/nautobot-plugin-chatops/issues/273) - Fixed dependency resolution issues with latest release of golden config. +- [#273](https://github.com/nautobot/nautobot-app-chatops/issues/273) - Fixed dependency resolution issues with latest release of golden config. diff --git a/docs/admin/release_notes/version_3.0.md b/docs/admin/release_notes/version_3.0.md index 0e8c7b57..c02dd2bf 100644 --- a/docs/admin/release_notes/version_3.0.md +++ b/docs/admin/release_notes/version_3.0.md @@ -2,15 +2,39 @@ # v3.0 Release Notes -## [v3.0.0 (2023-09-29)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v3.0.0) +## [v3.0.0 (2023-09-29)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v3.0.0) ### Added -- [#112](https://github.com/nautobot/nautobot-plugin-chatops/issues/112) - Add ability to link Chat User with Nautobot User. -- [#272](https://github.com/nautobot/nautobot-plugin-chatops/issues/272) - Add ObjectNotesView for ChatOps models. +- [#112](https://github.com/nautobot/nautobot-app-chatops/issues/112) - Add ability to link Chat User with Nautobot User. +- [#272](https://github.com/nautobot/nautobot-app-chatops/issues/272) - Add ObjectNotesView for ChatOps models. -## [v3.0.1 (2023-09-29)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v3.0.1) +## [v3.0.1 (2023-09-29)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v3.0.1) ### Fixed -- [[#281](https://github.com/nautobot/nautobot-plugin-chatops/issues/281) - Address permissions bug found during release review. \ No newline at end of file +- [#281](https://github.com/nautobot/nautobot-app-chatops/issues/281) - Address permissions bug found during release review. + +## [v3.0.2 (2024-03-28)](https://github.com/nautobot/nautobot-app-chatops/releases/tag/v3.0.2) + +### Added + +- [#270](https://github.com/nautobot/nautobot-app-chatops/issues/270) - Add run_job Nautobot subcommand, which initiates a job with kwargs or a job requiring no manual form input. +- [#270](https://github.com/nautobot/nautobot-app-chatops/issues/270) - Add run_job_form Nautobot subcommand, which presents job's form widgets to the user. +- [#270](https://github.com/nautobot/nautobot-app-chatops/issues/270) - Add get_jobs Nautobot subcommand, which returns all Nautobot jobs viewable to user. +- [#270](https://github.com/nautobot/nautobot-app-chatops/issues/270) - Add filter_jobs Nautobot subcommand, which returns filtered set of Nautobot jobs viewable to user. +- [#288](https://github.com/nautobot/nautobot-app-chatops/issues/288) - Added Cisco NSO integration + +### Changed + +- [#265](https://github.com/nautobot/nautobot-app-chatops/issues/265) - Aligned integrations documentation structure with SSoT. +- [#297](https://github.com/nautobot/nautobot-app-chatops/issues/297) - Replaced pydocstyle with ruff. + +### Fixed + +- [#293](https://github.com/nautobot/nautobot-app-chatops/issues/293) - Fix Aristacv not disabling with the setting. + +### Housekeeping + +- [#8](https://github.com/nautobot/nautobot-app-chatops/issues/8), [#307](https://github.com/nautobot/nautobot-app-chatops/issues/307) - Re-baked from the latest template. +- [#293](https://github.com/nautobot/nautobot-app-chatops/issues/293) - Add debug logs to msteams dispatcher and api view. diff --git a/docs/admin/uninstall.md b/docs/admin/uninstall.md index d1a18925..d132d305 100644 --- a/docs/admin/uninstall.md +++ b/docs/admin/uninstall.md @@ -1,18 +1,21 @@ # Uninstall the App from Nautobot -## Uninstall Guide +Here you will find any steps necessary to cleanly remove the App from your Nautobot environment. -1. Remove Database migrations for ChatOps: +## Database Cleanup - ```bash - nautobot-server migrate nautobot-chatops zero - ``` +Prior to removing the app from the `nautobot_config.py`, run the following command to roll back any migration specific to this app. -2. Remove the configuration you added in `nautobot_config.py` from `PLUGINS` & `PLUGINS_CONFIG`. -3. Run Nautobot-server post_upgrade +```shell +nautobot-server migrate nautobot_chatops zero +``` - ```bash - nautobot-server post_ugprade - ``` +## Remove App configuration -4. Restart Nautobot Services +Remove the configuration you added in `nautobot_config.py` from `PLUGINS` & `PLUGINS_CONFIG`. + +## Uninstall the package + +```bash +$ pip3 uninstall nautobot-chatops +``` diff --git a/docs/admin/upgrade.md b/docs/admin/upgrade.md index 31dde8bb..6c8becb4 100644 --- a/docs/admin/upgrade.md +++ b/docs/admin/upgrade.md @@ -1,8 +1,10 @@ # Upgrading the App +Here you will find any steps necessary to upgrade the App in your Nautobot environment. + ## Upgrade Guide -When a new release comes out it may be necessary to run a migration of the database to account for any changes in the data models used by this plugin. Execute the command `nautobot-server post_upgrade` from the Nautobot install nautobot/ directory after updating the package. +When a new release comes out it may be necessary to run a migration of the database to account for any changes in the data models used by this app. Execute the command `nautobot-server post_upgrade` within the runtime environment of your Nautobot installation after updating the `nautobot-chatops` package via `pip`. ### Upgrading to ChatOps 3.0 diff --git a/docs/assets/extra.css b/docs/assets/extra.css index ce9ea9c8..1eff1192 100644 --- a/docs/assets/extra.css +++ b/docs/assets/extra.css @@ -18,6 +18,15 @@ font-size: 0.7rem; } +/* +* The default max-width is 61rem which does not provide nearly enough space to present code examples or larger tables +*/ +.md-grid { + margin-left: auto; + margin-right: auto; + max-width: 95%; +} + .md-tabs__link { font-size: 0.8rem; } @@ -38,13 +47,8 @@ font-size: 1.2rem; } -/* Keep images in tables at 50px */ -.md-typeset table:not([class]) :is(img) { - height: 50px; -} - img.logo { - height: 100px; + height: 200px; } img.copyright-logo { @@ -91,6 +95,71 @@ a.autorefs-external:hover::after { background-color: var(--md-accent-fg-color); } + +/* Customization for mkdocs-version-annotations */ +:root { + /* Icon for "version-added" admonition: Material Design Icons "plus-box-outline" */ + --md-admonition-icon--version-added: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-changed" admonition: Material Design Icons "delta" */ + --md-admonition-icon--version-changed: url('data:image/svg+xml;charset=utf-8,'); + /* Icon for "version-removed" admonition: Material Design Icons "minus-circle-outline" */ + --md-admonition-icon--version-removed: url('data:image/svg+xml;charset=utf-8,'); +} + +/* "version-added" admonition in green */ +.md-typeset .admonition.version-added, +.md-typeset details.version-added { + border-color: rgb(0, 200, 83); +} + +.md-typeset .version-added>.admonition-title, +.md-typeset .version-added>summary { + background-color: rgba(0, 200, 83, .1); +} + +.md-typeset .version-added>.admonition-title::before, +.md-typeset .version-added>summary::before { + background-color: rgb(0, 200, 83); + -webkit-mask-image: var(--md-admonition-icon--version-added); + mask-image: var(--md-admonition-icon--version-added); +} + +/* "version-changed" admonition in orange */ +.md-typeset .admonition.version-changed, +.md-typeset details.version-changed { + border-color: rgb(255, 145, 0); +} + +.md-typeset .version-changed>.admonition-title, +.md-typeset .version-changed>summary { + background-color: rgba(255, 145, 0, .1); +} + +.md-typeset .version-changed>.admonition-title::before, +.md-typeset .version-changed>summary::before { + background-color: rgb(255, 145, 0); + -webkit-mask-image: var(--md-admonition-icon--version-changed); + mask-image: var(--md-admonition-icon--version-changed); +} + +/* "version-removed" admonition in red */ +.md-typeset .admonition.version-removed, +.md-typeset details.version-removed { + border-color: rgb(255, 82, 82); +} + +.md-typeset .version-removed>.admonition-title, +.md-typeset .version-removed>summary { + background-color: rgba(255, 82, 82, .1); +} + +.md-typeset .version-removed>.admonition-title::before, +.md-typeset .version-removed>summary::before { + background-color: rgb(255, 82, 82); + -webkit-mask-image: var(--md-admonition-icon--version-removed); + mask-image: var(--md-admonition-icon--version-removed); +} + /* Do not wrap code blocks in markdown tables. */ div.md-typeset__table>table>tbody>tr>td>code { white-space: nowrap; diff --git a/docs/assets/overrides/partials/copyright.html b/docs/assets/overrides/partials/copyright.html index e2c55d12..b92cf5e3 100644 --- a/docs/assets/overrides/partials/copyright.html +++ b/docs/assets/overrides/partials/copyright.html @@ -1,9 +1,10 @@ + @@ -17,4 +18,5 @@ -
\ No newline at end of file +
+ diff --git a/docs/dev/code_reference/api.md b/docs/dev/code_reference/api.md index 01e7ce0a..f2bdd255 100644 --- a/docs/dev/code_reference/api.md +++ b/docs/dev/code_reference/api.md @@ -1,4 +1,4 @@ -# Nautobot Plugin ChatOps API Package +# Nautobot ChatOps App API Package ::: nautobot_chatops.api options: diff --git a/docs/dev/code_reference/package.md b/docs/dev/code_reference/package.md new file mode 100644 index 00000000..664696ae --- /dev/null +++ b/docs/dev/code_reference/package.md @@ -0,0 +1 @@ +::: nautobot_chatops diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md index 57cd6cb3..d0875111 100644 --- a/docs/dev/contributing.md +++ b/docs/dev/contributing.md @@ -1,15 +1,14 @@ -# Contributing to Nautobot ChatOps +# Contributing to the App The project is packaged with a light [development environment](dev_environment.md) based on `docker-compose` to help with the local development of the project and to run tests. The project is following Network to Code software development guidelines and is leveraging the following: -- Python linting and formatting: `black`, `pylint`, `bandit`, `flake8`, and `pydocstyle`. +- Python linting and formatting: `black`, `pylint`, `bandit`, `flake8`, and `ruff`. - YAML linting is done with `yamllint`. -- Django unit test to ensure the plugin is working properly. +- Django unit test to ensure the app is working properly. -Documentation is built using [mkdocs](https://www.mkdocs.org/). -The [Docker based development environment](dev_environment.md#docker-development-environment) automatically starts a container hosting a live version of the documentation website on [http://localhost:8001](http://localhost:8001) that auto-refreshes when you make any changes to your local files. +Documentation is built using [mkdocs](https://www.mkdocs.org/). The [Docker based development environment](dev_environment.md#docker-development-environment) automatically starts a container hosting a live version of the documentation website on [http://localhost:8001](http://localhost:8001) that auto-refreshes when you make any changes to your local files. ## Creating Changelog Fragments @@ -182,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. +- 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 proper branch, e.g. either `main` or `stable-.`. + - 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-.`. +- 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/design.md b/docs/dev/design.md index 6568727b..0e4a0422 100644 --- a/docs/dev/design.md +++ b/docs/dev/design.md @@ -1,6 +1,6 @@ # The design of Nautobot ChatOps -By delivering this as a Nautobot ChatOps plugin, we gain the following benefits: +By delivering this as a Nautobot ChatOps App, we gain the following benefits: - No need to stand up a separate HTTP server, just use Nautobot's own HTTP server. - Use of `async` is not required because we can hand off long-running tasks to Nautobot's `celery` workers. With one notable exception, WebSocket connections will be done with `async`. We have opted for `AIOHTTP` for our WebSocket [clients](https://docs.aiohttp.org/en/stable/client_quickstart.html#aiohttp-client-websockets). @@ -12,7 +12,7 @@ By delivering this as a Nautobot ChatOps plugin, we gain the following benefits: ## Code structure -The design goal of this plugin is to be able to write chatbot commands once and have them run anywhere +The design goal of this app is to be able to write chatbot commands once and have them run anywhere (Slack, Microsoft Teams, Cisco Webex, etc.). Toward that end, it's divided into three layers: 1. input @@ -39,8 +39,8 @@ The design goal of this plugin is to be able to write chatbot commands once and - In addition to enqueuing the command parameters for the worker, the queue also requires a `Dispatcher` class (see below) and any additional `context` that the dispatcher requires (such as user_id, channel_id, tokens, etc.) - - Support for additional chat platform endpoints can be implemented as additional modules in this plugin, - or could be delivered as an entirely separate Nautobot plugin if desired. + - Support for additional chat platform endpoints can be implemented as additional modules in this app, + or could be delivered as an entirely separate Nautobot app if desired. 2. worker (`nautobot_chatops.workers`) @@ -54,7 +54,7 @@ The design goal of this plugin is to be able to write chatbot commands once and - Each module in this layer would provide a different top-level command, such as `nautobot`, `grafana`, or `ansible`. - This layer is designed to be extensible through Python's packaging `entry_points` functionality (`plugins` in - Poetry's terminology). A Python package (Nautobot plugin) can register any worker functions under the `nautobot.workers` entry point, + Poetry's terminology). A Python package (Nautobot App) can register any worker functions under the `nautobot.workers` entry point, and the worker(s) will automatically be added to the client's capabilities. 3. output (`nautobot_chatops.dispatchers`) @@ -78,7 +78,7 @@ The design goal of this plugin is to be able to write chatbot commands once and `views` submodules and `dispatchers` submodules. - As with the `views` layer, the `Dispatcher` for a new chat platform could be implemented as a new submodule for - this plugin, or could be delivered as part of a separate Nautobot plugin. + this app, or could be delivered as part of a separate Nautobot App. ## Information flow @@ -90,7 +90,7 @@ The design goal of this plugin is to be able to write chatbot commands once and |-- User input ->| | | |-- HTTP POST ->| | | | nautobot_chatops/views/* - | | |-- Enqueue job,dispatcher to RQ --> + | | |-- Enqueue job,dispatcher to Celery --> | |<---- 200 OK --| |<- "Received" --| ``` diff --git a/docs/dev/dev_environment.md b/docs/dev/dev_environment.md index 73f88702..621c4ea2 100644 --- a/docs/dev/dev_environment.md +++ b/docs/dev/dev_environment.md @@ -13,9 +13,9 @@ This is a quick reference guide if you're already familiar with the development The [Invoke](http://www.pyinvoke.org/) library is used to provide some helper commands based on the environment. There are a few configuration parameters which can be passed to Invoke to override the default configuration: -- `nautobot_ver`: the version of Nautobot to use as a base for any built docker containers (default: latest) -- `project_name`: the default docker compose project name (default: `nautobot_chatops`) -- `python_ver`: the version of Python to use as a base for any built docker containers (default: 3.8) +- `nautobot_ver`: the version of Nautobot to use as a base for any built docker containers (default: 2.0.0) +- `project_name`: the default docker compose project name (default: `nautobot-chatops`) +- `python_ver`: the version of Python to use as a base for any built docker containers (default: 3.11) - `local`: a boolean flag indicating if invoke tasks should be run on the host or inside the docker containers (default: False, commands will be run in docker containers) - `compose_dir`: the full path to a directory containing the project compose files - `compose_files`: a list of compose files applied in order (see [Multiple Compose files](https://docs.docker.com/compose/extends/#multiple-compose-files) for more information) @@ -29,13 +29,14 @@ Using **Invoke** these configuration options can be overridden using [several me This project is managed by [Python Poetry](https://python-poetry.org/) and has a few requirements to set up your development environment: -1. Install Poetry, see the [Poetry Documentation](https://python-poetry.org/docs/#installation) for your operating system. +1. Install Poetry, see the [Poetry documentation](https://python-poetry.org/docs/#installation) for your operating system. 2. Install Docker, see the [Docker documentation](https://docs.docker.com/get-docker/) for your operating system. +3. Install Docker-compose, see the [Docker-compose documentation](https://github.com/docker/compose) for your operation system. Once you have Poetry and Docker installed you can run the following commands (in the root of the repository) to install all other development dependencies in an isolated Python virtual environment: ```shell -git clone git@github.com:nautobot/nautobot-plugin-chatops.git +git clone git@github.com:nautobot/nautobot-app-chatops.git cd nautobot-plugin-chatops poetry shell poetry install @@ -50,8 +51,6 @@ invoke start invoke bootstrap-mattermost ``` -``` - The Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080) and the live documentation at [http://localhost:8001](http://localhost:8001). To either stop or destroy the development environment use the following options. @@ -67,8 +66,6 @@ To either stop or destroy the development environment use the following options. --- nautobot_chatops: local: true - compose_files: - - "docker-compose.requirements.yml" ``` Run the following commands: @@ -76,7 +73,7 @@ Run the following commands: ```shell poetry shell poetry install --extras nautobot -export $(cat development/dev.env | xargs) +export $(cat development/development.env | xargs) export $(cat development/creds.env | xargs) invoke start && sleep 5 nautobot-server migrate @@ -85,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 @@ -93,7 +90,7 @@ nautobot-server runserver 0.0.0.0:8080 --insecure Nautobot server can now be accessed at [http://localhost:8080](http://localhost:8080). -It is typically recommended to launch the Nautobot `runserver` command in a separate shell, so you can keep developing and manage the web server separately. +It is typically recommended to launch the Nautobot **runserver** command in a separate shell so you can keep developing and manage the webserver separately. ### Updating the Documentation @@ -111,9 +108,6 @@ The project features a CLI helper based on [Invoke](https://www.pyinvoke.org/) t Each command can be executed with `invoke `. All commands support the arguments `--nautobot-ver` and `--python-ver` if you want to manually define the version of Python and Nautobot to use. Each command also has its own help `invoke --help` -!!! note - To run the MySQL (MariaDB) development environment, set the environment variable as such `export NAUTOBOT_USE_MYSQL=1`. - #### Local Development Environment ``` @@ -140,34 +134,33 @@ Each command can be executed with `invoke `. All commands support the a bandit Run bandit to validate basic static code security analysis. black Run black to check that Python files adhere to its style standards. flake8 Run flake8 to check that Python files adhere to its style standards. - pydocstyle Run pydocstyle to validate docstring formatting adheres to NTC defined standards. + ruff Run ruff to validate docstring formatting adheres to NTC defined standards. pylint Run pylint code analysis. - tests Run all tests for this plugin. - unittest Run Django unit tests for the plugin. + tests Run all tests for this app. + unittest Run Django unit tests for the app. ``` - ## Project Overview -This project provides the ability to develop and manage the Nautobot server locally (with supporting services being dockerized) or by using only Docker containers to manage Nautobot. The main difference between the two environments is the ability to debug and use **pdb** when developing locally. Debugging with **pdb** within the Docker container is more complicated, but can still be accomplished by either entering into the container (via `docker exec`) or attaching your IDE to the container and running the Nautobot service manually within the container. +This project provides the ability to develop and manage the Nautobot server locally (with supporting services being *Dockerized*) or by using only Docker containers to manage Nautobot. The main difference between the two environments is the ability to debug and use **pdb** when developing locally. Debugging with **pdb** within the Docker container is more complicated, but can still be accomplished by either entering into the container (via `docker exec`) or attaching your IDE to the container and running the Nautobot service manually within the container. The upside to having the Nautobot service handled by Docker rather than locally is that you do not have to manage the Nautobot server. The [Docker logs](#docker-logs) provide the majority of the information you will need to help troubleshoot, while getting started quickly and not requiring you to perform several manual steps and remembering to have the Nautobot server running in a separate terminal while you develop. !!! note - The local environment still uses Docker containers for the supporting services (Postgres, Redis, and RQ Worker), but the Nautobot server is handled locally by you, the developer. + The local environment still uses Docker containers for the supporting services (Postgres, Redis, and Celery Worker), but the Nautobot server is handled locally by you, the developer. Follow the directions below for the specific development environment that you choose. ## Poetry -Poetry is used in lieu of the `virtualenv` commands and is leveraged in both environments. The virtual environment will provide all the Python packages required to manage the development environment such as **Invoke**. See the [Local Development Environment](#local-poetry-development-environment) section to see how to install Nautobot if you're going to be developing locally (i.e. not using the Docker container). +Poetry is used in lieu of the "virtualenv" commands and is leveraged in both environments. The virtual environment will provide all of the Python packages required to manage the development environment such as **Invoke**. See the [Local Development Environment](#local-poetry-development-environment) section to see how to install Nautobot if you're going to be developing locally (i.e. not using the Docker container). -The `pyproject.toml` file outlines all the relevant dependencies for the project: +The `pyproject.toml` file outlines all of the relevant dependencies for the project: - `tool.poetry.dependencies` - the main list of dependencies. -- `tool.poetry.dev-dependencies` - development dependencies, to facilitate linting, testing, and documentation building. +- `tool.poetry.group.dev.dependencies` - development dependencies, to facilitate linting, testing, and documentation building. -The `poetry shell` command is used to create and enable a virtual environment managed by Poetry, so all commands ran going forward are executed within the virtual environment. This is similar to running the `source venv/bin/activate` command with `virtualenv`. To install project dependencies in the virtual environment, you should run `poetry install` - this will install **both** project and development dependencies. +The `poetry shell` command is used to create and enable a virtual environment managed by Poetry, so all commands ran going forward are executed within the virtual environment. This is similar to running the `source venv/bin/activate` command with virtualenvs. To install project dependencies in the virtual environment, you should run `poetry install` - this will install **both** project and development dependencies. For more details about Poetry and its commands please check out its [online documentation](https://python-poetry.org/docs/). @@ -195,7 +188,7 @@ The first thing you need to do is build the necessary Docker image for Nautobot #14 exporting layers #14 exporting layers 1.2s done #14 writing image sha256:2d524bc1665327faa0d34001b0a9d2ccf450612bf8feeb969312e96a2d3e3503 done -#14 naming to docker.io/nautobot-chatops/nautobot:latest-py3.7 done +#14 naming to docker.io/nautobot-chatops/nautobot:2.0.0-py3.11 done ``` ### Invoke - Starting the Development Environment @@ -221,14 +214,14 @@ Creating nautobot_chatops_worker_1 ... done Docker Compose is now in the Docker CLI, try `docker compose up` ``` -This will start all containers used for hosting Nautobot. You should see the following containers running after `invoke start` is finished. +This will start all of the Docker containers used for hosting Nautobot. You should see the following containers running after `invoke start` is finished. ```bash ➜ docker ps ****CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -ee90fbfabd77 nautobot-chatops/nautobot:latest-py3.7 "nautobot-server rqw…" 16 seconds ago Up 13 seconds nautobot_chatops_worker_1 -b8adb781d013 nautobot-chatops/nautobot:latest-py3.7 "/docker-entrypoint.…" 20 seconds ago Up 15 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp nautobot_chatops_nautobot_1 -d64ebd60675d nautobot-chatops/nautobot:latest-py3.7 "mkdocs serve -v -a …" 25 seconds ago Up 18 seconds 0.0.0.0:8001->8080/tcp, :::8001->8080/tcp nautobot_chatops_docs_1 +ee90fbfabd77 nautobot-chatops/nautobot:2.0.0-py3.11 "nautobot-server cel…" 16 seconds ago Up 13 seconds nautobot_chatops_worker_1 +b8adb781d013 nautobot-chatops/nautobot:2.0.0-py3.11 "/docker-entrypoint.…" 20 seconds ago Up 15 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp nautobot_chatops_nautobot_1 +d64ebd60675d nautobot-chatops/nautobot:2.0.0-py3.11 "mkdocs serve -v -a …" 25 seconds ago Up 18 seconds 0.0.0.0:8001->8080/tcp, :::8001->8080/tcp nautobot_chatops_docs_1 e72d63129b36 postgres:13-alpine "docker-entrypoint.s…" 25 seconds ago Up 19 seconds 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp nautobot_chatops_postgres_1 96c6ff66997c redis:6-alpine "docker-entrypoint.s…" 25 seconds ago Up 21 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp nautobot_chatops_redis_1 ``` @@ -243,14 +236,14 @@ Once the containers are fully up, you should be able to open up a web browser, a ### Invoke - Creating a Superuser -The Nautobot development image will automatically provision a super-user when specifying the following variables within `creds.env` which is the default when copying `creds.example.env` to `creds.env`. +The Nautobot development image will automatically provision a super user when specifying the following variables within `creds.env` which is the default when copying `creds.example.env` to `creds.env`. - `NAUTOBOT_CREATE_SUPERUSER=true` - `NAUTOBOT_SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567` - `NAUTOBOT_SUPERUSER_PASSWORD=admin` !!! note - The default username is **admin**, but can be overridden by specifying `NAUTOBOT_SUPERUSER_USERNAME`. + The default username is **admin**, but can be overridden by specifying **NAUTOBOT_SUPERUSER_USERNAME**. If you need to create additional superusers, run the follow commands. @@ -306,14 +299,14 @@ This will safely shut down all of your running Docker containers for this projec Your environment should now be fully setup, all necessary Docker containers are created and running, and you're logged into Nautobot in your web browser. Now what? -Now you can start developing your plugin in the project folder! +Now you can start developing your app in the project folder! -The magic here is the root directory is mounted inside your Docker containers when built and ran, so **any** changes made to the files in here are directly updated to the Nautobot plugin code running in Docker. This means that as you modify the code in your plugin folder, the changes will be instantly updated in Nautobot. +The magic here is the root directory is mounted inside your Docker containers when built and ran, so **any** changes made to the files in here are directly updated to the Nautobot app code running in Docker. This means that as you modify the code in your app folder, the changes will be instantly updated in Nautobot. !!! warning There are a few exceptions to this, as outlined in the section [To Rebuild or Not To Rebuild](#to-rebuild-or-not-to-rebuild). -The back-end Django process is set up to automatically reload itself (it only takes a couple of seconds) every time a file is updated (saved). So for example, if you were to update one of the files like `tables.py`, then save it, the changes will be visible right away in the web browser! +The back-end Django process is setup to automatically reload itself (it only takes a couple of seconds) every time a file is updated (saved). So for example, if you were to update one of the files like `tables.py`, then save it, the changes will be visible right away in the web browser! !!! note You may get connection refused while Django reloads, but it should be refreshed fairly quickly. @@ -327,9 +320,12 @@ When trying to debug an issue, one helpful thing you can look at are the logs wi ``` !!! note - The `--follow` tag will keep the logs open, and output them in real-time as they are generated. + The `--follow` argument will keep the logs open, and output them in real-time as they are generated. -So for example, `invoke logs --service nautobot --follow` will follow logs from `nautobot` docker compose service. You can find all running services via `invoke ps`. +!!! info + Want to limit the log output even further? Use the `--tail <#>` command line argument in conjunction with `-f`. + +So for example, our app is named `nautobot-chatops`, the command would most likely be `docker logs nautobot_chatops_nautobot_1 -f`. You can find the name of all running containers via `docker ps`. If you want to view the logs specific to the worker container, simply use the name of that container instead. @@ -355,7 +351,7 @@ Once completed, the new/updated environment variables should now be live. ### Installing Additional Python Packages -If you want your plugin to leverage another available Nautobot plugin or another Python package, you can easily add them into your Docker environment. +If you want your app to leverage another available Nautobot app or another Python package, you can easily add them into your Docker environment. ```bash ➜ poetry shell @@ -370,18 +366,18 @@ Once the dependencies are resolved, stop the existing containers, rebuild the Do ➜ invoke start ``` -### Installing Additional Nautobot Plugins +### Installing Additional Nautobot Apps -Let's say for example you want the new plugin you're creating to integrate into Nautobot ChatOps. To do this, you will want to integrate into the existing Nautobot ChatOps Plugin. +Let's say for example you want the new app you're creating to integrate into Nautobot ChatOps. To do this, you will want to integrate into the existing Nautobot ChatOps App. ```bash ➜ poetry shell ➜ poetry add nautobot-chatops ``` -Once you activate the virtual environment via Poetry, you then tell Poetry to install the new plugin. +Once you activate the virtual environment via Poetry, you then tell Poetry to install the new app. -Before you continue, you'll need to update the file `development/nautobot_config.py` accordingly with the name of the new plugin under `PLUGINS` and any relevant settings as necessary for the plugin under `PLUGINS_CONFIG`. Since you're modifying the underlying OS (not just Django files), you need to rebuild the image. This is a similar process to updating environment variables, which was explained earlier. +Before you continue, you'll need to update the file `development/nautobot_config.py` accordingly with the name of the new app under `PLUGINS` and any relevant settings as necessary for the app under `PLUGINS_CONFIG`. Since you're modifying the underlying OS (not just Django files), you need to rebuild the image. This is a similar process to updating environment variables, which was explained earlier. ```bash ➜ invoke stop @@ -389,7 +385,7 @@ Before you continue, you'll need to update the file `development/nautobot_config ➜ invoke start ``` -Once the containers are up and running, you should now see the new plugin installed in your Nautobot instance. +Once the containers are up and running, you should now see the new app installed in your Nautobot instance. !!! note You can even launch `ngrok` service locally on your laptop, pointing to port 8080 (such as for ChatOps development), and it will point traffic directly to your Docker images. @@ -404,14 +400,14 @@ namespace.configure( { "nautobot_chatops": { ... - "python_ver": "3.7", + "python_ver": "3.11", ... } } ) ``` -Or set the `INVOKE_NAUTOBOT_GOLDEN_CONFIG_PYTHON_VER` variable. +Or set the `INVOKE_NAUTOBOT_CHATOPS_PYTHON_VER` variable. ### Updating Nautobot Version @@ -423,7 +419,7 @@ namespace.configure( { "nautobot_chatops": { ... - "nautobot_ver": "1.0.2", + "nautobot_ver": "2.0.0", ... } } @@ -479,6 +475,24 @@ To run an individual test, you can run any or all of the following: ➜ invoke bandit ➜ invoke black ➜ invoke flake8 -➜ invoke pydocstyle +➜ 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/dev/release_checklist.md b/docs/dev/release_checklist.md index f859c96c..c5e4e59b 100644 --- a/docs/dev/release_checklist.md +++ b/docs/dev/release_checklist.md @@ -49,7 +49,7 @@ Add the release notes (`docs/release-notes/X.Y.md`) to the table of contents wit ### Verify and Revise the Installation Documentation -Follow the [installation instructions](../admin/install/index.md) to perform a new production installation of Nautobot ChatOps. +Follow the [installation instructions](../admin/install.md) to perform a new production installation of Nautobot ChatOps. The goal of this step is to walk through the entire install process *as documented* to make sure nothing there needs to be changed or updated, to catch any errors or omissions in the documentation, and to ensure that it is current with each release. @@ -143,7 +143,7 @@ Once CI has completed on the PR, merge it. ### Create a New Release -Draft a [new release](https://github.com/nautobot/nautobot-plugin-chatops/releases/new) with the following parameters. +Draft a [new release](https://github.com/nautobot/nautobot-app-chatops/releases/new) with the following parameters. * **Tag:** Current version (e.g. `v1.0.0`) * **Target:** `main` diff --git a/docs/images/nso-01.png b/docs/images/nso-01.png new file mode 100644 index 00000000..11527e30 Binary files /dev/null and b/docs/images/nso-01.png differ diff --git a/docs/images/nso-02.png b/docs/images/nso-02.png new file mode 100644 index 00000000..189a680c Binary files /dev/null and b/docs/images/nso-02.png differ diff --git a/docs/images/nso-03.png b/docs/images/nso-03.png new file mode 100644 index 00000000..12807c8b Binary files /dev/null and b/docs/images/nso-03.png differ diff --git a/docs/images/nso-04.png b/docs/images/nso-04.png new file mode 100644 index 00000000..400a49b7 Binary files /dev/null and b/docs/images/nso-04.png differ diff --git a/docs/images/nso-05.png b/docs/images/nso-05.png new file mode 100644 index 00000000..cc9caac9 Binary files /dev/null and b/docs/images/nso-05.png differ diff --git a/docs/images/nso-06.png b/docs/images/nso-06.png new file mode 100644 index 00000000..59e92b96 Binary files /dev/null and b/docs/images/nso-06.png differ diff --git a/docs/images/nso-07.png b/docs/images/nso-07.png new file mode 100644 index 00000000..33ddc9b2 Binary files /dev/null and b/docs/images/nso-07.png differ diff --git a/docs/images/nso-08.png b/docs/images/nso-08.png new file mode 100644 index 00000000..5fb55544 Binary files /dev/null and b/docs/images/nso-08.png differ diff --git a/docs/images/nso-09.png b/docs/images/nso-09.png new file mode 100644 index 00000000..a4a1fe86 Binary files /dev/null and b/docs/images/nso-09.png differ diff --git a/docs/images/nso-10.png b/docs/images/nso-10.png new file mode 100644 index 00000000..a30ba118 Binary files /dev/null and b/docs/images/nso-10.png differ diff --git a/docs/index.md b/docs/index.md index f8e5c92f..f32fd72b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,4 +3,4 @@ hide: - navigation --- ---8<-- "README.md" \ No newline at end of file +--8<-- "README.md" diff --git a/docs/models/chatopsaccountlink.md b/docs/models/chatopsaccountlink.md index 56746302..a1eb488c 100644 --- a/docs/models/chatopsaccountlink.md +++ b/docs/models/chatopsaccountlink.md @@ -1,7 +1,7 @@ # Account Link -+++3.0.0 ++++ 3.0.0 Nautobot ChatOps now uses the built-in Nautobot permissions for Nautobot Objects (Devices, Locations, Racks, etc.). Each user will need to link their Nautobot Account with their Chat Platform User Account. Login to Nautobot then access the Link ChatOps Account within the Plugins menu. Here you can provide your email address and select the ChatOps Platform you are using, then click the Look up User ID from Email to get your Chat User ID. diff --git a/docs/models/commandtoken.md b/docs/models/commandtoken.md index ef34d1c7..1b10e073 100644 --- a/docs/models/commandtoken.md +++ b/docs/models/commandtoken.md @@ -7,7 +7,7 @@ Some platforms this `signing_secret` is valid for all commands, other platforms, create a separate `token` for every slash command. Keeping the records for Mattermost tokens in the `.creds.env` file would not be sustainable. -To solve this issue, the plugin has the option to store Command Tokens to the Nautobot Database. +To solve this issue, the app has the option to store Command Tokens to the Nautobot Database. In Nautobot, open Nautobot and go to the Plugins and select Command Tokens. Below is an example to get you started. diff --git a/docs/requirements.txt b/docs/requirements.txt index 0da7e270..e3d2c7ec 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,8 +1,6 @@ -griffe==0.30.1 -mkdocs==1.3.1 -mkdocs-material==8.4.2 +mkdocs==1.5.2 +mkdocs-material==9.1.15 mkdocs-version-annotations==1.0.0 +mkdocstrings-python==1.5.2 mkdocstrings==0.22.0 -mkdocstrings-python==1.1.2 -Jinja2==3.0.3 -mkdocs-include-markdown-plugin==3.6.1 \ No newline at end of file +mkdocs-include-markdown-plugin==6.0.3 diff --git a/docs/user/app_getting_started.md b/docs/user/app_getting_started.md index c2da634b..f6c519b3 100644 --- a/docs/user/app_getting_started.md +++ b/docs/user/app_getting_started.md @@ -1,14 +1,14 @@ # Getting Started with the App -A step-by-step tutorial on how to get the App going and how to use it. +This document provides a step-by-step tutorial on how to get the App going and how to use it. ## Install the App -To install the App, please follow the instructions detailed in the [Administrator Guide](../admin/install/index.md). +To install the App, please follow the instructions detailed in the [Administrator Guide](../admin/install.md). ## Link Nautobot Account -+++3.0.0 ++++ 3.0.0 Nautobot ChatOps now uses the built-in Nautobot permissions for Nautobot Objects (Devices, Locations, Racks, etc.). Each user will need to link their Nautobot Account with their Chat Platform User Account. Login to Nautobot then access the Link ChatOps Account within the Plugins menu. Here you can provide your email address and select the ChatOps Platform you are using, then click the Look up User ID from Email to get your Chat User ID. @@ -52,10 +52,11 @@ Interact with Nautobot by utilizing the following sub-commands: The `nautobot-chatops` package includes multiple integrations. Each integration adds chat commands described here: -- [Cisco ACI](./aci_commands.md) -- [AWX / Ansible Tower](./ansible_commands.md) -- [Arista CloudVision](./aristacv_commands.md) -- [Grafana](./grafana_commands.md) -- [IPFabric](./ipfabric_commands.md) -- [Cisco Meraki](./meraki_commands.md) -- [Palo Alto Panorama](./panorama_commands.md) +- [Cisco ACI](./integrations/aci.md) +- [AWX / Ansible Tower](./integrations/ansible.md) +- [Arista CloudVision](./integrations/aristacv.md) +- [Grafana](./integrations/grafana.md) +- [IPFabric](./integrations/ipfabric.md) +- [Cisco Meraki](./integrations/meraki.md) +- [Cisco NSO](./integrations/nso.md) +- [Palo Alto Panorama](./integrations/panorama.md) diff --git a/docs/user/app_overview.md b/docs/user/app_overview.md index b2af3cca..e27cfd55 100644 --- a/docs/user/app_overview.md +++ b/docs/user/app_overview.md @@ -1,10 +1,13 @@ # App Overview -The ChatOps plugin is a Nautobot Plugin that provides a Chatbot framework for Nautobot. +This document provides an overview of the App including critical information and important considerations when applying it to your Nautobot environment. -## Description/Overview +!!! note + Throughout this documentation, the terms "app" and "plugin" will be used interchangeably. -The ChatOps framework provides Network Engineers power to query Nautobot or their Network (through ChatOps plugins) while staying within their preferred Chat application. The goal of ChatOps is to bring people, processes and Automation together. +## Description + +The ChatOps framework provides Network Engineers power to query Nautobot or their Network (through ChatOps apps) while staying within their preferred Chat application. The goal of ChatOps is to bring people, processes and Automation together. {% include-markdown '../glossary.md' diff --git a/docs/user/app_faq.md b/docs/user/faq.md similarity index 100% rename from docs/user/app_faq.md rename to docs/user/faq.md diff --git a/docs/user/aci_commands.md b/docs/user/integrations/aci.md similarity index 82% rename from docs/user/aci_commands.md rename to docs/user/integrations/aci.md index 40e71756..9b6416fa 100644 --- a/docs/user/aci_commands.md +++ b/docs/user/integrations/aci.md @@ -25,16 +25,16 @@ Interact with Cisco ACI by utilizing the following sub-commands: ### Slack -![image](../images/aci-slack-get-tenants.png) +![image](../../images/aci-slack-get-tenants.png) -![image](../images/aci-slack-get-epg-details.png) +![image](../../images/aci-slack-get-epg-details.png) -![image](../images/aci-slack-get-bds.png) +![image](../../images/aci-slack-get-bds.png) ### Cisco Webex -![image](../images/aci-slack-get-tenants.png) +![image](../../images/aci-slack-get-tenants.png) -![image](../images/aci-slack-get-epg-details.png) +![image](../../images/aci-slack-get-epg-details.png) -![image](../images/aci-slack-get-bds.png) +![image](../../images/aci-slack-get-bds.png) diff --git a/docs/user/ansible_commands.md b/docs/user/integrations/ansible.md similarity index 100% rename from docs/user/ansible_commands.md rename to docs/user/integrations/ansible.md diff --git a/docs/user/aristacv_commands.md b/docs/user/integrations/aristacv.md similarity index 88% rename from docs/user/aristacv_commands.md rename to docs/user/integrations/aristacv.md index 8ee52bd9..465cc265 100644 --- a/docs/user/aristacv_commands.md +++ b/docs/user/integrations/aristacv.md @@ -20,8 +20,8 @@ Interact with Arista CloudVision by utilizing the following sub-commands: ## Screenshots -![image](../images/aristacv-get-device-cve.png) +![image](../../images/aristacv-get-device-cve.png) -![image](../images/aristacv-get-configlet.png) +![image](../../images/aristacv-get-configlet.png) -![image](../images/aristacv-get-device-cve.png) +![image](../../images/aristacv-get-device-cve.png) diff --git a/docs/user/grafana_commands.md b/docs/user/integrations/grafana.md similarity index 100% rename from docs/user/grafana_commands.md rename to docs/user/integrations/grafana.md diff --git a/docs/user/ipfabric_commands.md b/docs/user/integrations/ipfabric.md similarity index 73% rename from docs/user/ipfabric_commands.md rename to docs/user/integrations/ipfabric.md index 053c0941..5c98aeb9 100644 --- a/docs/user/ipfabric_commands.md +++ b/docs/user/integrations/ipfabric.md @@ -21,20 +21,20 @@ Interact with IPFabric by utilizing the following sub-commands: !!! note All sub-commands are intended to be used with the `/ipfabric` prefix. -IP Fabric uses a concept of snapshots which can include different devices and data. The plugin supports querying specific snapshots via the `/ipfabric set-snapshot` command. The snapshot is set per user and cached for all future commands. If a snapshot is not set, the commands will default to `$last` unless a specific snapshot id is required. +IP Fabric uses a concept of snapshots which can include different devices and data. The app supports querying specific snapshots via the `/ipfabric set-snapshot` command. The snapshot is set per user and cached for all future commands. If a snapshot is not set, the commands will default to `$last` unless a specific snapshot id is required. ## Screenshots -![image](../images/ipfabric-1.png) +![image](../../images/ipfabric-1.png) -![image](../images/ipfabric-2.png) +![image](../../images/ipfabric-2.png) -![image](../images/ipfabric-3.png) +![image](../../images/ipfabric-3.png) -![image](../images/ipfabric-4.png) +![image](../../images/ipfabric-4.png) -![image](../images/ipfabric-5.png) +![image](../../images/ipfabric-5.png) -![image](../images/ipfabric-6.png) +![image](../../images/ipfabric-6.png) -![image](../images/ipfabric-7.png) +![image](../../images/ipfabric-7.png) diff --git a/docs/user/meraki_commands.md b/docs/user/integrations/meraki.md similarity index 89% rename from docs/user/meraki_commands.md rename to docs/user/integrations/meraki.md index 701f4d88..d114666d 100644 --- a/docs/user/meraki_commands.md +++ b/docs/user/integrations/meraki.md @@ -27,15 +27,15 @@ Interact with Cisco Meraki by utilizing the following sub-commands: Running `/meraki get-organizations`. -![Example output for get-organizations](../images/00-meraki-get-orgs.png) +![Example output for get-organizations](../../images/00-meraki-get-orgs.png) Running `/meraki get-networks`. -![Example output for get-networks](../images/00-meraki-get-networks.png) +![Example output for get-networks](../../images/00-meraki-get-networks.png) Running `/meraki get-switchports-status`. -![Example output for get-networks](../images/00-meraki-get-port-stats.png) +![Example output for get-networks](../../images/00-meraki-get-port-stats.png) Since the output was cut off the output example is below: @@ -62,12 +62,12 @@ To demonstrate a example of configuration updates. There is a simple configurat Specify Org, Switch, and Port ID. -![Example output for config-port0](../images/00-meraki-port-config.png) +![Example output for config-port0](../../images/00-meraki-port-config.png) Fill out the Port Specific Configuration. -![Example output for config-port1](../images/01-meraki-port-config.png) +![Example output for config-port1](../../images/01-meraki-port-config.png) Result of the configuration. -![Example output for config-port2](../images/02-meraki-port-config.png) +![Example output for config-port2](../../images/02-meraki-port-config.png) diff --git a/docs/user/integrations/nso.md b/docs/user/integrations/nso.md new file mode 100644 index 00000000..7280a960 --- /dev/null +++ b/docs/user/integrations/nso.md @@ -0,0 +1,30 @@ +# Cisco NSO Chat Commands + +## `/nso` Command + +Interact with Cisco NSO by utilizing the following sub-commands: + +| Command | Arguments | Description | +| ----------------- | ---------------------------------- | --------------------------------------| +| `ping` | `[device-name]` | Ping a device. | +| `connect` | `[device-name]` | Check device connection with NSO. | +| `check-sync` | `[device-name]` `[compare-config]` | Check sync between current device config and stored in NSO. | +| `run-command-set` | `[device-name]` `[commands]` | Run predefined set of commands on a device. | + +!!! note + All sub-commands are intended to be used with the `/nso` prefix. + +## Screenshots + +![Commands list](../../images/nso-01.png) + +![Ping command](../../images/nso-02.png) + +![Check-sync command](../../images/nso-03.png) + +![Check-sync command, compare config](../../images/nso-04.png) + +![Run remote commands](../../images/nso-05.png) + +![Run remote commands result](../../images/nso-06.png) + diff --git a/docs/user/panorama_commands.md b/docs/user/integrations/panorama.md similarity index 73% rename from docs/user/panorama_commands.md rename to docs/user/integrations/panorama.md index 9eb6e752..a4332e30 100644 --- a/docs/user/panorama_commands.md +++ b/docs/user/integrations/panorama.md @@ -21,20 +21,20 @@ Interact with Palo Alto Panorama by utilizing the following sub-commands: ## Screenshots -![Help](../images/panorama-01.png) +![Help](../../images/panorama-01.png) -![Validate Rule Exists Success](../images/panorama-02.png) +![Validate Rule Exists Success](../../images/panorama-02.png) -![Validate Rule Exists Failure](../images/panorama-03.png) +![Validate Rule Exists Failure](../../images/panorama-03.png) -![Upload Software](../images/panorama-04.png) +![Upload Software](../../images/panorama-04.png) -![Capture Traffic Filter](../images/panorama-05.png) +![Capture Traffic Filter](../../images/panorama-05.png) -![Capture Traffic](../images/panorama-06.png) +![Capture Traffic](../../images/panorama-06.png) -![Get Devices](../images/panorama-07.png) +![Get Devices](../../images/panorama-07.png) -![Get DeviceGroups](../images/panorama-08.png) +![Get Device Groups](../../images/panorama-08.png) -![Get Device Rules](../images/panorama-09.png) +![Get Device Rules](../../images/panorama-09.png) diff --git a/invoke.example.yml b/invoke.example.yml index 90872991..f9e42e74 100644 --- a/invoke.example.yml +++ b/invoke.example.yml @@ -1,9 +1,9 @@ --- nautobot_chatops: project_name: "nautobot-chatops" - nautobot_ver: "1.5.4" + nautobot_ver: "2.0.0" local: false - python_ver: "3.8" + python_ver: "3.11" compose_dir: "development" compose_files: - "docker-compose.base.yml" diff --git a/invoke.mysql.yml b/invoke.mysql.yml index 20cebb59..5002f6c9 100644 --- a/invoke.mysql.yml +++ b/invoke.mysql.yml @@ -1,9 +1,9 @@ --- nautobot_chatops: project_name: "nautobot-chatops" - nautobot_ver: "1.5.4" + nautobot_ver: "2.0.0" local: false - python_ver: "3.8" + python_ver: "3.11" compose_dir: "development" compose_files: - "docker-compose.base.yml" diff --git a/mkdocs.yml b/mkdocs.yml index 0f8d2034..25aec33f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,11 @@ --- dev_addr: "127.0.0.1:8001" -edit_uri: "edit/develop/docs" +edit_uri: "edit/main/nautobot-app-chatops/docs" site_dir: "nautobot_chatops/static/nautobot_chatops/docs" -site_name: "Nautobot ChatOps Documentation" -site_url: "https://docs.nautobot.com/projects/chatops/en/stable/" -repo_url: "https://github.com/nautobot/nautobot-plugin-chatops" -copyright: "Copyright © 2020 Network to Code" +site_name: "Nautobot ChatOps App Documentation" +site_url: "https://docs.nautobot.com/projects/chatops/en/latest/" +repo_url: "https://github.com/nautobot/nautobot-app-chatops" +copyright: "Copyright © The Authors" theme: name: "material" navigation_depth: 4 @@ -14,16 +14,17 @@ theme: - "django" - "yaml" features: - - "navigation.tracking" + - "content.action.edit" + - "content.action.view" + - "content.code.copy" + - "navigation.footer" + - "navigation.indexes" - "navigation.tabs" - "navigation.tabs.sticky" - - "navigation.footer" - - "search.suggest" + - "navigation.tracking" - "search.highlight" - "search.share" - - "navigation.indexes" - - "content.action.edit" - - "content.action.view" + - "search.suggest" favicon: "assets/favicon.ico" logo: "assets/nautobot_logo.svg" palette: @@ -80,11 +81,14 @@ 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" - - "include-markdown" - "mkdocs-version-annotations" - "mkdocstrings": default_handler: "python" @@ -93,6 +97,7 @@ plugins: paths: ["."] options: show_root_heading: true + - "include-markdown" watch: - "README.md" @@ -101,29 +106,32 @@ nav: - User Guide: - App Overview: "user/app_overview.md" - Getting Started: "user/app_getting_started.md" - - Frequently Asked Questions: "user/app_faq.md" + - Frequently Asked Questions: "user/faq.md" - Integrations: - - "user/aci_commands.md" - - "user/ansible_commands.md" - - "user/aristacv_commands.md" - - "user/grafana_commands.md" - - "user/ipfabric_commands.md" - - "user/meraki_commands.md" - - "user/panorama_commands.md" + - "user/integrations/aci.md" + - "user/integrations/ansible.md" + - "user/integrations/aristacv.md" + - "user/integrations/grafana.md" + - "user/integrations/ipfabric.md" + - "user/integrations/meraki.md" + - "user/integrations/panorama.md" + - "user/integrations/nso.md" - Administrator Guide: - - Install and Configure: - - "admin/install/index.md" - - "admin/install/slack_setup.md" - - "admin/install/mattermost_setup.md" - - "admin/install/webex_setup.md" - - "admin/install/microsoft_teams_setup.md" - - "admin/install/aci_setup.md" - - "admin/install/ansible_setup.md" - - "admin/install/aristacv_setup.md" - - "admin/install/grafana_setup.md" - - "admin/install/ipfabric_setup.md" - - "admin/install/meraki_setup.md" - - "admin/install/panorama_setup.md" + - Install and Configure: "admin/install.md" + - Platforms: + - "admin/platforms/slack.md" + - "admin/platforms/mattermost.md" + - "admin/platforms/webex.md" + - "admin/platforms/microsoft_teams.md" + - Integrations: + - "admin/integrations/aci.md" + - "admin/integrations/ansible.md" + - "admin/integrations/aristacv.md" + - "admin/integrations/grafana.md" + - "admin/integrations/ipfabric.md" + - "admin/integrations/meraki.md" + - "admin/integrations/panorama.md" + - "admin/integrations/nso.md" - Upgrade: "admin/upgrade.md" - Uninstall: "admin/uninstall.md" - Compatibility Matrix: "admin/compatibility_matrix.md" @@ -151,6 +159,7 @@ nav: - Glossary: "glossary.md" - Code Reference: - "dev/code_reference/index.md" + - Package: "dev/code_reference/package.md" - Models: "dev/code_reference/models.md" - API: "dev/code_reference/api.md" - Dispatchers: @@ -161,4 +170,5 @@ nav: - "dev/code_reference/mattermost.md" - "models/accessgrant.md" - "models/commandtoken.md" + - "models/chatopsaccountlink.md" - Nautobot Docs Home ↗︎: "https://docs.nautobot.com" diff --git a/nautobot_chatops/__init__.py b/nautobot_chatops/__init__.py index dd1c8c6f..ab18bba1 100644 --- a/nautobot_chatops/__init__.py +++ b/nautobot_chatops/__init__.py @@ -1,15 +1,12 @@ -"""Nautobot plugin implementing a chatbot.""" -try: - from importlib import metadata -except ImportError: - # Python version < 3.8 - import importlib_metadata as metadata - -__version__ = metadata.version(__name__) +"""App declaration for nautobot_chatops.""" +# Metadata is inherited from Nautobot. If not including Nautobot in the environment, this should be added +from importlib import metadata from django.conf import settings from nautobot.apps import ConstanceConfigItem, NautobotAppConfig +__version__ = metadata.version(__name__) + _CONFLICTING_APP_NAMES = [ # App names that conflict with nautobot_chatops @@ -35,7 +32,7 @@ def _check_for_conflicting_apps(): class NautobotChatOpsConfig(NautobotAppConfig): - """Plugin configuration for the nautobot_chatops plugin.""" + """App configuration for the nautobot_chatops app.""" name = "nautobot_chatops" verbose_name = "Nautobot ChatOps" @@ -54,7 +51,7 @@ class NautobotChatOpsConfig(NautobotAppConfig): # Should menus, text input fields, etc. be deleted from the chat history after the user makes a selection? "delete_input_on_submission": False, "restrict_help": False, - # As requested on https://github.com/nautobot/nautobot-plugin-chatops/issues/114 this setting is used for + # As requested on https://github.com/nautobot/nautobot-app-chatops/issues/114 this setting is used for # sending all messages as an ephemeral message, meaning only the person interacting with the bot will see the # responses. "send_all_messages_private": False, @@ -108,7 +105,7 @@ class NautobotChatOpsConfig(NautobotAppConfig): "grafana_default_timespan": "", "grafana_org_id": 1, "grafana_default_tz": "", - # - IPFabric --------------------- + # - IPFabric ------------------------- "ipfabric_api_token": "", "ipfabric_host": "", "ipfabric_timeout": "", @@ -119,6 +116,11 @@ class NautobotChatOpsConfig(NautobotAppConfig): "panorama_host": "", "panorama_password": "", "panorama_user": "", + # - Cisco NSO ------------------------ + "nso_url": "", + "nso_username": "", + "nso_password": "", + "nso_request_timeout": "", } constance_config = { "fallback_chatops_user": ConstanceConfigItem(default="chatbot", help_text="Enable Mattermost Chat Platform."), @@ -132,7 +134,7 @@ class NautobotChatOpsConfig(NautobotAppConfig): "enable_webex": ConstanceConfigItem(default=False, help_text="Enable Webex Chat Platform.", field_type=bool), "enable_aci": ConstanceConfigItem(default=False, help_text="Enable Cisco ACI Integration.", field_type=bool), "enable_ansible": ConstanceConfigItem(default=False, help_text="Enable Ansible Integration.", field_type=bool), - "enable_aristacv": ConstanceConfigItem( + "enable_cloudvision": ConstanceConfigItem( default=False, help_text="Enable Arista CloudVision Integration.", field_type=bool ), "enable_grafana": ConstanceConfigItem(default=False, help_text="Enable Grafana Integration.", field_type=bool), @@ -145,12 +147,13 @@ class NautobotChatOpsConfig(NautobotAppConfig): "enable_panorama": ConstanceConfigItem( default=False, help_text="Enable Panorama Integration.", field_type=bool ), + "enable_nso": ConstanceConfigItem(default=False, help_text="Enable NSO Integration.", field_type=bool), } caching_config = {} def ready(self): - """Function invoked after all plugins have been loaded.""" + """Function invoked after all apps have been loaded.""" super().ready() # pylint: disable=import-outside-toplevel from nautobot_capacity_metrics import register_metric_func diff --git a/nautobot_chatops/admin.py b/nautobot_chatops/admin.py index 917b355d..53b3f889 100644 --- a/nautobot_chatops/admin.py +++ b/nautobot_chatops/admin.py @@ -1,4 +1,4 @@ -"""Administrative capabilities for nautobot_chatops plugin.""" +"""Administrative capabilities for nautobot_chatops app.""" from django.contrib import admin from .models import ChatOpsAccountLink, CommandLog diff --git a/nautobot_chatops/api/__init__.py b/nautobot_chatops/api/__init__.py index e69de29b..f5329948 100644 --- a/nautobot_chatops/api/__init__.py +++ b/nautobot_chatops/api/__init__.py @@ -0,0 +1 @@ +"""REST API module for nautobot_chatops app.""" diff --git a/nautobot_chatops/api/serializers.py b/nautobot_chatops/api/serializers.py index 583095ee..d0cac19d 100644 --- a/nautobot_chatops/api/serializers.py +++ b/nautobot_chatops/api/serializers.py @@ -1,4 +1,4 @@ -"""API Serializers for ChatOps Plugin.""" +"""API Serializers for ChatOps App.""" from rest_framework import serializers diff --git a/nautobot_chatops/api/urls.py b/nautobot_chatops/api/urls.py index a2238616..9443a98d 100644 --- a/nautobot_chatops/api/urls.py +++ b/nautobot_chatops/api/urls.py @@ -1,4 +1,4 @@ -"""Django urlpatterns declaration for nautobot_chatops plugin.""" +"""Django urlpatterns declaration for nautobot_chatops app.""" import logging diff --git a/nautobot_chatops/api/views/__init__.py b/nautobot_chatops/api/views/__init__.py index 86df9e84..1fa340b0 100644 --- a/nautobot_chatops/api/views/__init__.py +++ b/nautobot_chatops/api/views/__init__.py @@ -1,4 +1,4 @@ -"""API Views module for the nautobot_chatops Nautobot plugin. +"""API Views module for the nautobot_chatops Nautobot App. The views implemented in this module act as endpoints for various chat platforms to send requests and notifications to. diff --git a/nautobot_chatops/api/views/ms_teams.py b/nautobot_chatops/api/views/ms_teams.py index f3e10daf..abb75bcc 100644 --- a/nautobot_chatops/api/views/ms_teams.py +++ b/nautobot_chatops/api/views/ms_teams.py @@ -2,6 +2,7 @@ import json import re +import logging import requests import jwt @@ -17,6 +18,8 @@ from nautobot_chatops.utils import check_and_enqueue_command +logger = logging.getLogger(__name__) + APP_ID = settings.PLUGINS_CONFIG["nautobot_chatops"]["microsoft_app_id"] BOT_CONNECTOR_METADATA_URI = "https://login.botframework.com/v1/.well-known/openidconfiguration" @@ -146,11 +149,13 @@ def post(self, request, *args, **kwargs): "bot_name": body["recipient"]["name"], "bot_role": body["recipient"].get("role"), "message_id": body["id"], - "service_url": body["serviceUrl"], + "service_url": body["serviceUrl"].rstrip("/"), "tenant_id": body["channelData"]["tenant"]["id"], "is_group": body["conversation"].get("isGroup", False), } + logger.debug("DEBUG: post context %s", context) + if context["org_id"]: # Get the organization name as well response = requests.get( diff --git a/nautobot_chatops/api/views/webex.py b/nautobot_chatops/api/views/webex.py index 3c449aa3..0e014e52 100644 --- a/nautobot_chatops/api/views/webex.py +++ b/nautobot_chatops/api/views/webex.py @@ -42,7 +42,7 @@ API = None BOT_ID = None -# TODO: the plugin should verify that the webhooks are correctly set up, or else make API calls to create them +# TODO: the app should verify that the webhooks are correctly set up, or else make API calls to create them def generate_signature(request): 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/nautobot_chatops/constants.py b/nautobot_chatops/constants.py index ca668c60..22f46662 100644 --- a/nautobot_chatops/constants.py +++ b/nautobot_chatops/constants.py @@ -1,4 +1,4 @@ -"""Static variables used in plugin.""" +"""Static variables used in app.""" COMMAND_LOG_USER_NAME_HELP_TEXT = "Invoking username" COMMAND_LOG_USER_ID_HELP_TEXT = "Invoking user ID" diff --git a/nautobot_chatops/dispatchers/__init__.py b/nautobot_chatops/dispatchers/__init__.py index 71ff9a0f..f93daef7 100644 --- a/nautobot_chatops/dispatchers/__init__.py +++ b/nautobot_chatops/dispatchers/__init__.py @@ -1,4 +1,4 @@ -"""Dispatchers module for the nautobot_chatops Nautobot plugin. +"""Dispatchers module for the nautobot_chatops Nautobot App. The classes implemented in this module implement a common API for "dispatching" content (plaintext messages, formatted text, UI elements, etc.) to the user of a given chat platform. diff --git a/nautobot_chatops/dispatchers/adaptive_cards.py b/nautobot_chatops/dispatchers/adaptive_cards.py index d325c59d..e1dd5ff3 100644 --- a/nautobot_chatops/dispatchers/adaptive_cards.py +++ b/nautobot_chatops/dispatchers/adaptive_cards.py @@ -201,7 +201,7 @@ def select_element(self, action_id, choices, default=(None, None), confirm=False Args: action_id (str): Identifying string to associate with this element choices (list): List of (display, value) tuples - default (tuple: Default (display, value) to preselect + default (tuple): Default (display, value) to preselect confirm (bool): If true (and the platform supports it), prompt the user to confirm their selection """ return { diff --git a/nautobot_chatops/dispatchers/base.py b/nautobot_chatops/dispatchers/base.py index 6204a378..2bbf4836 100644 --- a/nautobot_chatops/dispatchers/base.py +++ b/nautobot_chatops/dispatchers/base.py @@ -53,7 +53,7 @@ def user(self): ).nautobot_user except ObjectDoesNotExist: logger.warning( - "Could not find User matching %s - id: %s." "Add a ChatOps User to link the accounts.", + "Could not find User matching %s - id: %s. Add a ChatOps User to link the accounts.", self.context["user_name"], self.context["user_id"], ) @@ -64,7 +64,7 @@ def user(self): return user def _get_cache_key(self) -> str: - """Key generator for the cache, adding the plugin prefix name.""" + """Key generator for the cache, adding the app prefix name.""" # Using __file__ as a key customization within the cache return "-".join([__file__, self.context.get("user_id", "generic")]) @@ -240,7 +240,6 @@ def multi_input_dialog(self, command, sub_command, dialog_title, dialog_list): """ raise NotImplementedError - # pylint: disable=no-self-use def needs_permission_to_send_image(self): """Return True if this bot needs to ask the user for permission to post an image.""" return False @@ -326,17 +325,14 @@ def user_mention(self): """Markup for a mention of the username/userid specified in our context.""" raise NotImplementedError - # pylint: disable=no-self-use def bold(self, text): """Mark text as bold.""" return f"**{text}**" - # pylint: disable=no-self-use def hyperlink(self, text, url): """Create Hyperlinks.""" return f"[{text}]({url})" - # pylint: disable=no-self-use def monospace(self, text): """Mark text as monospace.""" return f"`{text}`" @@ -367,7 +363,7 @@ def select_element(self, action_id, choices, default=(None, None), confirm=False Args: action_id (str): Identifying string to associate with this element choices (list): List of (display, value) tuples - default (tuple: Default (display, value) to preselect + default (tuple): Default (display, value) to preselect confirm (bool): If true (and the platform supports it), prompt the user to confirm their selection """ raise NotImplementedError diff --git a/nautobot_chatops/dispatchers/mattermost.py b/nautobot_chatops/dispatchers/mattermost.py index bc111dd6..5303f2a1 100644 --- a/nautobot_chatops/dispatchers/mattermost.py +++ b/nautobot_chatops/dispatchers/mattermost.py @@ -606,7 +606,6 @@ def actions_block(self, block_id, actions): # Leaving in place to pass the testing. return {"block_id": block_id, "actions": actions} - # pylint: disable=no-self-use def _input_block(self, block_id, label, element): """Construct a block consisting of Input elements.""" element["display_name"] = label diff --git a/nautobot_chatops/dispatchers/ms_teams.py b/nautobot_chatops/dispatchers/ms_teams.py index d49a9919..563461fb 100644 --- a/nautobot_chatops/dispatchers/ms_teams.py +++ b/nautobot_chatops/dispatchers/ms_teams.py @@ -39,12 +39,13 @@ def user(self): """Dispatcher property containing the Nautobot User that is linked to the Chat User.""" if self.context.get("user_ad_id"): try: + logger.debug("DEBUG: user() - Found ChatOps user - %s", self.context["user_name"]) return ChatOpsAccountLink.objects.get( platform=self.platform_slug, user_id=self.context["user_ad_id"] ).nautobot_user except ObjectDoesNotExist: logger.warning( - "Could not find User matching %s - id: %s." "Add a ChatOps User to link the accounts.", + "Could not find User matching %s - id: %s. Add a ChatOps User to link the accounts.", self.context["user_name"], self.context["user_ad_id"], ) @@ -135,6 +136,7 @@ def lookup_user_id_by_email(cls, email) -> Optional[str]: def _send(self, content, content_type="message"): """Publish content back to Microsoft Teams.""" + logger.debug("DEBUG: _send() - updating content with %s", self.context) content = content.copy() content.update( { @@ -154,12 +156,22 @@ def _send(self, content, content_type="message"): "replyToId": self.context["message_id"], } ) + logger.debug("DEBUG: _send() - Sending response back to MSTeams") + logger.debug("DEBUG: _send() - Sending content with %s", content) + logger.debug( + "DEBUG: _send() - Sending to URL %s/v3/conversations/%s/activities", + self.context["service_url"], + self.context["conversation_id"], + ) response = requests.post( f"{self.context['service_url']}/v3/conversations/{self.context['conversation_id']}/activities", headers={"Authorization": f"Bearer {self.get_token()}"}, json=content, timeout=15, ) + logger.debug("DEBUG: _send() response %s", response.status_code) + logger.debug("DEBUG: _send() reason %s", response.reason) + response.raise_for_status() return response def send_large_table(self, header, rows, title=None): @@ -222,11 +234,13 @@ def ask_permission_to_send_image(self, filename, action_id): @BACKEND_ACTION_MARKDOWN.time() def send_markdown(self, message, ephemeral=None): """Send a markdown-formatted text message to the user/channel specified by the context.""" + logger.debug("DEBUG: send_markdown() Sending message = %s", message) self._send({"text": message, "textFormat": "markdown"}) @BACKEND_ACTION_BLOCKS.time() def send_blocks(self, blocks, callback_id=None, modal=False, ephemeral=None, title=None): """Send a series of formatting blocks to the user/channel specified by the context.""" + logger.debug("DEBUG: send_blocks() Sending Blocks = %s", blocks) if title and title not in str(blocks[0]): blocks.insert(0, self.markdown_element(self.bold(title))) self._send( diff --git a/nautobot_chatops/dispatchers/slack.py b/nautobot_chatops/dispatchers/slack.py index c52d29aa..82ce52fc 100644 --- a/nautobot_chatops/dispatchers/slack.py +++ b/nautobot_chatops/dispatchers/slack.py @@ -315,7 +315,6 @@ def send_exception(self, exception): text=f"Sorry @{self.context.get('user_name')}, an error occurred :sob:\n```{exception}```", ) - # pylint: disable=no-self-use def delete_message(self, response_url): """Delete a message that was previously sent.""" WebhookClient(response_url).send_dict({"delete_original": "true"}) @@ -506,7 +505,7 @@ def select_element(self, action_id, choices, default=(None, None), confirm=False Args: action_id (str): Identifying string to associate with this element choices (list): List of (display, value) tuples - default (tuple: Default (display, value) to preselect + default (tuple): Default (display, value) to preselect confirm (bool): If true (and the platform supports it), prompt the user to confirm their selection """ data = { diff --git a/nautobot_chatops/integrations/__init__.py b/nautobot_chatops/integrations/__init__.py index e69de29b..9c158ba0 100644 --- a/nautobot_chatops/integrations/__init__.py +++ b/nautobot_chatops/integrations/__init__.py @@ -0,0 +1 @@ +"""Nautobot ChatOps Integrations.""" diff --git a/nautobot_chatops/integrations/aci/aci.py b/nautobot_chatops/integrations/aci/aci.py index 247a4694..572401fa 100644 --- a/nautobot_chatops/integrations/aci/aci.py +++ b/nautobot_chatops/integrations/aci/aci.py @@ -204,6 +204,7 @@ def get_static_path(self, tenant: str, ap: str, epg: str) -> list: ) sp_list = [] for obj in resp.json()["imdata"]: + # pylint: disable-next=use-dict-literal sp_dict = dict(encap=obj["fvRsPathAtt"]["attributes"]["encap"]) # pylint: disable-next=invalid-name tDn = obj["fvRsPathAtt"]["attributes"]["tDn"] @@ -273,6 +274,7 @@ def get_static_path(self, tenant: str, ap: str, epg: str) -> list: def get_epg_details(self, tenant: str, ap: str, epg: str) -> dict: """Return EPG configuration details.""" resp = self._get(f"/api/node/mo/uni/tn-{tenant}/ap-{ap}/epg-{epg}.json?query-target=children") + # pylint: disable-next=use-dict-literal epg_dict = dict(bd=None, subnets=[], provided_contracts=[], consumed_contracts=[], domains=[], static_paths=[]) epg_dict["name"] = epg for obj in resp.json()["imdata"]: @@ -281,6 +283,7 @@ def get_epg_details(self, tenant: str, ap: str, epg: str) -> dict: epg_dict["subnets"] = self.get_bd_subnet(tenant, epg_dict["bd"]) if "fvRsCons" in obj: epg_dict["consumed_contracts"].append( + # pylint: disable-next=use-dict-literal dict( name=obj["fvRsCons"]["attributes"]["tnVzBrCPName"], filters=self.get_contract_filters(tenant, obj["fvRsCons"]["attributes"]["tnVzBrCPName"]), @@ -288,6 +291,7 @@ def get_epg_details(self, tenant: str, ap: str, epg: str) -> dict: ) if "fvRsProv" in obj: epg_dict["provided_contracts"].append( + # pylint: disable-next=use-dict-literal dict( name=obj["fvRsProv"]["attributes"]["tnVzBrCPName"], filters=self.get_contract_filters(tenant, obj["fvRsProv"]["attributes"]["tnVzBrCPName"]), diff --git a/nautobot_chatops/integrations/aci/worker.py b/nautobot_chatops/integrations/aci/worker.py index 71c8288b..cb2652bf 100644 --- a/nautobot_chatops/integrations/aci/worker.py +++ b/nautobot_chatops/integrations/aci/worker.py @@ -36,7 +36,7 @@ def _read_settings(): @nautobot_task def aci(subcommand, **kwargs): - """Interact with aci plugin.""" + """Interact with aci app.""" return handle_subcommands("aci", subcommand, **kwargs) diff --git a/nautobot_chatops/integrations/ansible/tower.py b/nautobot_chatops/integrations/ansible/tower.py index 4f69ffdc..a8d07914 100644 --- a/nautobot_chatops/integrations/ansible/tower.py +++ b/nautobot_chatops/integrations/ansible/tower.py @@ -6,10 +6,12 @@ from django.conf import settings import requests -logger = logging.getLogger("rq.worker") +logger = logging.getLogger(__name__) _CONFIG = settings.PLUGINS_CONFIG["nautobot_chatops"] +DEFAULT_TIMEOUT = 20 + def _get_uri(uri): """Validate URI schema and no trailing slash. @@ -57,9 +59,7 @@ def __init__( self.origin = origin self.extra_vars = {} if not self.uri or not self.username or not self.password: - raise ValueError( - "Missing required parameters for Tower access - check environment and plugin configuration" - ) + raise ValueError("Missing required parameters for Tower access - check environment and app configuration") def _launch_job(self, template_name, extra_vars): """Launch a playbook in Ansible Tower. @@ -79,6 +79,7 @@ def _launch_job(self, template_name, extra_vars): headers=self.headers, data=json.dumps({"extra_vars": extra_vars}), verify=self.tower_verify_ssl, # nosec + timeout=DEFAULT_TIMEOUT, ) response.raise_for_status() logger.info("Job submission to Ansible Tower:") @@ -100,6 +101,7 @@ def _get_tower(self, api_path, **kwargs): auth=(self.username, self.password), **kwargs, verify=self.tower_verify_ssl, # nosec + timeout=DEFAULT_TIMEOUT, ) return response.json() diff --git a/nautobot_chatops/integrations/aristacv/__init__.py b/nautobot_chatops/integrations/cloudvision/__init__.py similarity index 100% rename from nautobot_chatops/integrations/aristacv/__init__.py rename to nautobot_chatops/integrations/cloudvision/__init__.py diff --git a/nautobot_chatops/integrations/aristacv/cvpgrpcutils.py b/nautobot_chatops/integrations/cloudvision/cvpgrpcutils.py similarity index 95% rename from nautobot_chatops/integrations/aristacv/cvpgrpcutils.py rename to nautobot_chatops/integrations/cloudvision/cvpgrpcutils.py index 9e1d0da5..7a0ca77d 100644 --- a/nautobot_chatops/integrations/aristacv/cvpgrpcutils.py +++ b/nautobot_chatops/integrations/cloudvision/cvpgrpcutils.py @@ -25,7 +25,10 @@ def connect_cv(settings): cert = bytes(ssl.get_server_certificate((cvp_host, 8443)), "utf-8") channel_creds = grpc.ssl_channel_credentials(cert) response = requests.post( - f"https://{cvp_host}/cvpservice/login/authenticate.do", auth=(username, password), verify=False # nosec + f"https://{cvp_host}/cvpservice/login/authenticate.do", + auth=(username, password), + verify=False, # nosec + timeout=DEFAULT_TIMEOUT, ) # Otherwise, the server is expected to have a valid certificate signed by a well-known CA. else: diff --git a/nautobot_chatops/integrations/aristacv/utils.py b/nautobot_chatops/integrations/cloudvision/utils.py similarity index 99% rename from nautobot_chatops/integrations/aristacv/utils.py rename to nautobot_chatops/integrations/cloudvision/utils.py index 70ff1818..456987f3 100644 --- a/nautobot_chatops/integrations/aristacv/utils.py +++ b/nautobot_chatops/integrations/cloudvision/utils.py @@ -560,6 +560,7 @@ def get_token_crt(): f"https://{CVP_HOST}/cvpservice/login/authenticate.do", auth=(CVP_USERNAME, CVP_PASSWORD), verify=False, # nosec + timeout=DEFAULT_TIMEOUT, ) else: request = requests.post( diff --git a/nautobot_chatops/integrations/aristacv/worker.py b/nautobot_chatops/integrations/cloudvision/worker.py similarity index 99% rename from nautobot_chatops/integrations/aristacv/worker.py rename to nautobot_chatops/integrations/cloudvision/worker.py index f2b05c05..27b50ddf 100644 --- a/nautobot_chatops/integrations/aristacv/worker.py +++ b/nautobot_chatops/integrations/cloudvision/worker.py @@ -33,7 +33,7 @@ ) -logger = logging.getLogger("rq.worker") +logger = logging.getLogger(__name__) dir_path = os.path.dirname(os.path.realpath(__file__)) CLOUDVISION_LOGO_PATH = "nautobot_cloudvision/cloudvision_logo.png" CLOUDVISION_LOGO_ALT = "CloudVision Logo" diff --git a/nautobot_chatops/integrations/grafana/__init__.py b/nautobot_chatops/integrations/grafana/__init__.py index e69de29b..10a07da3 100644 --- a/nautobot_chatops/integrations/grafana/__init__.py +++ b/nautobot_chatops/integrations/grafana/__init__.py @@ -0,0 +1 @@ +"""Nautobot ChatOps Graphana Integration.""" diff --git a/nautobot_chatops/integrations/grafana/api/urls.py b/nautobot_chatops/integrations/grafana/api/urls.py index 1e2a5c67..2ccef219 100644 --- a/nautobot_chatops/integrations/grafana/api/urls.py +++ b/nautobot_chatops/integrations/grafana/api/urls.py @@ -1,4 +1,4 @@ -"""Django urlpatterns declaration for nautobot_chatops.integrations.grafana plugin.""" +"""Django urlpatterns declaration for nautobot_chatops.integrations.grafana app.""" from nautobot.apps.api import OrderedDefaultRouter from nautobot.apps.config import get_app_settings_or_config diff --git a/nautobot_chatops/integrations/grafana/api/views/__init__.py b/nautobot_chatops/integrations/grafana/api/views/__init__.py index 85c920fb..752d6639 100644 --- a/nautobot_chatops/integrations/grafana/api/views/__init__.py +++ b/nautobot_chatops/integrations/grafana/api/views/__init__.py @@ -1,4 +1,4 @@ -"""API Views module for the nautobot_chatops.integrations.grafana Nautobot plugin. +"""API Views module for the nautobot_chatops.integrations.grafana Nautobot App. The views implemented in this module act as endpoints for various chat platforms to send requests and notifications to. diff --git a/nautobot_chatops/integrations/grafana/api/views/generic.py b/nautobot_chatops/integrations/grafana/api/views/generic.py index 4fdad892..da24c2cb 100644 --- a/nautobot_chatops/integrations/grafana/api/views/generic.py +++ b/nautobot_chatops/integrations/grafana/api/views/generic.py @@ -1,4 +1,4 @@ -"""API Views for Nautobot Plugin Chatops Grafana.""" +"""API Views for Nautobot App Chatops Grafana.""" from rest_framework.routers import APIRootView diff --git a/nautobot_chatops/integrations/grafana/exceptions.py b/nautobot_chatops/integrations/grafana/exceptions.py index 6763f514..38975e7d 100644 --- a/nautobot_chatops/integrations/grafana/exceptions.py +++ b/nautobot_chatops/integrations/grafana/exceptions.py @@ -1,4 +1,4 @@ -"""Nautobot Plugin ChatOps Grafana Exceptions.""" +"""Nautobot App ChatOps Grafana Exceptions.""" from pydantic import ValidationError from isodate import ISO8601Error diff --git a/nautobot_chatops/integrations/grafana/filters.py b/nautobot_chatops/integrations/grafana/filters.py index be7bf0c0..51e4aa6b 100644 --- a/nautobot_chatops/integrations/grafana/filters.py +++ b/nautobot_chatops/integrations/grafana/filters.py @@ -18,7 +18,7 @@ class Meta: fields = ("dashboard_slug", "dashboard_uid", "friendly_name") - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Perform the filtered search.""" if not value.strip(): return queryset @@ -40,7 +40,7 @@ class Meta: fields = ("dashboard", "command_name", "friendly_name", "panel_id") - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Perform the filtered search.""" if not value.strip(): return queryset @@ -66,7 +66,7 @@ class Meta: fields = ("panel", "name", "friendly_name", "query", "modelattr", "value", "response") - def search(self, queryset, name, value): # pylint: disable=unused-argument,no-self-use + def search(self, queryset, name, value): # pylint: disable=unused-argument """Perform the filtered search.""" if not value.strip(): return queryset diff --git a/nautobot_chatops/integrations/grafana/tables.py b/nautobot_chatops/integrations/grafana/tables.py index 06ef8ce5..a8f9ec67 100644 --- a/nautobot_chatops/integrations/grafana/tables.py +++ b/nautobot_chatops/integrations/grafana/tables.py @@ -6,7 +6,7 @@ class DashboardViewTable(BaseTable): - """Table for rendering panels for dashboards in the grafana plugin.""" + """Table for rendering panels for dashboards in the grafana app.""" pk = ToggleColumn() @@ -20,7 +20,7 @@ class Meta(BaseTable.Meta): # pylint: disable=too-few-public-methods class PanelViewTable(BaseTable): - """Table for rendering panels for dashboards in the grafana plugin.""" + """Table for rendering panels for dashboards in the grafana app.""" pk = ToggleColumn() @@ -40,7 +40,7 @@ class Meta(BaseTable.Meta): # pylint: disable=too-few-public-methods class PanelVariableViewTable(BaseTable): - """Table for rendering panel variables for dashboards in the grafana plugin.""" + """Table for rendering panel variables for dashboards in the grafana app.""" pk = ToggleColumn() diff --git a/nautobot_chatops/integrations/grafana/urls.py b/nautobot_chatops/integrations/grafana/urls.py index 96c67b7e..1f1f7b25 100644 --- a/nautobot_chatops/integrations/grafana/urls.py +++ b/nautobot_chatops/integrations/grafana/urls.py @@ -1,4 +1,4 @@ -"""Django urlpatterns declaration for nautobot_chatops.integrations.grafana plugin.""" +"""Django urlpatterns declaration for nautobot_chatops.integrations.grafana app.""" from django.urls import path from nautobot.extras.views import ObjectChangeLogView from nautobot_chatops.integrations.grafana.models import Dashboard, PanelVariable, Panel diff --git a/nautobot_chatops/integrations/grafana/views.py b/nautobot_chatops/integrations/grafana/views.py index 1ae3a045..09fbc5bc 100644 --- a/nautobot_chatops/integrations/grafana/views.py +++ b/nautobot_chatops/integrations/grafana/views.py @@ -1,4 +1,4 @@ -"""Views module for the nautobot_chatops.integrations.grafana plugin. +"""Views module for the nautobot_chatops.integrations.grafana App. The views implemented in this module act as endpoints for various chat platforms to send requests and notifications to. diff --git a/nautobot_chatops/integrations/ipfabric/context.py b/nautobot_chatops/integrations/ipfabric/context.py index 2cff7ab2..b8e2f38b 100644 --- a/nautobot_chatops/integrations/ipfabric/context.py +++ b/nautobot_chatops/integrations/ipfabric/context.py @@ -5,7 +5,7 @@ def _get_cache_key(user: str) -> str: - """Key generator for the cache, adding the plugin prefix name.""" + """Key generator for the cache, adding the app prefix name.""" key_string = "-".join([NautobotChatOpsConfig.name, user]) return hashlib.md5(key_string.encode("utf-8")).hexdigest() # nosec diff --git a/nautobot_chatops/integrations/ipfabric/worker.py b/nautobot_chatops/integrations/ipfabric/worker.py index a9dda45b..4957336d 100644 --- a/nautobot_chatops/integrations/ipfabric/worker.py +++ b/nautobot_chatops/integrations/ipfabric/worker.py @@ -51,7 +51,7 @@ def ipfabric_logo(dispatcher): def ipfabric(subcommand, **kwargs): - """Interact with ipfabric plugin.""" + """Interact with ipfabric app.""" return handle_subcommands("ipfabric", subcommand, **kwargs) diff --git a/nautobot_chatops/integrations/meraki/worker.py b/nautobot_chatops/integrations/meraki/worker.py index 5b71502a..6d08f2c2 100644 --- a/nautobot_chatops/integrations/meraki/worker.py +++ b/nautobot_chatops/integrations/meraki/worker.py @@ -28,6 +28,7 @@ except KeyError as err: MERAKI_DASHBOARD_API_KEY = os.getenv("MERAKI_DASHBOARD_API_KEY") if not MERAKI_DASHBOARD_API_KEY: + # pylint: disable-next=broad-exception-raised raise Exception("Unable to find the Meraki API key.") from err @@ -570,6 +571,7 @@ def configure_basic_access_port( # pylint: disable=too-many-arguments dialog_list=dialog_list, ) return False + # pylint: disable-next=use-dict-literal port_params = dict(name=port_desc, enabled=bool(enabled), type="access", vlan=vlan) LOGGER.info("PORT PARMS: %s", port_params) client = MerakiClient(api_key=MERAKI_DASHBOARD_API_KEY) diff --git a/nautobot_chatops/integrations/nso/__init__.py b/nautobot_chatops/integrations/nso/__init__.py new file mode 100644 index 00000000..d5aa34f2 --- /dev/null +++ b/nautobot_chatops/integrations/nso/__init__.py @@ -0,0 +1 @@ +"""Nautobot ChatOps NSO Integration.""" diff --git a/nautobot_chatops/integrations/nso/exceptions.py b/nautobot_chatops/integrations/nso/exceptions.py new file mode 100644 index 00000000..dd637295 --- /dev/null +++ b/nautobot_chatops/integrations/nso/exceptions.py @@ -0,0 +1,17 @@ +"""Custom Exceptions for the nautobot_chatops.integrations.nso plugin.""" + + +class CommunicationError(Exception): + """Error communicating with NSO.""" + + +class DeviceNotFound(Exception): + """Device not found in NSO.""" + + +class DeviceNotSupported(Exception): + """Device not supported in NSO.""" + + +class DeviceLocked(Exception): + """Device not reachable in NSO.""" diff --git a/nautobot_chatops/integrations/nso/jinja_filters.py b/nautobot_chatops/integrations/nso/jinja_filters.py new file mode 100644 index 00000000..50688bf0 --- /dev/null +++ b/nautobot_chatops/integrations/nso/jinja_filters.py @@ -0,0 +1,14 @@ +"""Custom filters for nautobot_chatops.integrations.nso.""" +from django_jinja import library +from nautobot_chatops.integrations.nso.nso import NSOClient + + +@library.filter +def get_nso_sync_status(device_name): + """Pull NSO sync status for specified device.""" + nso = NSOClient() + try: + response = nso.sync_status(device_name) + return response + except Exception: # pylint: disable=W0703 + return "N/A" diff --git a/nautobot_chatops/integrations/nso/nso.py b/nautobot_chatops/integrations/nso/nso.py new file mode 100644 index 00000000..a4a9b77c --- /dev/null +++ b/nautobot_chatops/integrations/nso/nso.py @@ -0,0 +1,215 @@ +"""All interactions with nso.""" + +import logging +import requests +from django.conf import settings +from rest_framework import status + +from nautobot_chatops.integrations.nso.exceptions import ( + CommunicationError, + DeviceNotFound, + DeviceNotSupported, + DeviceLocked, +) + + +logger = logging.getLogger("nautobot.plugin.nso") + +# Import config vars from nautobot_config.py +PLUGIN_SETTINGS = settings.PLUGINS_CONFIG["nautobot_chatops"] + +SLASH_COMMAND = "nso" +REQUEST_TIMEOUT_SEC = PLUGIN_SETTINGS["nso_request_timeout"] + +NSO_URL = PLUGIN_SETTINGS["nso_url"] +NSO_USERNAME = PLUGIN_SETTINGS["nso_username"] +NSO_PASSWORD = PLUGIN_SETTINGS["nso_password"] + + +class NSOClient: + """Representation and methods for interacting with nso.""" + + def __init__(self, url=NSO_URL, username=NSO_USERNAME, password=NSO_PASSWORD): + """Initialization of nso class.""" + self.url = url + self.auth = (username, password) + self.headers = {"Accept": "application/yang-data+json", "Content-Type": "application/yang-data+json"} + + @property + def base_url(self): + """Base URL for RESTCONF.""" + return f"{self.url}/restconf/data" + + def __device_operation(self, device, operation): + """Basic device operations. + + Args: + device (str): Device name + operation (str): Device operation, such as ping, connect, sync-to + + Returns: + The response. + + Raises: + CommunicationError: Raises an exception when response code != 200 or 404. + DeviceNotFound: Raises an exception when response code == 404. + """ + url = f"{self.base_url}/tailf-ncs:devices/device={device}/{operation}" + + response = requests.post(url, headers=self.headers, auth=self.auth, timeout=REQUEST_TIMEOUT_SEC) + + if response.ok: + json_response = response.json() + out = json_response.get("tailf-ncs:output", {}) + if "result" in out: + return out["result"] + if "diff" in out: + return out["diff"] + return out + if response.status_code == status.HTTP_404_NOT_FOUND: + json_response = response.json() + out = json_response.get("ietf-restconf:errors", {}) + if "error" in out: + if "error-message" in out["error"][0]: + if out["error"][0]["error-message"] == "uri keypath not found": + raise DeviceNotFound(f"Device {device} does not exist in NSO") + raise CommunicationError(f"Error communicating to NSO! ({response.status_code})") + + def ping(self, device): + """Ping device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "ping") + + def connect(self, device): + """Connect device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "connect") + + def sync_to(self, device): + """Sync to device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "sync-to") + + def sync_from(self, device): + """Sync from device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "sync-from") + + def sync_status(self, device): + """Check sync device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "check-sync") + + def sync_status_all(self): + """Check sync of all devices operation. + + Returns: + The response. + + Raises: + CommunicationError: Raises an exception when response code != 200. + """ + url = f"{self.base_url}/tailf-ncs:devices/check-sync" + + response = requests.post(url, headers=self.headers, auth=self.auth, timeout=REQUEST_TIMEOUT_SEC) + + if response.ok: + json_response = response.json() + out = json_response.get("tailf-ncs:output", {}) + if "sync-result" in out: + return out["sync-result"] + return out + raise CommunicationError(f"Error communicating to NSO! ({response.status_code})") + + def compare_config(self, device): + """Compare config device operation. + + Args: + device (str): Device name + + Returns: + The response. + """ + return self.__device_operation(device, "compare-config") + + def live_status(self, device, command): + """Executes a show command. + + Args: + device (str): Device name + command (str): The show command + + Returns: + The response. + """ + # Get device type + url = f"{self.base_url}/tailf-ncs:devices/device={device}/device-type" + response = requests.get(url, headers=self.headers, auth=self.auth, timeout=REQUEST_TIMEOUT_SEC) + + if not response.ok: + json_response = response.json() + out = json_response.get("ietf-restconf:errors", {}) + if "error" in out: + if "error-message" in out["error"][0]: + if out["error"][0]["error-message"] == "uri keypath not found": + raise DeviceNotFound(f"Device {device} does not exist in NSO") + raise CommunicationError(f"Error communicating to NSO! ({response.status_code})") + + json_response = response.json() + ned_id = json_response["tailf-ncs:device-type"]["cli"]["ned-id"] + if "nx" in ned_id: + ned_id_live = "tailf-ned-cisco-nx-stats" + elif "ios" in ned_id: + ned_id_live = "tailf-ned-cisco-ios-stats" + else: + raise DeviceNotSupported(f"Device type is not supported! ({ned_id})") + + url = f"{self.base_url}/tailf-ncs:devices/device={device}" + url += f"/live-status/{ned_id_live}:exec/show" + + command = command.replace("show ", "") + body = {"input": {"args": command}} + + response = requests.post(url, headers=self.headers, auth=self.auth, json=body, timeout=REQUEST_TIMEOUT_SEC) + + if response.ok: + json_response = response.json() + return json_response[f"{ned_id_live}:output"]["result"] + if response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR: + json_response = response.json() + out = json_response.get("ietf-restconf:errors", {}) + if "error" in out: + if "error-message" in out["error"][0]: + if "southbound locked" in out["error"][0]["error-message"]: + raise DeviceLocked(f"Device {device} is southbound locked") + raise CommunicationError(f"Error communicating to NSO! ({response.status_code})") diff --git a/nautobot_chatops/integrations/nso/worker.py b/nautobot_chatops/integrations/nso/worker.py new file mode 100644 index 00000000..2da09bb2 --- /dev/null +++ b/nautobot_chatops/integrations/nso/worker.py @@ -0,0 +1,246 @@ +"""Worker functions implementing Nautobot "nso" command and subcommands.""" +from django.core.exceptions import ObjectDoesNotExist +from nautobot.dcim.models import Device +from nautobot.core.settings_funcs import is_truthy + +from nautobot_chatops.choices import CommandStatusChoices +from nautobot_chatops.workers import handle_subcommands, subcommand_of +from nautobot_chatops.integrations.nso.nso import NSOClient, REQUEST_TIMEOUT_SEC, SLASH_COMMAND + + +def nso_logo(dispatcher): + """Construct an image_element containing the locally hosted Cisco NSO logo.""" + return dispatcher.image_element(dispatcher.static_url("nso/nso-logo.png"), alt_text="Cisco NSO Logo") + + +def nso(subcommand, **kwargs): + """Interact with nso plugin.""" + return handle_subcommands("nso", subcommand, **kwargs) + + +@subcommand_of("nso") +def ping(dispatcher, device_name=None): + """Ping a device.""" + if not device_name: + devices = Device.objects.all() + choices = [(device.name, device.name) for device in devices] + dispatcher.prompt_from_menu("nso ping", "Select a device.", choices) + return False + + nso_client = NSOClient() + ping_result = nso_client.ping(device_name) + + if "100% packet loss" in ping_result: + dispatcher.send_markdown(f"❌ NSO Ping of Device {device_name} failed.") + return CommandStatusChoices.STATUS_FAILED + if "Device does not exist in NSO" in ping_result: + dispatcher.send_markdown(f"❌ Device {device_name} doesn't exist in NSO.") + return CommandStatusChoices.STATUS_FAILED + dispatcher.send_markdown(f"✅ NSO Ping of Device {device_name} was successful.") + return CommandStatusChoices.STATUS_SUCCEEDED + + +@subcommand_of("nso") +def connect(dispatcher, device_name=None): + """Get connect status of device.""" + if not device_name: + devices = Device.objects.all() + choices = [(device.name, device.name) for device in devices] + dispatcher.prompt_from_menu("nso connect", "Select a device.", choices) + return False + + nso_client = NSOClient() + ping_result = nso_client.connect(device_name) + + if not ping_result: + dispatcher.send_markdown(f"❌ NSO Connection to Device {device_name} failed.") + return CommandStatusChoices.STATUS_FAILED + if "Device does not exist in NSO" in str(ping_result): + dispatcher.send_markdown(f"❌ Device {device_name} does not exist in NSO.") + return CommandStatusChoices.STATUS_FAILED + dispatcher.send_markdown(f"✅ NSO Connection to Device {device_name} was successful.") + return CommandStatusChoices.STATUS_SUCCEEDED + + +@subcommand_of("nso") +def check_sync(dispatcher, device_name=None, compare_config=None): + """Get sync status of device.""" + nso_client = NSOClient() + + if not device_name: + devices = Device.objects.all() + choices = [(device.name, device.name) for device in devices] + choices.insert(0, ("all", "all")) + + dispatcher.prompt_from_menu("nso check-sync", "Select a device.", choices) + return False + + if device_name == "all": + dispatcher.send_markdown(f"Stand by {dispatcher.user_mention()}, I'm getting that sync status report for you.") + sync_data = nso_client.sync_status_all() + + dispatcher.send_blocks( + [ + *dispatcher.command_response_header( + "nso", "check_sync", [("Device Name", device_name)], "information", nso_logo(dispatcher) + ) + ] + ) + + header = ["Device Name", "NSO Sync Status"] + rows = [(item["device"], item["result"]) for item in sync_data] + + dispatcher.send_large_table(header, rows) + return CommandStatusChoices.STATUS_SUCCEEDED + + # If user chose to compare config on the device and NSO, return compare_config + if device_name and compare_config: + if is_truthy(compare_config): + dispatcher.send_markdown(f"Checking configuration of device {device_name}.") + compared_config = nso_client.compare_config(device_name) + if len(compared_config) < 1000: + dispatcher.send_markdown(f"```{compared_config}\n```") + else: + dispatcher.send_snippet(compared_config) + else: + dispatcher.send_warning("Device configuration will not be checked.") + return CommandStatusChoices.STATUS_SUCCEEDED + + # Check sync status for chosen device + sync_status = nso_client.sync_status(device_name) + + if sync_status == "in-sync": + dispatcher.send_markdown(f"✅ Device {device_name} configuration is in sync with NSO.") + return CommandStatusChoices.STATUS_SUCCEEDED + + if sync_status == "out-of-sync": + dispatcher.send_markdown(f"❌ Device {device_name} configuration is out of sync with NSO.") + dispatcher.prompt_from_menu( + f"nso check-sync {device_name}", "Would you like to compare the config?", [("Yes", "Yes"), ("No", "No")] + ) + return False + + dispatcher.send_markdown(f"❌ Device {device_name} NSO status: {sync_status}") + + return CommandStatusChoices.STATUS_SUCCEEDED + + +def _run_command_helper(dispatcher, device_name, device_commands, sub_command): + """Helper function for run-commands and run-command-set NSO commands.""" + # Create a dialog prompt for any missing parameters in the command. + dialog_list = [] + + all_choices = [(device.name, device.name) for device in Device.objects.all()] + if not device_name: + # Handle Slack 100 items menu limit + if dispatcher.platform_slug == "slack": + all_choices = dispatcher.get_prompt_from_menu_choices(choices=all_choices) + + dialog_list.append( + { + "type": "select", + "label": "Select target device", + "default": ("", "-----"), + "choices": all_choices, + } + ) + elif device_name.startswith("menu_offset-"): + dialog_list.append( + { + "type": "select", + "label": "Select target device", + "default": ("", "-----"), + "choices": dispatcher.get_prompt_from_menu_choices( + choices=all_choices, offset=int(device_name.replace("menu_offset-", "")) + ), + } + ) + else: + try: + nautobot_device = Device.objects.get(name=device_name) + except ObjectDoesNotExist: + dispatcher.send_error(f"{device_name} does not exist in Nautobot!") + return False + dialog_list.append( + { + "type": "select", + "label": "Select target device", + "default": (nautobot_device.name, nautobot_device.name), + "choices": all_choices, + } + ) + + if not device_commands: + if sub_command == "run-commands": + dialog_list.append({"type": "text", "label": "Comma separated device commands.", "default": ""}) + if sub_command == "run-command-set": + cmd_choices = [ + ("display ip addresses and routing table", "show ip interface brief, show ip route"), + ("display routing table", "show ip route"), + ("display OS version", "show version"), + ("display device neighbors", "show cdp neighbor"), + ("display mac table", "show mac address-table"), + ("list interfaces", "show interface brief"), + ("display bgp neighbors", "show ip bgp sum"), + ] + dialog_list.append( + {"type": "select", "label": "Select command set", "choices": cmd_choices, "default": (None, None)} + ) + + dispatcher.multi_input_dialog( + command=SLASH_COMMAND, + sub_command=sub_command, + dialog_title="Run raw commands", + dialog_list=dialog_list, + ) + return False + + # Split and strip device_commands, exclude empty results + stripped_device_commands = [cmd.strip() for cmd in device_commands.split(",") if cmd.strip() != ""] + + # Send a Markdown-formatted text message. + dispatcher.send_markdown( + f"Standby {dispatcher.user_mention()} while I get that info from Cisco NSO.\n" + f"Please be patient as this can take up to {REQUEST_TIMEOUT_SEC} seconds.", + ephemeral=True, + ) + + # Send a "typing" indicator to show that work is in progress. + dispatcher.send_busy_indicator() + + nso_client = NSOClient() + + # Response we're going to send to the chat client. This will get built as commands + # are run through NSO. + response = "" + for cmd in stripped_device_commands: + # Pull data from NSO using the live_status operand. + data = nso_client.live_status(device_name, cmd) + response += f"\n! {'-' * 30}\n! Command '{cmd}' results:\n! {'-' * 30}\n{data}" + + dispatcher.send_blocks( + [ + *dispatcher.command_response_header( + SLASH_COMMAND, + f'{sub_command} {device_name} "{device_commands}"', + [], + "Cisco NSO Live Status", + nso_logo(dispatcher), + ) + ] + ) + + # If it's a short response, we can add it as a code-block. If it's a bit larger, we will need to stream + # it as a file attachment. + if len(response) < 1000: + dispatcher.send_markdown(f"```{response}\n```") + return True + + dispatcher.send_snippet(response) + return True + + +@subcommand_of("nso") +def run_command_set(dispatcher, device_name, device_commands): + """Select a predefined command set to run on a device using Cisco NSO.""" + return _run_command_helper(dispatcher, device_name, device_commands, "run-command-set") diff --git a/nautobot_chatops/integrations/panorama/constant.py b/nautobot_chatops/integrations/panorama/constant.py index 17967d43..1748f8f1 100644 --- a/nautobot_chatops/integrations/panorama/constant.py +++ b/nautobot_chatops/integrations/panorama/constant.py @@ -22,3 +22,4 @@ PANOS_MANUFACTURER_NAME = "Palo Alto Networks" PANOS_PLATFORM = "PANOS" PANOS_DEVICE_ROLE = "Firewall" +DEFAULT_TIMEOUT = 20 diff --git a/nautobot_chatops/integrations/panorama/utils.py b/nautobot_chatops/integrations/panorama/utils.py index e8157d9a..4d82f8b3 100644 --- a/nautobot_chatops/integrations/panorama/utils.py +++ b/nautobot_chatops/integrations/panorama/utils.py @@ -12,7 +12,7 @@ from panos.policies import PostRulebase, PreRulebase, Rulebase, SecurityRule from requests.exceptions import RequestException -from .constant import PLUGIN_CFG +from .constant import DEFAULT_TIMEOUT, PLUGIN_CFG logger = logging.getLogger(__name__) @@ -31,7 +31,12 @@ def get_api_key_api(url: str = PLUGIN_CFG["panorama_host"]) -> str: params = {"type": "keygen", "user": PLUGIN_CFG["panorama_user"], "password": PLUGIN_CFG["panorama_password"]} - response = requests.get(f"https://{url}/api/", params=params, verify=False) # nosec + response = requests.get( + f"https://{url}/api/", + params=params, + verify=False, # nosec + timeout=DEFAULT_TIMEOUT, + ) if response.status_code != 200: raise RequestException(f"Something went wrong while making a request. Reason: {response.text}") @@ -218,7 +223,12 @@ def _get_pcap(capture_filename: str, ip_address: str): params = {"key": get_api_key_api(), "type": "export", "category": "filters-pcap", "from": "1.pcap"} - respone = requests.get(url, params=params, verify=False) # nosec + respone = requests.get( + url, + params=params, + verify=False, # nosec + timeout=DEFAULT_TIMEOUT, + ) with open(capture_filename, "wb") as pcap_file: pcap_file.write(respone.content) diff --git a/nautobot_chatops/integrations/panorama/worker.py b/nautobot_chatops/integrations/panorama/worker.py index b4b0c42c..799dfa60 100644 --- a/nautobot_chatops/integrations/panorama/worker.py +++ b/nautobot_chatops/integrations/panorama/worker.py @@ -1,4 +1,4 @@ -"""Example rq worker to handle /panorama chat commands with 1 subcommand addition.""" +"""Example worker to handle /panorama chat commands with 1 subcommand addition.""" import logging import os import re @@ -565,7 +565,7 @@ def capture_traffic( """Capture IP traffic on PANOS Device. Args: - dispatcher (object): Chatops plugin dispatcher object + dispatcher (object): Chatops app dispatcher object device (str): Device name snet (str): Source IP/network in IPv4 CIDR notation dnet (str): Destination IP/network in IPv4 CIDR notation diff --git a/nautobot_chatops/metrics.py b/nautobot_chatops/metrics.py index 6ef23428..4401bdb4 100644 --- a/nautobot_chatops/metrics.py +++ b/nautobot_chatops/metrics.py @@ -1,4 +1,4 @@ -"""Nautobot plugin metrics exposed through nautobot_metrics_ext.""" +"""Nautobot app metrics exposed through nautobot_metrics_ext.""" from prometheus_client import Counter, Histogram, Summary diff --git a/nautobot_chatops/metrics_app.py b/nautobot_chatops/metrics_app.py index 2485911d..2cc6e6d0 100644 --- a/nautobot_chatops/metrics_app.py +++ b/nautobot_chatops/metrics_app.py @@ -1,4 +1,4 @@ -"""Nautobot plugin application level metrics exposed through nautobot_metrics_ext.""" +"""Nautobot app application level metrics exposed through nautobot_metrics_ext.""" from prometheus_client.core import CounterMetricFamily diff --git a/nautobot_chatops/navigation.py b/nautobot_chatops/navigation.py index 8baaa557..3bd9ec7b 100644 --- a/nautobot_chatops/navigation.py +++ b/nautobot_chatops/navigation.py @@ -1,4 +1,4 @@ -"""Plugin additions to the Nautobot navigation menu.""" +"""App additions to the Nautobot navigation menu.""" from nautobot.apps.config import get_app_settings_or_config from nautobot.apps.ui import NavMenuAddButton, NavMenuGroup, NavMenuItem, NavMenuTab diff --git a/nautobot_chatops/sockets/__init__.py b/nautobot_chatops/sockets/__init__.py index e69de29b..c63edf0d 100644 --- a/nautobot_chatops/sockets/__init__.py +++ b/nautobot_chatops/sockets/__init__.py @@ -0,0 +1 @@ +"""Nautobot ChatOps Sockets.""" diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index bf1f6c22..6d8dd1bb 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -15,11 +15,11 @@ from nautobot_chatops.utils import socket_check_and_enqueue_command -async def main(): # pylint: disable=too-many-statements +# pylint: disable-next=too-many-statements +async def main(): """Slack Socket Main Loop.""" - SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get( # pylint:disable=invalid-name - "slack_slash_command_prefix" - ) + # pylint: disable-next=invalid-name + SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), @@ -78,7 +78,7 @@ async def process_slash_command(client, req): return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackDispatcher) - # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements,too-many-nested-blocks + # pylint: disable-next=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements async def process_interactive(client, req): client.logger.debug("Processing interactive.") payload = req.payload @@ -125,6 +125,7 @@ async def process_interactive(client, req): # Nothing more to do return + # pylint: disable-next=too-many-nested-blocks elif "view" in payload and payload["view"]: # View submission triggered from a modal dialog client.logger.info("Submission triggered from a modal dialog") diff --git a/nautobot_chatops/static/nso/nso-logo.png b/nautobot_chatops/static/nso/nso-logo.png new file mode 100644 index 00000000..6d716575 Binary files /dev/null and b/nautobot_chatops/static/nso/nso-logo.png differ diff --git a/nautobot_chatops/templates/nautobot_chatops_nso/nsocommandfilter.html b/nautobot_chatops/templates/nautobot_chatops_nso/nsocommandfilter.html new file mode 100644 index 00000000..844551fe --- /dev/null +++ b/nautobot_chatops/templates/nautobot_chatops_nso/nsocommandfilter.html @@ -0,0 +1,38 @@ +{% extends 'generic/object_retrieve.html' %} +{% load helpers %} + +{% block content_left_page %} +
+
+ Command Filter +
+ + + + + + + + + + + + + +
Command + {{ object.command }} +
Role{{ object.role|hyperlinked_object }}
Platform{{ object.platform|hyperlinked_object }}
+
+
+
+ Comments +
+
+ {% if object.comments %} + {{ object.comments|render_markdown }} + {% else %} + None + {% endif %} +
+
+{% endblock content_left_page %} \ No newline at end of file diff --git a/nautobot_chatops/tests/__init__.py b/nautobot_chatops/tests/__init__.py index 90a42e97..ead6aa80 100644 --- a/nautobot_chatops/tests/__init__.py +++ b/nautobot_chatops/tests/__init__.py @@ -1 +1 @@ -"""Test for the nautobot_chatops plugin.""" +"""Unit tests for nautobot_chatops app.""" diff --git a/nautobot_chatops/tests/aci/__init__.py b/nautobot_chatops/tests/aci/__init__.py index 0991627c..daad5815 100644 --- a/nautobot_chatops/tests/aci/__init__.py +++ b/nautobot_chatops/tests/aci/__init__.py @@ -1 +1 @@ -"""Unit tests for integrations.aci plugin.""" +"""Unit tests for integrations.aci app.""" diff --git a/nautobot_chatops/tests/aci/test_aci.py b/nautobot_chatops/tests/aci/test_aci.py index 2126f813..1385399a 100644 --- a/nautobot_chatops/tests/aci/test_aci.py +++ b/nautobot_chatops/tests/aci/test_aci.py @@ -1,5 +1,5 @@ """Tests for integrations.aci.aci.""" -# pylint: disable=no-self-use, import-outside-toplevel, invalid-name +# pylint: disable=invalid-name import unittest from unittest.mock import patch, Mock from nautobot_chatops.integrations.aci.aci import NautobotPluginChatopsAci, RequestHTTPError diff --git a/nautobot_chatops/tests/ansible/__init__.py b/nautobot_chatops/tests/ansible/__init__.py index 8cac59da..bea26431 100644 --- a/nautobot_chatops/tests/ansible/__init__.py +++ b/nautobot_chatops/tests/ansible/__init__.py @@ -1 +1 @@ -"""Unit tests for nautobot_chatops.integrations.ansible plugin.""" +"""Unit tests for nautobot_chatops.integrations.ansible app.""" diff --git a/nautobot_chatops/tests/grafana/__init__.py b/nautobot_chatops/tests/grafana/__init__.py index d914107c..ebfa6dfe 100644 --- a/nautobot_chatops/tests/grafana/__init__.py +++ b/nautobot_chatops/tests/grafana/__init__.py @@ -1 +1 @@ -"""Unit tests for nautobot_chatops.integrations.grafana plugin.""" +"""Unit tests for nautobot_chatops.integrations.grafana app.""" diff --git a/nautobot_chatops/tests/grafana/test_workers.py b/nautobot_chatops/tests/grafana/test_workers.py index 36f5f7a7..2707c037 100644 --- a/nautobot_chatops/tests/grafana/test_workers.py +++ b/nautobot_chatops/tests/grafana/test_workers.py @@ -142,7 +142,7 @@ def test_get_commands_registry_dynamic_subcommands(self): self.assertIn("nautobot", registry) def test_grafana_commands_registry_dynamic_subcommands(self): - """Specific testing for the Grafana Chatops Plugin.""" + """Specific testing for the Grafana Chatops App.""" with dynamic_entrypoint("nautobot.workers", name="grafana", module="nautobot_chatops.grafana.worker"): registry = get_commands_registry() diff --git a/nautobot_chatops/tests/meraki/test_utils.py b/nautobot_chatops/tests/meraki/test_utils.py index 31680cdd..3a14a80b 100644 --- a/nautobot_chatops/tests/meraki/test_utils.py +++ b/nautobot_chatops/tests/meraki/test_utils.py @@ -9,7 +9,7 @@ class TestUtils(unittest.TestCase): """Test Version is the same.""" @patch("nautobot_chatops.integrations.meraki.utils.MerakiClient.get_meraki_orgs") - def test_org_name_to_id(self, mock_orgs): # pylint: disable=no-self-use + def test_org_name_to_id(self, mock_orgs): """Test Translate Org Name to Org Id.""" mock_orgs.return_value = [ { @@ -23,7 +23,7 @@ def test_org_name_to_id(self, mock_orgs): # pylint: disable=no-self-use assert client.org_name_to_id("NTC-TEST") == "123456" @patch("nautobot_chatops.integrations.meraki.utils.MerakiClient.get_meraki_devices") - def test_name_to_serial(self, mock_devices): # pylint: disable=no-self-use + def test_name_to_serial(self, mock_devices): """Test Translate Name to Serial.""" mock_devices.return_value = [ { @@ -45,7 +45,7 @@ def test_name_to_serial(self, mock_devices): # pylint: disable=no-self-use assert client.name_to_serial("NTC-TEST", "fw01-test") == "SN123456" @patch("nautobot_chatops.integrations.meraki.utils.MerakiClient.get_meraki_networks_by_org") - def test_netname_to_id(self, mock_net_name): # pylint: disable=no-self-use + def test_netname_to_id(self, mock_net_name): """Translate Network Name to Network ID.""" mock_net_name.return_value = [ { diff --git a/nautobot_chatops/tests/nso/__init__.py b/nautobot_chatops/tests/nso/__init__.py new file mode 100644 index 00000000..351ad7ce --- /dev/null +++ b/nautobot_chatops/tests/nso/__init__.py @@ -0,0 +1 @@ +"""Unit tests for nautobot_chatops.integrations.nso plugin.""" diff --git a/nautobot_chatops/tests/nso/fixtures/compare_config_responses.json b/nautobot_chatops/tests/nso/fixtures/compare_config_responses.json new file mode 100644 index 00000000..ad16fb9d --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/compare_config_responses.json @@ -0,0 +1,28 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=in_sync_device/compare-config", + "method": "POST", + "status": 200, + "response_json": {} + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=out_of_sync_device/compare-config", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "diff": "\n devices {\n device out_of_sync_device {\n config {\n interface {\n+ Loopback 100 {\n+ description \"Test Change\";\n+ }\n }\n }\n }\n }\n" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/compare-config", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "info": "Device c3 is southbound locked" + } + } + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/connect_device_responses.json b/nautobot_chatops/tests/nso/fixtures/connect_device_responses.json new file mode 100644 index 00000000..9e39422e --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/connect_device_responses.json @@ -0,0 +1,40 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/connect", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": true, + "info": "(admin) Connected to good_device - 127.0.0.1:10022" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/connect", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": false, + "info": "Device c3 is southbound locked" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=nonexistent_device/connect", + "method": "POST", + "status": 404, + "response_json": { + "ietf-restconf:errors": { + "error": [ + { + "error-type": "application", + "error-tag": "invalid-value", + "error-message": "uri keypath not found" + } + ] + } + } + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/live_status_responses.json b/nautobot_chatops/tests/nso/fixtures/live_status_responses.json new file mode 100644 index 00000000..96d0469b --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/live_status_responses.json @@ -0,0 +1,142 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/device-type", + "method": "GET", + "status": 200, + "response_json": { + "tailf-ncs:device-type": { + "cli": { + "ned-id": "cisco-ios-cli-6.77:cisco-ios-cli-6.77" + } + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/live-status/tailf-ned-cisco-ios-stats:exec/show", + "method": "POST", + "status": 200, + "body": { + "input": { + "args": "version" + } + }, + "response_json": { + "tailf-ned-cisco-ios-stats:output": { + "result": "\r\nCisco IOS Software, NETSIM\r\ngood_device# " + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/device-type", + "method": "GET", + "status": 200, + "response_json": { + "tailf-ncs:device-type": { + "cli": { + "ned-id": "cisco-ios-cli-6.77:cisco-ios-cli-6.77" + } + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/live-status/tailf-ned-cisco-ios-stats:exec/show", + "method": "POST", + "status": 500, + "body": { + "input": { + "args": "version" + } + }, + "response_json": { + "ietf-restconf:errors": { + "error": [ + { + "error-type": "application", + "error-tag": "operation-failed", + "error-path": "/tailf-ncs:devices/device[name='offline_device']/live-status/tailf-ned-cisco-ios-stats:exec/show", + "error-message": "Device offline_device is southbound locked" + } + ] + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=nonexistent_device/device-type", + "method": "GET", + "status": 404, + "response_json": { + "ietf-restconf:errors": { + "error": [ + { + "error-type": "application", + "error-tag": "invalid-value", + "error-message": "uri keypath not found" + } + ] + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device_nx/device-type", + "method": "GET", + "status": 200, + "response_json": { + "tailf-ncs:device-type": { + "cli": { + "ned-id": "cisco-nx-cli-3.0:cisco-nx-cli-3.0" + } + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device_nx/live-status/tailf-ned-cisco-nx-stats:exec/show", + "method": "POST", + "status": 200, + "body": { + "input": { + "args": "version" + } + }, + "response_json": { + "tailf-ned-cisco-nx-stats:output": { + "result": "\r\nCisco NX-OS Software, NETSIM\r\ngood_device_nx# " + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=unsupported_device_asa/device-type", + "method": "GET", + "status": 200, + "response_json": { + "tailf-ncs:device-type": { + "cli": { + "ned-id": "cisco-asa-cli-6.6:cisco-asa-cli-6.6" + } + } + } + }, + { + "url": "https://nso.error/restconf/data/tailf-ncs:devices/device=error_device_type/device-type", + "method": "GET", + "status": 404, + "response_json": {} + }, + { + "url": "https://nso.error/restconf/data/tailf-ncs:devices/device=error_live_status/device-type", + "method": "GET", + "status": 200, + "response_json": { + "tailf-ncs:device-type": { + "cli": { + "ned-id": "cisco-ios-cli-6.77:cisco-ios-cli-6.77" + } + } + } + }, + { + "url": "https://nso.error/restconf/data/tailf-ncs:devices/device=error_live_status/live-status/tailf-ned-cisco-ios-stats:exec/show", + "method": "POST", + "status": 404, + "response_json": {} + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/ping_device_responses.json b/nautobot_chatops/tests/nso/fixtures/ping_device_responses.json new file mode 100644 index 00000000..c8f98b1e --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/ping_device_responses.json @@ -0,0 +1,44 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/ping", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": "PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.\n64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.014 ms\n\n--- 10.0.0.2 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.014/0.014/0.014/0.000 ms\n" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/ping", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": "PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.\n\n--- 10.0.0.2 ping statistics ---\n1 packets transmitted, 0 received, 100% packet loss, time 0ms\n\n" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=nonexistent_device/ping", + "method": "POST", + "status": 404, + "response_json": { + "ietf-restconf:errors": { + "error": [ + { + "error-type": "application", + "error-tag": "invalid-value", + "error-message": "uri keypath not found" + } + ] + } + } + }, + { + "url": "https://nso.error/restconf/data/tailf-ncs:devices/device=error_device/ping", + "method": "POST", + "status": 404, + "response_json": {} + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/sync_from_responses.json b/nautobot_chatops/tests/nso/fixtures/sync_from_responses.json new file mode 100644 index 00000000..2f2fa7db --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/sync_from_responses.json @@ -0,0 +1,23 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/sync-from", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": true + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/sync-from", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": false, + "info": "Device c3 is southbound locked" + } + } + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/sync_status_responses.json b/nautobot_chatops/tests/nso/fixtures/sync_status_responses.json new file mode 100644 index 00000000..57edacc6 --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/sync_status_responses.json @@ -0,0 +1,61 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=in_sync_device/check-sync", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": "in-sync" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=out_of_sync_device/check-sync", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": "out-of-sync" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/check-sync", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": "locked" + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/check-sync", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "sync-result": [ + { + "device": "in_sync_device", + "result": "in-sync" + }, + { + "device": "out_of_sync_device", + "result": "out-of-sync" + }, + { + "device": "offline_device", + "result": "locked" + } + ] + } + } + }, + { + "url": "https://nso.error/restconf/data/tailf-ncs:devices/check-sync", + "method": "POST", + "status": 404, + "response_json": {} + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/fixtures/sync_to_responses.json b/nautobot_chatops/tests/nso/fixtures/sync_to_responses.json new file mode 100644 index 00000000..9416a586 --- /dev/null +++ b/nautobot_chatops/tests/nso/fixtures/sync_to_responses.json @@ -0,0 +1,23 @@ +[ + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=good_device/sync-to", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": true + } + } + }, + { + "url": "https://nso.test/restconf/data/tailf-ncs:devices/device=offline_device/sync-to", + "method": "POST", + "status": 200, + "response_json": { + "tailf-ncs:output": { + "result": false, + "info": "Device c3 is southbound locked" + } + } + } +] \ No newline at end of file diff --git a/nautobot_chatops/tests/nso/test_nso.py b/nautobot_chatops/tests/nso/test_nso.py new file mode 100644 index 00000000..995a787f --- /dev/null +++ b/nautobot_chatops/tests/nso/test_nso.py @@ -0,0 +1,162 @@ +"""Test rundeck client.""" +# Disable protected access, since..ya know. We need to test them. # pylint: disable=protected-access + +from os import path +import json +import responses +from django.test import SimpleTestCase + +from nautobot_chatops.integrations.nso.nso import NSOClient as nso +from nautobot_chatops.integrations.nso.exceptions import ( + CommunicationError, + DeviceNotFound, + DeviceNotSupported, + DeviceLocked, +) + + +HERE = path.abspath(path.dirname(__file__)) + + +def load_api_calls(_responses, fixture): + """Load the API calls into memory for mocking.""" + with open(f"{HERE}/fixtures/{fixture}.json", "r", encoding="utf-8") as file_: + api_calls = json.load(file_) + + for api_call in api_calls: + if api_call["method"] == "GET": + _responses.add( + _responses.GET, + api_call["url"], + json=api_call["response_json"], + status=api_call["status"], + headers={"Content-Type": "application/yang-data+xml"}, + ) + continue + + if api_call["method"] == "POST": + _responses.add( + _responses.POST, + api_call["url"], + json=api_call["response_json"], + match=[_responses.matchers.json_params_matcher(api_call["body"])] if "body" in api_call else [], + status=api_call["status"], + headers={"Content-Type": "application/yang-data+xml"}, + ) + continue + + +class TestNSO(SimpleTestCase): + """Test Base NSO Client and Calls.""" + + def setUp(self): + """Setup.""" + self.url = "https://nso.test" + self.username = "username" + self.password = "password" # nosec + self.nso = nso(self.url, self.username, self.password) + + self.error_url = "https://nso.error" + self.error_nso = nso(self.error_url, self.username, self.password) + + @responses.activate + def test_ping(self): + """Test Ping Device API Call.""" + + load_api_calls(responses, "ping_device_responses") + + self.assertIn("1 packets transmitted, 1 received, 0% packet loss", self.nso.ping("good_device")) + self.assertIn("100% packet loss", self.nso.ping("offline_device")) + # self.assertIn("Device does not exist in NSO", self.nso.ping("nonexistent_device")) + with self.assertRaises(DeviceNotFound): + self.nso.ping("nonexistent_device") + with self.assertRaises(CommunicationError): + self.error_nso.ping("error_device") + + @responses.activate + def test_connect(self): + """Test Connect to Device API Call.""" + + load_api_calls(responses, "connect_device_responses") + + self.assertEqual(self.nso.connect("good_device"), True) + self.assertEqual(self.nso.connect("offline_device"), False) + # self.assertEqual(self.nso.connect("nonexistent_device"), "Device does not exist in NSO") + with self.assertRaises(DeviceNotFound): + self.nso.connect("nonexistent_device") + + @responses.activate + def test_sync_to(self): + """Test Sync to Device API Call.""" + + load_api_calls(responses, "sync_to_responses") + + self.assertEqual(self.nso.sync_to("good_device"), True) + self.assertEqual(self.nso.sync_to("offline_device"), False) + + @responses.activate + def test_sync_from(self): + """Test Sync from Device API Call.""" + + load_api_calls(responses, "sync_from_responses") + + self.assertEqual(self.nso.sync_from("good_device"), True) + self.assertEqual(self.nso.sync_from("offline_device"), False) + + @responses.activate + def test_sync_status(self): + """Test Check Sync Status of Device API Call.""" + + load_api_calls(responses, "sync_status_responses") + + self.assertEqual(self.nso.sync_status("in_sync_device"), "in-sync") + self.assertEqual(self.nso.sync_status("out_of_sync_device"), "out-of-sync") + self.assertEqual(self.nso.sync_status("offline_device"), "locked") + + @responses.activate + def test_sync_status_all(self): + """Test Check Sync Status of All Devices API Call.""" + + load_api_calls(responses, "sync_status_responses") + response_sync_status_all = [ + {"device": "in_sync_device", "result": "in-sync"}, + {"device": "out_of_sync_device", "result": "out-of-sync"}, + {"device": "offline_device", "result": "locked"}, + ] + self.assertEqual(self.nso.sync_status_all(), response_sync_status_all) + with self.assertRaises(CommunicationError): + self.error_nso.sync_status_all() + + @responses.activate + def test_compare_config(self): + """Test Compare Config of Device API Call.""" + + load_api_calls(responses, "compare_config_responses") + + self.assertEqual(self.nso.compare_config("in_sync_device"), {}) + self.assertIn("Test Change", self.nso.compare_config("out_of_sync_device")) + self.assertEqual(self.nso.compare_config("offline_device"), {"info": "Device c3 is southbound locked"}) + + @responses.activate + def test_live_status(self): + """Test Compare Config of Device API Call.""" + + load_api_calls(responses, "live_status_responses") + + self.assertEqual( + self.nso.live_status("good_device", "show version"), "\r\nCisco IOS Software, NETSIM\r\ngood_device# " + ) + self.assertEqual( + self.nso.live_status("good_device_nx", "show version"), + "\r\nCisco NX-OS Software, NETSIM\r\ngood_device_nx# ", + ) + with self.assertRaises(DeviceLocked): + self.nso.live_status("offline_device", "show version") + with self.assertRaises(DeviceNotSupported): + self.nso.live_status("unsupported_device_asa", "show version") + with self.assertRaises(DeviceNotFound): + self.nso.live_status("nonexistent_device", "show version") + with self.assertRaises(CommunicationError): + self.error_nso.live_status("error_device_type", "show version") + with self.assertRaises(CommunicationError): + self.error_nso.live_status("error_live_status", "show version") diff --git a/nautobot_chatops/tests/panorama/__init__.py b/nautobot_chatops/tests/panorama/__init__.py index f762864e..e61712ea 100644 --- a/nautobot_chatops/tests/panorama/__init__.py +++ b/nautobot_chatops/tests/panorama/__init__.py @@ -1 +1 @@ -"""Unit tests for nautobot_plugin.integrations.panorama plugin.""" +"""Unit tests for nautobot_plugin.integrations.panorama app.""" diff --git a/nautobot_chatops/tests/test_api.py b/nautobot_chatops/tests/test_api.py index eb319a70..3113ce4e 100644 --- a/nautobot_chatops/tests/test_api.py +++ b/nautobot_chatops/tests/test_api.py @@ -1,9 +1,5 @@ """Test cases for Nautobot Chatops API.""" -try: - from importlib import metadata -except ImportError: - # Python version < 3.8 - import importlib_metadata as metadata +from importlib import metadata from django.urls import reverse diff --git a/nautobot_chatops/tests/test_basic.py b/nautobot_chatops/tests/test_basic.py new file mode 100644 index 00000000..bcf7d12d --- /dev/null +++ b/nautobot_chatops/tests/test_basic.py @@ -0,0 +1,22 @@ +"""Basic tests that do not require Django.""" +import unittest +import os +import toml + + +class TestDocsPackaging(unittest.TestCase): + """Test Version in doc requirements is the same pyproject.""" + + def test_version(self): + """Verify that pyproject.toml dev dependencies have the same versions as in the docs requirements.txt.""" + parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) + poetry_path = os.path.join(parent_path, "pyproject.toml") + poetry_details = toml.load(poetry_path)["tool"]["poetry"]["group"]["dev"]["dependencies"] + with open(f"{parent_path}/docs/requirements.txt", "r", encoding="utf-8") as file: + requirements = [line for line in file.read().splitlines() if (len(line) > 0 and not line.startswith("#"))] + for pkg in requirements: + if len(pkg.split("==")) == 2: + pkg, version = pkg.split("==") + else: + version = "*" + self.assertEqual(poetry_details[pkg], version) diff --git a/nautobot_chatops/tests/test_utils.py b/nautobot_chatops/tests/test_utils.py index 413fcbcb..8d5276e2 100644 --- a/nautobot_chatops/tests/test_utils.py +++ b/nautobot_chatops/tests/test_utils.py @@ -144,7 +144,6 @@ def test_default_deny(self, mock_enqueue_task): self.assertIsNone(MockDispatcher.error) mock_enqueue_task.assert_called_once() - # pylint: disable=no-self-use def setup_db(self): """Per-testcase database population for most test cases.""" # Create some globally applicable access grants: diff --git a/nautobot_chatops/urls.py b/nautobot_chatops/urls.py index 6f02d1ee..8da8f0ac 100644 --- a/nautobot_chatops/urls.py +++ b/nautobot_chatops/urls.py @@ -1,4 +1,4 @@ -"""Django urlpatterns declaration for nautobot_chatops plugin.""" +"""Django urlpatterns declaration for nautobot_chatops app.""" import logging from django.urls import path diff --git a/nautobot_chatops/views.py b/nautobot_chatops/views.py index 6e980089..b629d4c9 100644 --- a/nautobot_chatops/views.py +++ b/nautobot_chatops/views.py @@ -1,4 +1,4 @@ -"""Views module for the nautobot_chatops Nautobot plugin. +"""Views module for the nautobot_chatops Nautobot App. The views implemented in this module act as endpoints for various chat platforms to send requests and notifications to. diff --git a/nautobot_chatops/workers/__init__.py b/nautobot_chatops/workers/__init__.py index dfe89d59..19bc4322 100644 --- a/nautobot_chatops/workers/__init__.py +++ b/nautobot_chatops/workers/__init__.py @@ -1,4 +1,4 @@ -"""Workers module for the nautobot_chatops Nautobot plugin. +"""Workers module for the nautobot_chatops Nautobot App. The functions in this module provide back-end worker logic that is totally ignorant of the differences between various chat platforms. They receive generic data from @@ -103,7 +103,7 @@ def get_commands_registry(): if _commands_registry[worker.name]["function"] == command_func: logger.warning("Command worker function '%s' was processed twice. This should not happen", worker.name) else: - logger.error("Duplicate worker name '%s' detected! Check for redundant plugins", worker.name) + logger.error("Duplicate worker name '%s' detected! Check for redundant apps", worker.name) continue if worker.name not in _commands_registry: diff --git a/nautobot_chatops/workers/nautobot.py b/nautobot_chatops/workers/nautobot.py index 819fb2be..11fc74c1 100644 --- a/nautobot_chatops/workers/nautobot.py +++ b/nautobot_chatops/workers/nautobot.py @@ -1,5 +1,9 @@ """Worker functions for interacting with Nautobot.""" +import json +import time + + from django.core.exceptions import ValidationError from django.db.models import Count from django.contrib.contenttypes.models import ContentType @@ -10,7 +14,9 @@ from nautobot.dcim.models import Device, DeviceType, Location, LocationType, Manufacturer, Rack, Cable from nautobot.ipam.models import VLAN, Prefix, VLANGroup from nautobot.tenancy.models import Tenant -from nautobot.extras.models import Role, Status +from nautobot.extras.choices import JobResultStatusChoices +from nautobot.extras.models import Job, JobResult, Role, Status +from nautobot.extras.jobs import get_job from nautobot_chatops.choices import CommandStatusChoices from nautobot_chatops.workers import subcommand_of, handle_subcommands @@ -1045,6 +1051,346 @@ def get_circuit_providers(dispatcher, *args): return CommandStatusChoices.STATUS_SUCCEEDED +@subcommand_of("nautobot") +def filter_jobs(dispatcher, job_filters: str = ""): # We can use a Literal["enabled", "installed"] here instead + """Get a filtered list of jobs from Nautobot that the request user have view permissions for. + + Args: + job_filters (str): Filter job results by literals in a comma-separated string. + Available filters are: enabled, installed. + """ + # Check for filters in user supplied input + job_filters_list = [item.strip() for item in job_filters.split(",")] if isinstance(job_filters, str) else "" + filters = ["enabled", "installed"] + if any(key in job_filters for key in filters): + filter_args = {key: True for key in filters if key in job_filters_list} + jobs = Job.objects.restrict(dispatcher.user, "view").filter(**filter_args) # enabled=True, installed=True + else: + jobs = Job.objects.restrict(dispatcher.user, "view").all() + + header = ["Name", "ID", "Enabled"] + rows = [ + ( + str(job.name), + str(job.id), + str(job.enabled), + ) + for job in jobs + ] + + dispatcher.send_large_table(header, rows) + + return CommandStatusChoices.STATUS_SUCCEEDED + + +@subcommand_of("nautobot") +def get_jobs(dispatcher, kwargs: str = ""): + """Get all jobs from Nautobot that the requesting user have view permissions for. + + Args: + kwargs (str): JSON-string array of header items to be exported. (Optional, default export is: name, id, enabled) + """ + # Confirm kwargs is valid JSON + json_args = ["name", "id", "enabled"] + try: + if kwargs: + json_args = json.loads(kwargs) + except json.JSONDecodeError: + dispatcher.send_error(f"Invalid JSON-string, cannot decode: {kwargs}") + return (CommandStatusChoices.STATUS_FAILED, f"Invalid JSON-string, cannot decode: {kwargs}") + + # Confirm `name` is always present in export + name_key = json_args.get("name") or json_args.get("Name") + if not name_key: + json_args.append("name") + + jobs = Job.objects.restrict(dispatcher.user, "view").all() + + # Check if all items in json_args are valid keys (assuming all keys of job object are valid) + valid_keys = [attr for attr in dir(Job) if not callable(getattr(Job, attr)) and not attr.startswith("_")] + for item in json_args: + if item.lower() not in valid_keys: + dispatcher.send_error(f"Invalid item provided: {item.lower()}") + return (CommandStatusChoices.STATUS_FAILED, f"Invalid item provided: {item.lower()}") + + # TODO: Check json_args are all valid keys + header = [item.capitalize() for item in json_args] + rows = [(tuple(str(getattr(job, item, "")) for item in json_args)) for job in jobs] + + dispatcher.send_large_table(header, rows) + + return CommandStatusChoices.STATUS_SUCCEEDED + + +@subcommand_of("nautobot") +def run_job(dispatcher, *args, job_name: str = "", json_string_kwargs: str = ""): # pylint: disable=too-many-locals + """Initiate a job in Nautobot by job name. + + Args: + *args (tuple): Dispatcher form will pass job args as tuple. + job_name (str): Name of Nautobot job to run. + json_string_kwargs (str): JSON-string dictionary for input keyword arguments for job run. + """ + # Prompt the user to pick a job if they did not specify one + if not job_name: + return prompt_for_job(dispatcher, "nautobot run-job") + + if args: + json_string_kwargs = "{}" + + # Confirm kwargs is valid JSON + json_args = {} + try: + if json_string_kwargs: + json_args = json.loads(json_string_kwargs) + except json.JSONDecodeError: + dispatcher.send_error(f"Invalid JSON-string, cannot decode: {json_string_kwargs}") + return (CommandStatusChoices.STATUS_FAILED, f"Invalid JSON-string, cannot decode: {json_string_kwargs}") + + profile = False + if json_args.get("profile") and json_args["profile"] is True: + profile = True + + # Get the job model instance using job name + try: + job_model = Job.objects.restrict(dispatcher.user, "view").get(name=job_name) + except Job.DoesNotExist: + dispatcher.send_error(f"Job {job_name} not found") + return (CommandStatusChoices.STATUS_FAILED, f'Job "{job_name}" was not found') + + if not job_model.enabled: + dispatcher.send_error(f"The requested job {job_name} is not enabled") + return (CommandStatusChoices.STATUS_FAILED, f'Job "{job_name}" is not enabled') + + form_class = get_job(job_model.class_path).as_form() + + # Parse base form fields from job class + form_fields = [] + for field_name, _ in form_class.base_fields.items(): # pylint: disable=unused-variable + if field_name.startswith("_"): + continue + form_fields.append(f"{field_name}") + + # Basic logic check with what we know, we should expect run-job-form vs run-job to parse the same base fields + if len(form_fields) != len(args): + dispatcher.send_error("The form class fields and the passed run-job args do not match.") + return ( + CommandStatusChoices.STATUS_FAILED, + "The form class fields and the passed run-job args do not match.", + ) + + form_item_kwargs = {} + for index, _ in enumerate(form_fields): # pylint: disable=unused-variable + # Check request input (string-type) is also valid JSON + if args[index][0] == "{": + try: + json_arg = json.loads(args[index]) + if not json_arg.get("id"): + dispatcher.send_error("Form field arg is JSON dictionary, and has no `id` key.") + return ( + CommandStatusChoices.STATUS_FAILED, + "Form field arg is JSON dictionary, and has no `id` key.", + ) + form_item_kwargs[form_fields[index]] = json_arg.get("id") + continue + except json.JSONDecodeError: + form_item_kwargs[form_fields[index]] = args[index] + continue + form_item_kwargs[form_fields[index]] = args[index] + + job_result = JobResult.enqueue_job( + job_model=job_model, + user=dispatcher.user, + profile=profile, + **form_item_kwargs, + ) + + # Wait on the job to finish + max_wait_iterations = 60 + while job_result.status not in JobResultStatusChoices.READY_STATES: + max_wait_iterations -= 1 + if not max_wait_iterations: + dispatcher.send_error(f"The requested job {job_name} failed to reach ready state.") + return (CommandStatusChoices.STATUS_FAILED, f'Job "{job_name}" failed to reach ready state.') + time.sleep(1) + job_result.refresh_from_db() + + if job_result and job_result.status == "FAILURE": + dispatcher.send_error(f"The requested job {job_name} was initiated but failed. Result: {job_result.result}") + return ( + CommandStatusChoices.STATUS_FAILED, + f'Job "{job_name}" was initiated but failed. Result: {job_result.result}', + ) # pylint: disable=line-too-long + + job_url = ( + f"{dispatcher.context['request_scheme']}://{dispatcher.context['request_host']}{job_result.get_absolute_url()}" + ) + blocks = [ + dispatcher.markdown_block( + f"The requested job {job_model.class_path} was initiated! [`click here`]({job_url}) to open the job." + ), + ] + + dispatcher.send_blocks(blocks) + + return CommandStatusChoices.STATUS_SUCCEEDED + + +@subcommand_of("nautobot") +def run_job_form(dispatcher, job_name: str = ""): + """Send job form as a multi-input dialog. On form submit it initiates the job with the form arguments. + + Args: + job_name (str): Name of Nautobot job to run. + """ + # Prompt the user to pick a job if they did not specify one + if not job_name: + return prompt_for_job(dispatcher, "nautobot run-job-form") + + # Get jobs available to user + try: + job = Job.objects.restrict(dispatcher.user, "view").get(name=job_name) + except Job.DoesNotExist: + blocks = [ + dispatcher.markdown_block( + f"Job {job_name} does not exist or {dispatcher.user} does not have permissions to run job." # pylint: disable=line-too-long + ), + ] + dispatcher.send_blocks(blocks) + return CommandStatusChoices.STATUS_SUCCEEDED + + except Job.MultipleObjectsReturned: + blocks = [ + dispatcher.markdown_block(f"Multiple jobs found by name {job_name}."), + ] + dispatcher.send_blocks(blocks) + return CommandStatusChoices.STATUS_SUCCEEDED + + if not job.enabled: + blocks = [ + dispatcher.markdown_block(f"Job {job_name} is not enabled. The job must be enabled to be ran."), + ] + dispatcher.send_blocks(blocks) + return CommandStatusChoices.STATUS_SUCCEEDED + + form_class = get_job(job.class_path).as_form() + + # Parse base form fields from job class + form_items = {} + for field_name, field in form_class.base_fields.items(): + if field_name.startswith("_"): + continue + form_items[field_name] = field + + form_item_dialogs = [] + for field_name, field in form_items.items(): + try: + field_type = field.widget.input_type + except AttributeError: + # Some widgets (eg: textarea) do have the `input_type` attribute + field_type = field.widget.template_name.split("/")[-1].split(".")[0] + + if field_type == "select": + if not hasattr(field, "choices"): + blocks = [ + dispatcher.markdown_block(f"Job {job_name} field {field} has no attribute `choices`."), + ] + dispatcher.send_blocks(blocks) + return CommandStatusChoices.STATUS_SUCCEEDED + + query_result_items = [] + for choice, value in field.choices: + query_result_items.append( + (value, f'{{"field_name": "{field_name}", "value": "{value}", "id": "{str(choice)}"}}') + ) + + if len(query_result_items) == 0 and field.required: + blocks = [ + dispatcher.markdown_block( + f"Job {job_name} for {field_name} is required, however no choices populated for dialog choices." + ), + ] + dispatcher.send_blocks(blocks) + return CommandStatusChoices.STATUS_SUCCEEDED + + form_item_dialogs.append( + { + "type": field_type, + "label": f"{field_name}: {field.help_text}", + "choices": query_result_items, + "default": query_result_items[0] if query_result_items else ("", ""), + "confirm": False, + } + ) + + elif field_type == "text": + default_value = field.initial + form_item_dialogs.append( + { + "type": field_type, + "label": f"{field_name}: {field.help_text}", + "default": default_value, + "confirm": False, + } + ) + + elif field_type == "number": + # TODO: Can we enforce numeric-character mask for widget input without JavaScript? + default_value = field.initial + form_item_dialogs.append( + { + "type": "text", + "label": f"{field_name}: {field.help_text} *integer values only*", + "default": default_value, + "confirm": False, + } + ) + + elif field_type == "checkbox": + # TODO: Is there a checkbox widget? + default_value = ("False", "false") + if field.initial: + default_value = ("True", "true") + form_item_dialogs.append( + { + "type": "select", + "label": f"{field_name}: {field.help_text}", + "choices": [("True", "true"), ("False", "false")], + "default": default_value, + "confirm": False, + } + ) + + elif field_type == "textarea": + # TODO: Is there a multi-line text input widget + default_value = field.initial + form_item_dialogs.append( + { + "type": "text", + "label": f"{field_name}: {field.help_text}", + "default": default_value, + "confirm": False, + } + ) + + # TODO: BUG: Single inputs will present but not submit properly with multi_input_dialog + dispatcher.multi_input_dialog( + command="nautobot", + sub_command=f"run-job {job_name} {{}}", + dialog_title=f"job {job_name} form input", + dialog_list=form_item_dialogs, + ) + + return CommandStatusChoices.STATUS_SUCCEEDED + + +def prompt_for_job(dispatcher, command): + """Prompt the user to select a Nautobot Job.""" + jobs = Job.objects.restrict(dispatcher.user, "view").all() + dispatcher.prompt_from_menu(command, "Select a Nautobot Job", [(job.name, job.name) for job in jobs]) + return False + + @subcommand_of("nautobot") def about(dispatcher, *args): """Provide link for more information on Nautobot Apps.""" diff --git a/poetry.lock b/poetry.lock index 4303eae6..2f76ab43 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.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" @@ -183,6 +183,17 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)"] test = ["anyio[trio]", "coverage[toml] (>=7)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.22)"] +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = "*" +files = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] + [[package]] name = "arrow" version = "1.2.3" @@ -216,20 +227,39 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "astroid" -version = "2.11.7" +version = "2.15.8" description = "An abstract syntax tree for Python with inference support." optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.2" files = [ - {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, - {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, + {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, + {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, ] [package.dependencies] lazy-object-proxy = ">=1.4.0" -setuptools = ">=20.0" -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<2" +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +wrapt = [ + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, +] + +[[package]] +name = "asttokens" +version = "2.4.0" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.0-py2.py3-none-any.whl", hash = "sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69"}, + {file = "asttokens-2.4.0.tar.gz", hash = "sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +test = ["astroid", "pytest"] [[package]] name = "async-timeout" @@ -260,6 +290,17 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +optional = false +python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] + [[package]] name = "backports-zoneinfo" version = "0.2.1" @@ -405,6 +446,17 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "bracex" +version = "2.4" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, + {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, +] + [[package]] name = "celery" version = "5.3.4" @@ -868,6 +920,17 @@ requests = {version = ">=2.27.0", extras = ["socks"]} [package.extras] dev = ["check-manifest", "coverage", "pep8", "pyflakes", "pylint", "pyyaml"] +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + [[package]] name = "deepdiff" version = "6.5.0" @@ -1041,6 +1104,21 @@ files = [ [package.dependencies] Django = "*" +[[package]] +name = "django-debug-toolbar" +version = "4.2.0" +description = "A configurable set of panels that display various debug information about the current request/response." +optional = false +python-versions = ">=3.8" +files = [ + {file = "django_debug_toolbar-4.2.0-py3-none-any.whl", hash = "sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327"}, + {file = "django_debug_toolbar-4.2.0.tar.gz", hash = "sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc"}, +] + +[package.dependencies] +django = ">=3.2.4" +sqlparse = ">=0.2" + [[package]] name = "django-extensions" version = "3.2.3" @@ -1328,6 +1406,20 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "executing" +version = "2.0.0" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = "*" +files = [ + {file = "executing-2.0.0-py2.py3-none-any.whl", hash = "sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657"}, + {file = "executing-2.0.0.tar.gz", hash = "sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + [[package]] name = "flake8" version = "3.9.2" @@ -1577,13 +1669,13 @@ six = ">=1.12" [[package]] name = "griffe" -version = "0.30.1" +version = "0.36.7" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "griffe-0.30.1-py3-none-any.whl", hash = "sha256:b2f3df6952995a6bebe19f797189d67aba7c860755d3d21cc80f64d076d0154c"}, - {file = "griffe-0.30.1.tar.gz", hash = "sha256:007cc11acd20becf1bb8f826419a52b9d403bbad9d8c8535699f5440ddc0a109"}, + {file = "griffe-0.36.7-py3-none-any.whl", hash = "sha256:7a09f8e9b97c7ebe227f6529a298bf7e0e742a9837ee261cc8260d50b4aa039f"}, + {file = "griffe-0.36.7.tar.gz", hash = "sha256:a6fe60b16720ca0cf63c9e667a4c05eea40dfe4abcf114741885f945b74c7071"}, ] [package.dependencies] @@ -1854,6 +1946,45 @@ files = [ httpx = ">=0.23.0,<0.24.0" PyJWT = ">=2.4.0,<3.0.0" +[[package]] +name = "ipython" +version = "8.12.3" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] + [[package]] name = "isodate" version = "0.6.1" @@ -1899,6 +2030,25 @@ pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib" plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + [[package]] name = "jinja2" version = "3.1.2" @@ -2168,6 +2318,20 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + [[package]] name = "mccabe" version = "0.6.1" @@ -2218,29 +2382,34 @@ files = [ [[package]] name = "mkdocs" -version = "1.3.1" +version = "1.5.2" description = "Project documentation with Markdown." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "mkdocs-1.3.1-py3-none-any.whl", hash = "sha256:fda92466393127d2da830bc6edc3a625a14b436316d1caf347690648e774c4f0"}, - {file = "mkdocs-1.3.1.tar.gz", hash = "sha256:a41a2ff25ce3bbacc953f9844ba07d106233cd76c88bac1f59cb1564ac0d87ed"}, + {file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"}, + {file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"}, ] [package.dependencies] -click = ">=3.3" +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = ">=4.3" -Jinja2 = ">=2.10.2" -Markdown = ">=3.2.1,<3.4" +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" packaging = ">=20.5" -PyYAML = ">=3.10" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] [[package]] name = "mkdocs-autorefs" @@ -2259,37 +2428,43 @@ mkdocs = ">=1.1" [[package]] name = "mkdocs-include-markdown-plugin" -version = "3.6.1" +version = "6.0.3" description = "Mkdocs Markdown includer plugin." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "mkdocs_include_markdown_plugin-3.6.1-py3-none-any.whl", hash = "sha256:ea36a7d50ee98028f03574d7bf40a307e16211ad3013a4e42f64494b3c106e9e"}, - {file = "mkdocs_include_markdown_plugin-3.6.1.tar.gz", hash = "sha256:5e7416f23081085a220f7534b2fc7456e74c5a65f3b401da1f29b9e9132b46e5"}, + {file = "mkdocs_include_markdown_plugin-6.0.3-py3-none-any.whl", hash = "sha256:8f9262cf4246ebc33dcdfbdb40c1253b7c9ad79e0f8dc2a9e338b1fb761d8e02"}, + {file = "mkdocs_include_markdown_plugin-6.0.3.tar.gz", hash = "sha256:9799ea8ac9179e9e91ab58869421be60a2585e3d9c4a53181d37a49d9a1780db"}, ] +[package.dependencies] +mkdocs = ">=1.4" +wcmatch = ">=8,<9" + [package.extras] -dev = ["bump2version (==1.0.1)", "flake8 (==3.9.2)", "flake8-implicit-str-concat (==0.2.0)", "flake8-print (==4.0.0)", "isort (==5.9.1)", "mdpo (==0.3.61)", "mkdocs (==1.2.3)", "pre-commit (==2.13.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "pyupgrade (==2.19.4)", "yamllint (==1.26.1)"] -test = ["pytest (==6.2.5)", "pytest-cov (==3.0.0)"] +cache = ["platformdirs"] [[package]] name = "mkdocs-material" -version = "8.4.2" +version = "9.1.15" description = "Documentation that simply works" optional = false python-versions = ">=3.7" files = [ - {file = "mkdocs-material-8.4.2.tar.gz", hash = "sha256:704c64c3fff126a3923c2961d95f26b19be621342a6a4e49ed039f0bb7a5c540"}, - {file = "mkdocs_material-8.4.2-py2.py3-none-any.whl", hash = "sha256:166287bb0e4197804906bf0389a852d5ced43182c30127ac8b48a4e497ecd7e5"}, + {file = "mkdocs_material-9.1.15-py3-none-any.whl", hash = "sha256:b49e12869ab464558e2dd3c5792da5b748a7e0c48ee83b4d05715f98125a7a39"}, + {file = "mkdocs_material-9.1.15.tar.gz", hash = "sha256:8513ab847c9a541ed3d11a3a7eed556caf72991ee786c31c5aac6691a121088a"}, ] [package.dependencies] -jinja2 = ">=3.0.2" +colorama = ">=0.4" +jinja2 = ">=3.0" markdown = ">=3.2" -mkdocs = ">=1.3.0" -mkdocs-material-extensions = ">=1.0.3" -pygments = ">=2.12" -pymdown-extensions = ">=9.4" +mkdocs = ">=1.4.2" +mkdocs-material-extensions = ">=1.1" +pygments = ">=2.14" +pymdown-extensions = ">=9.9.1" +regex = ">=2022.4.24" +requests = ">=2.26" [[package]] name = "mkdocs-material-extensions" @@ -2341,17 +2516,17 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "1.1.2" +version = "1.5.2" description = "A Python handler for mkdocstrings." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocstrings_python-1.1.2-py3-none-any.whl", hash = "sha256:c2b652a850fec8e85034a9cdb3b45f8ad1a558686edc20ed1f40b4e17e62070f"}, - {file = "mkdocstrings_python-1.1.2.tar.gz", hash = "sha256:f28bdcacb9bcdb44b6942a5642c1ea8b36870614d33e29e3c923e204a8d8ed61"}, + {file = "mkdocstrings_python-1.5.2-py3-none-any.whl", hash = "sha256:ed37ca6d216986e2ac3530c19c3e7be381d1e3d09ea414e4ff467d6fd2cbd9c1"}, + {file = "mkdocstrings_python-1.5.2.tar.gz", hash = "sha256:81eb4a93bc454a253daf247d1a11397c435d641c64fa165324c17c06170b1dfb"}, ] [package.dependencies] -griffe = ">=0.24" +griffe = ">=0.35" mkdocstrings = ">=0.20" [[package]] @@ -2734,6 +2909,21 @@ all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1 gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] invoke = ["invoke (>=2.0)"] +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + [[package]] name = "pathspec" version = "0.11.2" @@ -2756,6 +2946,31 @@ files = [ {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, ] +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] + [[package]] name = "pillow" version = "10.0.0" @@ -3028,6 +3243,31 @@ files = [ {file = "psycopg2_binary-2.9.8-cp39-cp39-win_amd64.whl", hash = "sha256:1f279ba74f0d6b374526e5976c626d2ac3b8333b6a7b08755c513f4d380d3add"}, ] +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "pycares" version = "4.3.0" @@ -3169,23 +3409,6 @@ typing-extensions = ">=4.2.0" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[[package]] -name = "pydocstyle" -version = "6.3.0" -description = "Python docstring style checker" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, - {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, -] - -[package.dependencies] -snowballstemmer = ">=2.2.0" - -[package.extras] -toml = ["tomli (>=1.2.3)"] - [[package]] name = "pyflakes" version = "2.3.1" @@ -3230,27 +3453,32 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pylint" -version = "2.13.9" +version = "2.17.7" description = "python code static checker" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.2" files = [ - {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, - {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, + {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, + {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, ] [package.dependencies] -astroid = ">=2.11.5,<=2.12.0-dev0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -dill = ">=0.2" +astroid = ">=2.15.8,<=2.17.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] -testutil = ["gitpython (>3)"] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] [[package]] name = "pylint-django" @@ -3444,7 +3672,7 @@ six = ">=1.5" name = "python-dotenv" version = "0.21.1" description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"}, @@ -3564,6 +3792,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -3571,8 +3800,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -3589,6 +3825,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -3596,6 +3833,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3633,6 +3871,103 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2 hiredis = ["hiredis (>=1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] +[[package]] +name = "regex" +version = "2023.10.3" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, + {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, + {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, + {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, + {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, + {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, + {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, + {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, + {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, + {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, + {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, + {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, + {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, + {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, + {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, +] + [[package]] name = "requests" version = "2.31.0" @@ -3706,6 +4041,25 @@ files = [ [package.dependencies] requests = ">=2.0.1,<3.0.0" +[[package]] +name = "responses" +version = "0.24.1" +description = "A utility library for mocking out the `requests` Python library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "responses-0.24.1-py3-none-any.whl", hash = "sha256:a2b43f4c08bfb9c9bd242568328c65a34b318741d3fab884ac843c5ceeb543f9"}, + {file = "responses-0.24.1.tar.gz", hash = "sha256:b127c6ca3f8df0eb9cc82fd93109a3007a86acb24871834c47b77765152ecf8c"}, +] + +[package.dependencies] +pyyaml = "*" +requests = ">=2.30.0,<3.0" +urllib3 = ">=1.25.10,<3.0" + +[package.extras] +tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-PyYAML", "types-requests"] + [[package]] name = "rfc3339-validator" version = "0.1.4" @@ -3799,7 +4153,8 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, @@ -3830,6 +4185,32 @@ files = [ {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] +[[package]] +name = "ruff" +version = "0.1.15" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, + {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, + {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, + {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, + {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, +] + [[package]] name = "rx" version = "1.6.3" @@ -3882,22 +4263,6 @@ files = [ [package.dependencies] paramiko = "*" -[[package]] -name = "setuptools" -version = "68.2.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, - {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "singledispatch" version = "4.1.0" @@ -3961,17 +4326,6 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - [[package]] name = "social-auth-app-django" version = "5.2.0" @@ -4030,6 +4384,25 @@ dev = ["build", "flake8"] doc = ["sphinx"] test = ["pytest", "pytest-cov"] +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] name = "stevedore" version = "5.1.0" @@ -4119,11 +4492,25 @@ 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" description = "Python Library for Tom's Obvious, Minimal Language" -optional = true +optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -4141,27 +4528,53 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tomlkit" +version = "0.12.1" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, + {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, +] + [[package]] name = "towncrier" -version = "22.8.0" +version = "23.6.0" description = "Building newsfiles for your project." optional = false python-versions = ">=3.7" files = [ - {file = "towncrier-22.8.0-py2.py3-none-any.whl", hash = "sha256:3b780c3d966e1b26414830aec3d15000654b31e64e024f3e5fd128b4c6eb8f47"}, - {file = "towncrier-22.8.0.tar.gz", hash = "sha256:7d3839b033859b45fb55df82b74cfd702431933c0cc9f287a5a7ea3e05d042cb"}, + {file = "towncrier-23.6.0-py3-none-any.whl", hash = "sha256:da552f29192b3c2b04d630133f194c98e9f14f0558669d427708e203fea4d0a5"}, + {file = "towncrier-23.6.0.tar.gz", hash = "sha256:fc29bd5ab4727c8dacfbe636f7fb5dc53b99805b62da1c96b214836159ff70c1"}, ] [package.dependencies] click = "*" click-default-group = "*" +importlib-resources = {version = ">=5", markers = "python_version < \"3.10\""} incremental = "*" jinja2 = "*" -setuptools = "*" -tomli = "*" +tomli = {version = "*", markers = "python_version < \"3.11\""} [package.extras] -dev = ["packaging"] +dev = ["furo", "packaging", "sphinx (>=5)", "twisted"] + +[[package]] +name = "traitlets" +version = "5.11.2" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"}, + {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "types-protobuf" @@ -4335,6 +4748,20 @@ files = [ [package.extras] watchmedo = ["PyYAML (>=3.10)"] +[[package]] +name = "wcmatch" +version = "8.5" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-8.5-py3-none-any.whl", hash = "sha256:14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5"}, + {file = "wcmatch-8.5.tar.gz", hash = "sha256:86c17572d0f75cbf3bcb1a18f3bf2f9e72b39a9c08c9b4a74e991e1882a8efb3"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + [[package]] name = "wcwidth" version = "0.2.6" @@ -4462,24 +4889,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" @@ -4596,4 +5005,4 @@ panorama = ["defusedxml", "ipaddr", "netmiko", "netutils", "pan-os-python"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "4c11a5938fe94cefce25e82a6d2fbdcb03a1342eef3ebb8a4193d8cae10b4721" +content-hash = "2494c3e26a2bd784e48c4ed707faa4c9667f047d4e160a58cffc8138bce6b637" diff --git a/pyproject.toml b/pyproject.toml index 1cf5dde0..118823bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,27 @@ [tool.poetry] name = "nautobot-chatops" -version = "3.0.1" -description = "A plugin providing chatbot capabilities for Nautobot" +version = "3.0.2" +description = "A app providing chatbot capabilities for Nautobot" authors = ["Network to Code, LLC "] +license = "Apache-2.0" readme = "README.md" -homepage = "https://github.com/nautobot/nautobot-plugin-chatops" -repository = "https://github.com/nautobot/nautobot-plugin-chatops" -documentation = "https://docs.nautobot.com/projects/chatops/en/stable/" -keywords = ["nautobot", "nautobot-plugin"] +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", + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] +packages = [ + { include = "nautobot_chatops" }, +] include = [ - "LICENSE", - "README.md", # Poetry by default will exclude files that are in .gitignore "nautobot_chatops/static/nautobot_chatops/docs/**/*", ] @@ -19,12 +30,13 @@ include = [ "aci" = "nautobot_chatops.integrations.aci.worker:aci" "ansible" = "nautobot_chatops.integrations.ansible.worker:ansible" "clear" = "nautobot_chatops.workers.clear:clear" -"cloudvision" = "nautobot_chatops.integrations.aristacv.worker:cloudvision" +"cloudvision" = "nautobot_chatops.integrations.cloudvision.worker:cloudvision" "grafana" = "nautobot_chatops.integrations.grafana.worker:grafana" "ipfabric" = "nautobot_chatops.integrations.ipfabric.worker:ipfabric" "meraki" = "nautobot_chatops.integrations.meraki.worker:cisco_meraki" "nautobot" = "nautobot_chatops.workers.nautobot:nautobot" "panorama" = "nautobot_chatops.integrations.panorama.worker:panorama" +"nso" = "nautobot_chatops.integrations.nso.worker:nso" [tool.poetry.dependencies] Markdown = "!=3.3.5" @@ -59,34 +71,32 @@ termcolor = { version = "1.1.0", optional = true } texttable = "^1.6.2" webexteamssdk = "^1.3" -[tool.poetry.dev-dependencies] -black = "*" -yamllint = "*" +[tool.poetry.group.dev.dependencies] +Markdown = "*" bandit = "*" -# Pinning older pylint due to https://github.com/pylint-dev/pylint/issues/7381 -pylint = "2.13.9" -pylint-django = "*" -pydocstyle = "*" -prybar = "*" +black = "*" +coverage = "~5.4" +django-debug-toolbar = "*" +flake8 = "*" invoke = "*" -flake8 = "^3.9.2" -griffe = "0.30.1" -# Rendering docs to HTML -mkdocs = "1.3.1" -# Material for mkdocs theme -mkdocs-material = "8.4.2" -# Automatic documentation from sources, for MkDocs +ipython = "*" +mkdocs = "1.5.2" +mkdocs-include-markdown-plugin = "6.0.3" +mkdocs-material = "9.1.15" +mkdocs-version-annotations = "1.0.0" mkdocstrings = "0.22.0" -mkdocstrings-python = "1.1.2" -# Render custom markdown for version added/changed/remove notes -mkdocs-version-annotations = "~1.0.0" -# Allow Markdown files to include other files -mkdocs-include-markdown-plugin = "~3.6.1" -python-dotenv = "^0.21.1" -# Change log management and generation -towncrier = "~22.8.0" -coverage = "~5.4" +mkdocstrings-python = "1.5.2" +prybar = "*" +pylint = "*" +pylint-django = "*" +pylint-nautobot = "*" requests-mock = "^1.9.3" +ruff = "*" +toml = "*" +towncrier = "~23.6.0" +to-json-schema = "*" +jsonschema = "*" +responses = "^0.24.0" [tool.poetry.extras] all = [ @@ -146,12 +156,9 @@ panorama = [ ] nautobot = ["nautobot"] -[tool.poetry.group.dev.dependencies] -pylint-nautobot = "^0.2.0" - [tool.black] line-length = 120 -target-version = ['py36'] +target-version = ['py38', 'py39', 'py310', 'py311'] include = '\.pyi?$' exclude = ''' ( @@ -173,53 +180,135 @@ exclude = ''' ''' [tool.pylint.master] -# Including the pylint_django plugin -load-plugins=["pylint_nautobot", "pylint_django"] - -[tool.pylint.message_control] -disable=""", - django-not-configured, - too-few-public-methods, - too-many-lines, - too-many-ancestors, - nb-incorrect-base-class, - """ +# Include the pylint_django plugin to avoid spurious warnings about Django patterns +load-plugins="pylint_django, pylint_nautobot" +ignore=".venv" + +[tool.pylint.basic] +# No docstrings required for private methods (Pylint default), or for test_ functions, or for inner Meta classes. +no-docstring-rgx="^(_|test_|Meta$)" + +[tool.pylint.messages_control] +# Line length is enforced by Black, so pylint doesn't need to check it. +# Pylint and Black disagree about how to format multi-line arrays; Black wins. +disable = [ + "line-too-long", + "nb-incorrect-base-class", + "too-few-public-methods", + "too-many-ancestors", + "too-many-arguments", + "too-many-lines", +] [tool.pylint.miscellaneous] -notes=""", +# Don't flag TODO as a failure, let us commit with things that still need to be done in the code +notes = """, FIXME, XXX, """ -[tool.pylint.design] -max-args=6 -max-public-methods=22 - [tool.pylint.similarities] -ignore-imports= true -min-similarity-lines=0 - -[tool.pylint.format] -max-line-length=120 +ignore-imports = true +min-similarity-lines = 0 [tool.pylint-nautobot] -supported_nautobot_versions = ["2",] +supported_nautobot_versions = [ + "2.0.0" +] + +[tool.ruff] +line-length = 120 +target-version = "py38" + +[tool.ruff.lint] +select = [ + "D", # pydocstyle +] +ignore = [ + # warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. + "D203", # 1 blank line required before class docstring + + # D212 is enabled by default in google convention, and complains if we have a docstring like: + # """ + # My docstring is on the line after the opening quotes instead of on the same line as them. + # """ + # We've discussed and concluded that we consider this to be a valid style choice. + "D212", # Multi-line docstring summary should start at the first line + "D213", # Multi-line docstring summary should start at the second line + + # Produces a lot of issues in the current codebase. + "D401", # First line of docstring should be in imperative mood + "D407", # Missing dashed underline after section + "D416", # Section name ends in colon + + # Package specific + "D417", # Missing argument descriptions in Docstrings +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.per-file-ignores] +"nautobot_chatops/migrations/*" = [ + "D", # pydocstyle +] +"nautobot_chatops/tests/*" = [ + "D", # pydocstyle +] [build-system] -requires = ["poetry-core>=1.0.0"] +requires = ["poetry_core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.towncrier] package = "nautobot_chatops" directory = "changes" -filename = "docs/admin/release_notes/version_3.0.md" +filename = "docs/admin/release_notes/version_X.Y.md" template = "development/towncrier_template.j2" start_string = "" -issue_format = "[#{issue}](https://github.com/nautobot/nautobot-plugin-chatops/issues/{issue})" - -[tool.towncrier.fragment.added] -[tool.towncrier.fragment.changed] -[tool.towncrier.fragment.deprecated] -[tool.towncrier.fragment.fixed] -[tool.towncrier.fragment.removed] -[tool.towncrier.fragment.security] +issue_format = "[#{issue}](https://github.com/nautobot/nautobot-app-chatops/issues/{issue})" + +[[tool.towncrier.type]] +directory = "security" +name = "Security" +showcontent = true + +[[tool.towncrier.type]] +directory = "added" +name = "Added" +showcontent = true + +[[tool.towncrier.type]] +directory = "changed" +name = "Changed" +showcontent = true + +[[tool.towncrier.type]] +directory = "deprecated" +name = "Deprecated" +showcontent = true + +[[tool.towncrier.type]] +directory = "removed" +name = "Removed" +showcontent = true + +[[tool.towncrier.type]] +directory = "fixed" +name = "Fixed" +showcontent = true + +[[tool.towncrier.type]] +directory = "dependencies" +name = "Dependencies" +showcontent = true + +[[tool.towncrier.type]] +directory = "documentation" +name = "Documentation" +showcontent = true + +[[tool.towncrier.type]] +directory = "housekeeping" +name = "Housekeeping" +showcontent = true diff --git a/tasks.py b/tasks.py index e8674a6a..62dad57a 100644 --- a/tasks.py +++ b/tasks.py @@ -1,6 +1,6 @@ """Tasks for use with Invoke. -(c) 2020-2021 Network To Code +Copyright (c) 2023, Network to Code, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -12,16 +12,12 @@ limitations under the License. """ -from distutils.util import strtobool -from invoke import Collection, task as invoke_task import os +from pathlib import Path +from time import sleep -from dotenv import load_dotenv - - -def _load_dotenv(): - load_dotenv("./development/development.env") - load_dotenv("./development/creds.env") +from invoke.collection import Collection +from invoke.tasks import task as invoke_task def is_truthy(arg): @@ -36,7 +32,14 @@ def is_truthy(arg): """ if isinstance(arg, bool): return arg - return bool(strtobool(arg)) + + val = str(arg).lower() + if val in ("y", "yes", "t", "true", "on", "1"): + return True + elif val in ("n", "no", "f", "false", "off", "0"): + return False + else: + raise ValueError(f"Invalid truthy value: `{arg}`") # Use pyinvoke configuration for default values, see http://docs.pyinvoke.org/en/stable/concepts/configuration.html @@ -47,7 +50,7 @@ def is_truthy(arg): "nautobot_chatops": { "nautobot_ver": "2.0.0", "project_name": "nautobot-chatops", - "python_ver": "3.10", + "python_ver": "3.11", "local": False, "compose_dir": os.path.join(os.path.dirname(__file__), "development"), "compose_files": [ @@ -64,6 +67,29 @@ def is_truthy(arg): ) +def _is_compose_included(context, name): + return f"docker-compose.{name}.yml" in context.nautobot_chatops.compose_files + + +def _await_healthy_service(context, service): + container_id = docker_compose(context, f"ps -q -- {service}", pty=False, echo=False, hide=True).stdout.strip() + _await_healthy_container(context, container_id) + + +def _await_healthy_container(context, container_id): + while True: + result = context.run( + "docker inspect --format='{{.State.Health.Status}}' " + container_id, + pty=False, + echo=False, + hide=True, + ) + if result.stdout.strip() == "healthy": + break + print(f"Waiting for `{container_id}` container to become healthy ...") + sleep(1) + + def task(function=None, *args, **kwargs): """Task decorator to override the default Invoke task decorator and add each task to the invoke namespace.""" @@ -125,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) @@ -169,10 +207,17 @@ def generate_packages(context): run_command(context, command) -@task -def lock(context): +@task( + help={ + "check": ( + "If enabled, check for outdated dependencies in the poetry.lock file, " + "instead of generating a new one. (default: disabled)" + ) + } +) +def lock(context, check=False): """Generate poetry.lock inside the Nautobot container.""" - run_command(context, "poetry lock --no-update") + run_command(context, f"poetry {'check' if check else 'lock --no-update'}") # ------------------------------------------------------------------------------ @@ -206,11 +251,46 @@ def stop(context, service=""): docker_compose(context, "stop" if service else "down --remove-orphans", service=service) -@task -def destroy(context): +@task( + aliases=("down",), + help={ + "volumes": "Remove Docker compose volumes (default: True)", + "import-db-file": "Import database from `import-db-file` file into the fresh environment (default: empty)", + }, +) +def destroy(context, volumes=True, import_db_file=""): """Destroy all containers and volumes.""" print("Destroying Nautobot...") - docker_compose(context, "down --remove-orphans --volumes") + docker_compose(context, f"down --remove-orphans {'--volumes' if volumes else ''}") + + if not import_db_file: + return + + if not volumes: + raise ValueError("Cannot specify `--no-volumes` and `--import-db-file` arguments at the same time.") + + print(f"Importing database file: {import_db_file}...") + + input_path = Path(import_db_file).absolute() + if not input_path.is_file(): + raise ValueError(f"File not found: {input_path}") + + command = [ + "run", + "--rm", + "--detach", + f"--volume='{input_path}:/docker-entrypoint-initdb.d/dump.sql'", + "--", + "db", + ] + + container_id = docker_compose(context, " ".join(command), pty=False, echo=False, hide=True).stdout.strip() + _await_healthy_container(context, container_id) + print("Stopping database container...") + context.run(f"docker stop {container_id}", pty=False, echo=False, hide=True) + + print("Database import complete, you can start Nautobot with the following command:") + print("invoke start") @task @@ -261,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 @@ -360,160 +447,180 @@ def exec(context, service="nautobot", command="bash", file=""): @task( help={ + "db-name": "Database name (default: Nautobot database)", + "input-file": "SQL file to execute and quit (default: empty, start interactive CLI)", + "output-file": "Ouput file, overwrite if exists (default: empty, output to stdout)", "query": "SQL command to execute and quit (default: empty)", - "input": "SQL file to execute and quit (default: empty)", - "output": "Ouput file, overwrite if exists (default: empty)", } ) -def dbshell(context, query="", input="", output=""): +def dbshell(context, db_name="", input_file="", output_file="", query=""): """Start database CLI inside the running `db` container. Doesn't use `nautobot-server dbshell`, using started `db` service container only. """ - if input and query: - raise ValueError("Cannot specify both, `input` and `query` arguments") - if output and not (input or query): - raise ValueError("`output` argument requires `input` or `query` argument") + if input_file and query: + raise ValueError("Cannot specify both, `input_file` and `query` arguments") + if output_file and not (input_file or query): + raise ValueError("`output_file` argument requires `input_file` or `query` argument") - _load_dotenv() + env = {} + if query: + env["_SQL_QUERY"] = query - service = "db" - env_vars = {} - command = ["exec"] + command = [ + "exec", + "--env=_SQL_QUERY" if query else "", + "-- db sh -c '", + ] - if "docker-compose.mysql.yml" in context.nautobot_chatops.compose_files: - env_vars["MYSQL_PWD"] = os.getenv("MYSQL_PASSWORD") + if _is_compose_included(context, "mysql"): command += [ - "--env=MYSQL_PWD", - "--", - service, "mysql", - f"--user='{os.getenv('MYSQL_USER')}'", - f"--database='{os.getenv('MYSQL_DATABASE')}'", + "--user=$MYSQL_USER", + "--password=$MYSQL_PASSWORD", + f"--database={db_name or '$MYSQL_DATABASE'}", ] - if query: - command += [f"--execute='{query}'"] - elif "docker-compose.postgres.yml" in context.nautobot_chatops.compose_files: + elif _is_compose_included(context, "postgres"): command += [ - "--", - service, "psql", - f"--username='{os.getenv('POSTGRES_USER')}'", - f"--dbname='{os.getenv('POSTGRES_DB')}'", + "--username=$POSTGRES_USER", + f"--dbname={db_name or '$POSTGRES_DB'}", ] - if query: - command += [f"--command='{query}'"] else: raise ValueError("Unsupported database backend.") - if input: - command += [f"< '{input}'"] - if output: - command += [f"> '{output}'"] + command += [ + "'", + '<<<"$_SQL_QUERY"' if query else "", + f"< '{input_file}'" if input_file else "", + f"> '{output_file}'" if output_file else "", + ] - docker_compose(context, " ".join(command), env=env_vars, pty=not (input or output or query)) + docker_compose(context, " ".join(command), env=env, pty=not (input_file or output_file or query)) @task( help={ - "input": "SQL dump file to replace the existing database with. This can be generated using `invoke backup-db` (default: `dump.sql`).", + "db-name": "Database name to create (default: Nautobot database)", + "input-file": "SQL dump file to replace the existing database with. This can be generated using `invoke backup-db` (default: `dump.sql`).", } ) -def import_db(context, input="dump.sql"): - """Stop Nautobot containers and replace the current database with the dump into the running `db` container.""" - docker_compose(context, "stop -- nautobot worker") +def import_db(context, db_name="", input_file="dump.sql"): + """Stop Nautobot containers and replace the current database with the dump into `db` container.""" + docker_compose(context, "stop -- nautobot worker beat") + start(context, "db") + _await_healthy_service(context, "db") - _load_dotenv() + command = ["exec -- db sh -c '"] - service = "db" - env_vars = {} - command = ["exec"] - - if "docker-compose.mysql.yml" in context.nautobot_chatops.compose_files: - env_vars["MYSQL_PWD"] = os.getenv("MYSQL_PASSWORD") + if _is_compose_included(context, "mysql"): + if not db_name: + db_name = "$MYSQL_DATABASE" command += [ - "--env=MYSQL_PWD", - "--", - service, + "mysql --user root --password=$MYSQL_ROOT_PASSWORD", + '--execute="', + f"DROP DATABASE IF EXISTS {db_name};", + f"CREATE DATABASE {db_name};", + "" + if db_name == "$MYSQL_DATABASE" + else f"GRANT ALL PRIVILEGES ON {db_name}.* TO $MYSQL_USER; FLUSH PRIVILEGES;", + '"', + "&&", "mysql", - f"--user='{os.getenv('MYSQL_USER')}'", - f"--database='{os.getenv('MYSQL_DATABASE')}'", + f"--database={db_name}", + "--user=$MYSQL_USER", + "--password=$MYSQL_PASSWORD", ] - elif "docker-compose.postgres.yml" in context.nautobot_chatops.compose_files: + elif _is_compose_included(context, "postgres"): + if not db_name: + db_name = "$POSTGRES_DB" command += [ - "--", - service, - "psql", - f"--username='{os.getenv('POSTGRES_USER')}'", - "postgres", + f"dropdb --if-exists --user=$POSTGRES_USER {db_name} &&", + f"createdb --user=$POSTGRES_USER {db_name} &&", + f"psql --user=$POSTGRES_USER --dbname={db_name}", ] else: raise ValueError("Unsupported database backend.") - command += [f"< '{input}'"] + command += [ + "'", + f"< '{input_file}'", + ] - docker_compose(context, " ".join(command), env=env_vars, pty=False) + docker_compose(context, " ".join(command), pty=False) print("Database import complete, you can start Nautobot now: `invoke start`") @task( help={ - "output": "Ouput file, overwrite if exists (default: `dump.sql`)", + "db-name": "Database name to backup (default: Nautobot database)", + "output-file": "Ouput file, overwrite if exists (default: `dump.sql`)", "readable": "Flag to dump database data in more readable format (default: `True`)", } ) -def backup_db(context, output="dump.sql", readable=True): - """Dump database into `output` file from running `db` container.""" - _load_dotenv() +def backup_db(context, db_name="", output_file="dump.sql", readable=True): + """Dump database into `output_file` file from `db` container.""" + start(context, "db") + _await_healthy_service(context, "db") - service = "db" - env_vars = {} - command = ["exec"] + command = ["exec -- db sh -c '"] - if "docker-compose.mysql.yml" in context.nautobot_chatops.compose_files: - env_vars["MYSQL_PWD"] = os.getenv("MYSQL_ROOT_PASSWORD") + if _is_compose_included(context, "mysql"): command += [ - "--env=MYSQL_PWD", - "--", - service, "mysqldump", "--user=root", - "--add-drop-database", + "--password=$MYSQL_ROOT_PASSWORD", "--skip-extended-insert" if readable else "", - "--databases", - os.getenv("MYSQL_DATABASE", ""), + db_name if db_name else "$MYSQL_DATABASE", ] - elif "docker-compose.postgres.yml" in context.nautobot_chatops.compose_files: + elif _is_compose_included(context, "postgres"): command += [ - "--", - service, "pg_dump", - "--clean", - "--create", - "--if-exists", - f"--username='{os.getenv('POSTGRES_USER')}'", - f"--dbname='{os.getenv('POSTGRES_DB')}'", + "--username=$POSTGRES_USER", + f"--dbname={db_name or '$POSTGRES_DB'}", + "--inserts" if readable else "", ] - - if readable: - command += ["--inserts"] else: raise ValueError("Unsupported database backend.") - if output: - command += [f"> '{output}'"] + command += [ + "'", + f"> '{output_file}'", + ] - docker_compose(context, " ".join(command), env=env_vars, pty=False) + docker_compose(context, " ".join(command), pty=False) print(50 * "=") - print("The database backup has been successfully completed and saved to the file:") - print(output) - print("If you want to import this database backup, please execute the following command:") - print(f"invoke import-db --input '{output}'") + print("The database backup has been successfully completed and saved to the following file:") + print(output_file) + print("You can import this database backup with the following command:") + print(f"invoke import-db --input-file '{output_file}'") print(50 * "=") +# ------------------------------------------------------------------------------ +# DOCS +# ------------------------------------------------------------------------------ +@task +def docs(context): + """Build and serve docs locally for development.""" + command = "mkdocs serve -v" + + if is_truthy(context.nautobot_chatops.local): + print(">>> Serving Documentation at http://localhost:8001") + run_command(context, command) + else: + start(context, service="docs") + + +@task +def build_and_check_docs(context): + """Build documentation to be available within Nautobot.""" + command = "mkdocs build --no-directory-urls --strict" + run_command(context, command) + + @task(name="help") def help_task(context): """Print the help of available tasks.""" @@ -526,6 +633,19 @@ def help_task(context): context.run(f"invoke {task_name} --help") +@task( + help={ + "version": "Version of Nautobot ChatOps App to generate the release notes for.", + } +) +def generate_release_notes(context, version=""): + """Generate Release Notes using Towncrier.""" + command = "env DJANGO_SETTINGS_MODULE=nautobot.core.settings towncrier build" + if version: + command += f" --version {version}" + run_command(context, command) + + # ------------------------------------------------------------------------------ # TESTS # ------------------------------------------------------------------------------ @@ -567,12 +687,34 @@ def pylint(context): run_command(context, command) -@task -def pydocstyle(context): - """Run pydocstyle to validate docstring formatting adheres to NTC defined standards.""" - # We exclude the /migrations/ directory since it is autogenerated code - command = 'pydocstyle --config=.pydocstyle.ini --match-dir="^(?!migrations).*"' - run_command(context, command) +@task(aliases=("a",)) +def autoformat(context): + """Run code autoformatting.""" + black(context, autoformat=True) + ruff(context, fix=True) + + +@task( + help={ + "action": "One of 'lint', 'format', or 'both'", + "fix": "Automatically fix selected action. May not be able to fix all.", + "output_format": "see https://docs.astral.sh/ruff/settings/#output-format", + }, +) +def ruff(context, action="lint", fix=False, output_format="text"): + """Run ruff to perform code formatting and/or linting.""" + if action != "lint": + command = "ruff format" + if not fix: + command += " --check" + command += " ." + run_command(context, command) + if action != "format": + command = "ruff check" + if fix: + command += " --fix" + command += f" --output-format {output_format} ." + run_command(context, command) @task @@ -584,7 +726,7 @@ def bandit(context): @task def yamllint(context): - """Run yamllint to validate formating adheres to NTC defined YAML standards. + """Run yamllint to validate formatting adheres to NTC defined YAML standards. Args: context (obj): Used to run specific commands @@ -596,15 +738,8 @@ def yamllint(context): @task def check_migrations(context): """Check for missing migrations.""" - command = "nautobot-server --config=nautobot/core/tests/nautobot_config.py makemigrations --dry-run --check" - - run_command(context, command) + command = "nautobot-server makemigrations --dry-run --check" - -@task() -def build_and_check_docs(context): - """Build docs for use within Nautobot.""" - command = "mkdocs build --no-directory-urls --strict" run_command(context, command) @@ -615,9 +750,18 @@ def build_and_check_docs(context): "failfast": "fail as soon as a single test fails don't run the entire test suite", "buffer": "Discard output from passing tests", "pattern": "Run specific test methods, classes, or modules instead of all tests", + "verbose": "Enable verbose test output.", } ) -def unittest(context, keepdb=False, label="nautobot_chatops", failfast=False, buffer=True, pattern=""): +def unittest( + context, + keepdb=False, + label="nautobot_chatops", + failfast=False, + buffer=True, + pattern="", + verbose=False, +): """Run Nautobot unit tests.""" command = f"coverage run --module nautobot.core.cli test {label}" @@ -629,6 +773,9 @@ def unittest(context, keepdb=False, label="nautobot_chatops", failfast=False, bu command += " --buffer" if pattern: command += f" -k='{pattern}'" + if verbose: + command += " --verbosity 2" + run_command(context, command) @@ -642,11 +789,13 @@ def unittest_coverage(context): @task( help={ - "failfast": "fail as soon as a single test fails don't run the entire test suite", + "failfast": "fail as soon as a single test fails don't run the entire test suite. (default: False)", + "keepdb": "Save and re-use test database between test runs for faster re-testing. (default: False)", + "lint-only": "Only run linters; unit tests will be excluded. (default: False)", } ) -def tests(context, failfast=False): - """Run all tests for this plugin.""" +def tests(context, failfast=False, keepdb=False, lint_only=False): + """Run all tests for this app.""" # If we are not running locally, start the docker containers so we don't have to for each test if not is_truthy(context.nautobot_chatops.local): print("Starting Docker Containers...") @@ -654,22 +803,52 @@ def tests(context, failfast=False): # Sorted loosely from fastest to slowest print("Running black...") black(context) + print("Running ruff...") + ruff(context) print("Running flake8...") flake8(context) print("Running bandit...") bandit(context) - print("Running pydocstyle...") - pydocstyle(context) print("Running yamllint...") yamllint(context) + print("Running poetry check...") + lock(context, check=True) + print("Running migrations check...") + check_migrations(context) print("Running pylint...") pylint(context) - print("Building and checking docs...") + print("Running mkdocs...") build_and_check_docs(context) - print("Running unit tests...") - unittest(context, failfast=failfast) + print("Checking app config schema...") + validate_app_config(context) + if not lint_only: + print("Running unit tests...") + unittest(context, failfast=failfast, keepdb=keepdb) + unittest_coverage(context) print("All tests have passed!") - unittest_coverage(context) + + +@task +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. + + Its content is inferred from: + + - 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 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"}) # ------------------------------------------------------------------------------ @@ -686,44 +865,21 @@ def backup_mattermost(context): """Export Mattermost data to the SQL file. Certain tables are ignored.""" output = "./development/mattermost/dump.sql" - ignore_tables = [ - "Audits", - "ChannelMemberHistory", - "CommandWebhooks", - "Posts", - "PostsPriority", - "Sessions", - "UploadSessions", - ] - - base_command = [ + command = [ "exec", - "--env MYSQL_PWD=mostest", "--", "mattermost", - "mysqldump", - "--databases mattermost_test", - "--compact", - "-u root", - ] - - # Dump schema first - command = [ - *base_command, - "--add-drop-database", - "--no-data", + "bash", + "-c", + "'", + "pg_dump", + "--inserts", + "--user=$POSTGRES_USER", + "--dbname=$POSTGRES_DB", + "'", f"> {output}", ] - docker_compose(context, " ".join(command)) - # Dump data for all tables except ignored - command = [ - *base_command, - *(f"--ignore-table mattermost_test.{table}" for table in ignore_tables), - "--no-create-info", - "--skip-extended-insert", - f">> {output}", - ] docker_compose(context, " ".join(command)) @@ -744,16 +900,3 @@ def connect_awx_container(context, container_name="tools_awx_1"): 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") - - -@task( - help={ - "version": "Version of Nautobot ChatOps to generate the release notes for.", - } -) -def generate_release_notes(context, version=""): - """Generate Release Notes using Towncrier.""" - command = "env DJANGO_SETTINGS_MODULE=nautobot.core.settings towncrier build" - if version: - command += f" --version {version}" - run_command(context, command)