Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.2 Rollup #13

Merged
merged 11 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[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
# E203, W503: Black disagrees with this rule, as does PEP 8; Black wins
ignore = E501, W503, E203
2 changes: 0 additions & 2 deletions files/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,6 @@ development/*.txt
invoke.yml

# Docs
docs/README.md
docs/CHANGELOG.md
public
/compose.yaml
/dump.sql
2 changes: 1 addition & 1 deletion nautobot-app/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"project_slug": "nautobot-plugin-{{cookiecutter.plugin_slug}}",
"repo_url": "https://github.com/{{cookiecutter.github_org}}/{{cookiecutter.project_slug}}",
"base_url": "{{cookiecutter.plugin_slug}}",
"min_nautobot_version": "1.5.2",
"min_nautobot_version": "1.6.0",
"max_nautobot_version": "1.9999",
"nautobot_version": "latest",
"camel_name": "{{cookiecutter.plugin_slug.title().replace(' ', '').replace('-', '')}}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,17 @@ jobs:
strategy:
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
fail-fast: true
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
db-backend: ["postgresql"]
nautobot-version: ["stable"]
include:
- python-version: "3.10"
- python-version: "3.11"
db-backend: "postgresql"
nautobot-version: "{{cookiecutter.min_nautobot_version}}"
- python-version: "3.7"
- python-version: "3.8"
db-backend: "mysql"
nautobot-version: "{{cookiecutter.min_nautobot_version}}"
- python-version: "3.10"
- python-version: "3.11"
db-backend: "mysql"
nautobot-version: "stable"
runs-on: "ubuntu-20.04"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
"""Nautobot development configuration file."""
# pylint: disable=invalid-envvar-default
import os
import sys

from nautobot.core.settings import * # noqa: F403 # pylint: disable=wildcard-import,unused-wildcard-import
from nautobot.core.settings_funcs import parse_redis_connection, is_truthy
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
Expand All @@ -14,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 = {
Expand Down Expand Up @@ -43,20 +59,28 @@
DATABASES["default"]["OPTIONS"] = {"charset": "utf8mb4"}

#
# Debug
# Redis
#

DEBUG = is_truthy(os.getenv("NAUTOBOT_DEBUG", False))

TESTING = len(sys.argv) > 1 and sys.argv[1] == "test"
# 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",
},
}
}

# Django Debug Toolbar
DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING}
# Redis Cacheops
CACHEOPS_REDIS = parse_redis_connection(redis_database=1)

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
Expand All @@ -65,7 +89,7 @@
LOG_LEVEL = "DEBUG" if DEBUG else "INFO"

# 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,
Expand Down Expand Up @@ -101,41 +125,14 @@
}

#
# 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 = ["{{cookiecutter.plugin_name}}"]

# 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 = {
# '{{cookiecutter.plugin_name}}': {
# 'foo': 'bar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ 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: {{cookiecutter.nautobot_version}})
- `project_name`: the default docker compose project name (default: `{{cookiecutter.plugin_name}}`)
- `project_name`: the default docker compose project name (default: `{{cookiecutter.plugin_slug}}`)
- `python_ver`: the version of Python to use as a base for any built docker containers (default: 3.8)
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
- `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
Expand Down Expand Up @@ -152,7 +152,7 @@ Poetry is used in lieu of the "virtualenv" commands and is leveraged in both env
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 virtualenvs. To install project dependencies in the virtual environment, you should run `poetry install` - this will install **both** project and development dependencies.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
griffe==0.30.1
mkdocs==1.4.3
mkdocs-material==9.1.15
mkdocstrings==0.22.0
mkdocstrings-python==1.1.2
mkdocstrings-python==1.3.0
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
mkdocs-version-annotations==1.0.0
mkdocs==1.4.3
mkdocstrings-python==1.1.2
mkdocstrings==0.22.0
2 changes: 1 addition & 1 deletion nautobot-app/{{ cookiecutter.project_slug }}/mkdocs.yml
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
dev_addr: "127.0.0.1:8001"
edit_uri: "blob/develop/docs"
edit_uri: "edit/main/{{cookiecutter.project_slug}}/docs"
site_dir: "{{cookiecutter.plugin_name}}/static/{{cookiecutter.plugin_name}}/docs"
site_name: "{{cookiecutter.verbose_name}} Documentation"
site_url: "{{cookiecutter.docs_app_url}}/"
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
34 changes: 22 additions & 12 deletions nautobot-app/{{ cookiecutter.project_slug }}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ readme = "README.md"
homepage = "{{cookiecutter.repo_url}}"
repository = "{{cookiecutter.repo_url}}"
keywords = ["nautobot", "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",
]
include = [
{%- if cookiecutter.open_source_license == 'Apache-2.0' %}
"LICENSE",
Expand All @@ -21,28 +30,30 @@ packages = [
]

[tool.poetry.dependencies]
python = "^3.7"
# Required for Python 3.7 for now. See: https://stackoverflow.com/a/73932581/194311
importlib-metadata = "4.13.0"
python = ">=3.8,<3.12"
# Used for local development
nautobot = { version = "^{{cookiecutter.min_nautobot_version}}", optional = true }

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
Markdown = "*"
bandit = "*"
black = "*"
coverage = "*"
django-debug-toolbar = "*"
# we need to pin flake8 because of package dependencies that cause it to downgrade and
# therefore cause issues with linting since older versions do not take .flake8 as config
flake8 = "^3.9.2"
flake8 = "*"
invoke = "*"
ipython = "*"
mkdocs = "1.4.3"
mkdocs-material = "9.1.15"
mkdocs-version-annotations = "1.0.0"
mkdocstrings = "0.22.0" # Last version with python 3.7 support
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
mkdocstrings-python = "1.1.2" # Last version with python 3.7 support
pydocstyle = "*"
pylint = "*"
pylint-django = "*"
pylint-nautobot = "*"
pytest = "*"
python-dotenv = "^0.21.1"
python-dotenv = "^1.0.0"
yamllint = "*"
Markdown = "*"
toml = "*"
Expand All @@ -53,16 +64,15 @@ mkdocs-material = "9.1.15"
# Render custom markdown for version added/changed/remove notes
mkdocs-version-annotations = "1.0.0"
# Automatic documentation from sources, for MkDocs
mkdocstrings = "0.22.0" # Last version with python 3.7 support
mkdocstrings-python = "1.1.2" # Last version with python 3.7 support
griffe = "0.30.1" # Last version with python 3.7 support
mkdocstrings = "0.22.0"
mkdocstrings-python = "1.3.0"
bryanculver marked this conversation as resolved.
Show resolved Hide resolved

[tool.poetry.extras]
nautobot = ["nautobot"]

[tool.black]
line-length = 120
target-version = ['py37']
target-version = ['py38', 'py39', 'py310', 'py311']
include = '\.pyi?$'
exclude = '''
(
Expand Down
31 changes: 23 additions & 8 deletions nautobot-app/{{ cookiecutter.project_slug }}/tasks.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -46,7 +46,7 @@ def is_truthy(arg):
{
"{{cookiecutter.plugin_name}}": {
"nautobot_ver": "{{cookiecutter.nautobot_version}}",
"project_name": "{{cookiecutter.plugin_name}}",
"project_name": "{{cookiecutter.plugin_slug}}",
"python_ver": "3.8",
bryanculver marked this conversation as resolved.
Show resolved Hide resolved
"local": False,
"compose_dir": os.path.join(os.path.dirname(__file__), "development"),
Expand Down Expand Up @@ -616,7 +616,7 @@ 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"
command = "nautobot-server makemigrations --dry-run --check"

run_command(context, command)

Expand All @@ -628,9 +628,18 @@ def check_migrations(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="{{cookiecutter.plugin_name}}", failfast=False, buffer=True, pattern=""):
def unittest(
context,
keepdb=False,
label="{{cookiecutter.plugin_name}}",
failfast=False,
buffer=True,
pattern="",
verbose=False,
):
"""Run Nautobot unit tests."""
command = f"coverage run --module nautobot.core.cli test {label}"

Expand All @@ -642,6 +651,9 @@ def unittest(context, keepdb=False, label="{{cookiecutter.plugin_name}}", failfa
command += " --buffer"
if pattern:
command += f" -k='{pattern}'"
if verbose:
command += " --verbosity 2"

run_command(context, command)


Expand All @@ -655,10 +667,12 @@ 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):
def tests(context, failfast=False, keepdb=False, lint_only=False):
"""Run all tests for this plugin."""
# If we are not running locally, start the docker containers so we don't have to for each test
if not is_truthy(context.{{cookiecutter.plugin_name}}.local):
Expand All @@ -679,7 +693,8 @@ def tests(context, failfast=False):
pylint(context)
print("Running mkdocs...")
build_and_check_docs(context)
print("Running unit tests...")
unittest(context, failfast=failfast)
if not lint_only:
print("Running unit tests...")
unittest(context, failfast=failfast, keepdb=keepdb)
print("All tests have passed!")
unittest_coverage(context)
Loading