Skip to content

Commit

Permalink
Merge pull request #877 from nautobot/release/v2.3.0
Browse files Browse the repository at this point in the history
Release v2.3.0
  • Loading branch information
gsnider2195 authored Feb 4, 2025
2 parents 8c30848 + 94187e5 commit f072552
Show file tree
Hide file tree
Showing 29 changed files with 937 additions and 412 deletions.
4 changes: 2 additions & 2 deletions .cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"_drift_manager": {
"template": "https://github.com/nautobot/cookiecutter-nautobot-app.git",
"template_dir": "nautobot-app",
"template_ref": "refs/tags/nautobot-app-v2.4.0",
"template_ref": "refs/tags/nautobot-app-v2.4.1",
"cookie_dir": "",
"branch_prefix": "drift-manager",
"pull_request_strategy": "create",
Expand All @@ -30,7 +30,7 @@
"poetry"
],
"draft": false,
"baked_commit_ref": "69ab82f79f346d3e9e9cf62432bdd6d6b9c53e3f"
"baked_commit_ref": "baf8508b44f904c4c60e5d72dc19abc323508d8c"
}
}
}
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Linting: ruff format"
run: "poetry run invoke ruff --action format"
ruff-lint:
Expand All @@ -37,6 +39,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Linting: ruff"
run: "poetry run invoke ruff --action lint"
check-docs-build:
Expand All @@ -48,6 +52,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Check Docs Build"
run: "poetry run invoke build-and-check-docs"
poetry:
Expand All @@ -59,6 +65,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Checking: poetry lock file"
run: "poetry run invoke lock --check"
yamllint:
Expand All @@ -70,6 +78,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Linting: yamllint"
run: "poetry run invoke yamllint"
check-in-docker:
Expand All @@ -92,6 +102,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Constrain Nautobot version and regenerate lock file"
env:
INVOKE_NAUTOBOT_GOLDEN_CONFIG_LOCAL: "true"
Expand Down Expand Up @@ -147,6 +159,8 @@ jobs:
uses: "actions/checkout@v4"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Constrain Nautobot version and regenerate lock file"
env:
INVOKE_NAUTOBOT_GOLDEN_CONFIG_LOCAL: "true"
Expand Down Expand Up @@ -188,6 +202,8 @@ jobs:
fetch-depth: "0"
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v6"
with:
poetry-version: "1.8.5"
- name: "Check for changelog entry"
run: |
git fetch --no-tags origin +refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Apache Software License 2.0

Copyright (c) 2024, Network to Code, LLC
Copyright (c) 2025, 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.
Expand Down
6 changes: 4 additions & 2 deletions development/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ services:
volumes:
- "./nautobot_config.py:/opt/nautobot/nautobot_config.py"
- "../:/source"
# To expose postgres or redis to the host uncomment the following
# postgres:
# To expose postgres (5432), myql (3306) on db service or redis (6379) to the host uncomment the
# following. Ensure to match the 2 idented spaces which to have the service nested under services.
# db:
# ports:
# - "5432:5432"
# - "3306:3306"
# redis:
# ports:
# - "6379:6379"
7 changes: 7 additions & 0 deletions development/docker-compose.mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ services:
- "development.env"
- "creds.env"
- "development_mysql.env"
beat:
environment:
- "NAUTOBOT_DB_ENGINE=django.db.backends.mysql"
env_file:
- "development.env"
- "creds.env"
- "development_mysql.env"
db:
image: "mysql:8"
command:
Expand Down
14 changes: 3 additions & 11 deletions development/nautobot_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys

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
from nautobot.core.settings_funcs import is_truthy

#
# Debug
Expand Down Expand Up @@ -65,16 +65,8 @@
#

# 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",
},
}
}
# Inherited from nautobot.core.settings
# CACHES = {....}

#
# Celery settings are not defined here because they can be overloaded with
Expand Down
3 changes: 2 additions & 1 deletion docs/admin/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ echo nautobot-golden-config >> local_requirements.txt
Once installed, the app needs to be enabled in your Nautobot configuration. The following block of code below shows the additional configuration required to be added to your `nautobot_config.py` file:

- Append `"nautobot_golden_config"` to the `PLUGINS` list, and `"nautobot_plugin_nornir"` if it was not already there (more info [here](https://docs.nautobot.com/projects/plugin-nornir/en/latest/)).
- Append the `"nautobot_golden_config"` dictionary to the `PLUGINS_CONFIG` dictionary, and `"nautobot_plugin_nornir"` if it was not already there.
- Append the `"nautobot_golden_config"` dictionary to the `PLUGINS_CONFIG` dictionary as shown the **sample** below with your appropriate configs.
- Append the `"nautobot_plugin_nornir"` dictionary to the `PLUGINS_CONFIG` dictionary as shown the **sample** below with your appropriate configs (Note: this may already be in your configs).

```python
PLUGINS = ["nautobot_plugin_nornir", "nautobot_golden_config"]
Expand Down
28 changes: 28 additions & 0 deletions docs/admin/release_notes/version_2.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# v2.3 Release Notes

This document describes all new features and changes in the release. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Release Overview

- Added a `branch` parameter to the "Generate Intended Config" view.
- Fixed some bugs in the UI for device compliance and config compliance views.

## [v2.3.0 (2025-02-03)](https://github.com/nautobot/nautobot-app-golden-config/releases/tag/v2.3.0)

### Added

- [#828](https://github.com/nautobot/nautobot-app-golden-config/issues/828) - Added `branch` parameter to generate intended config view.

### Changed

- [#860](https://github.com/nautobot/nautobot-app-golden-config/issues/860) - Added a scroll bar and maximum height to the "Configuration" text boxes on the device configuration compliance tabs.

### Fixed

- [#812](https://github.com/nautobot/nautobot-app-golden-config/issues/812) - Fixed a bug in the config compliance list view when customizing the table columns.

### Housekeeping

- Rebaked from the cookie `nautobot-app-v2.4.1`.
- [#873](https://github.com/nautobot/nautobot-app-golden-config/issues/873) - Fixed failing tests in Nautobot v2.3.11 and higher.
- [#857](https://github.com/nautobot/nautobot-app-golden-config/issues/857) - Fixed installation docs to make clear that configurations are sample configurations.
Binary file modified docs/images/generate-intended-config-ui-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/generate-intended-config-ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 21 additions & 11 deletions docs/user/app_feature_intended.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,36 @@ In these examples, `/services.j2`, `/ntp.j2`, etc. could contain the actual Jinj

### Developing Intended Configuration Templates

To help developers create the Jinja2 templates for generating a device's intended configuration, the app provides a REST API at `/api/plugins/golden-config/generate-intended-config/` and a simple web UI at `/plugins/golden-config/generate-intended-config/`. The REST API accepts a query parameter for `device_id` and returns the rendered configuration for the specified device using the templates from the device's golden config `jinja_repository` Git repository. This feature allows developers to test their configuration templates without running a full "intended configuration" job.
To generate a device's intended configuration without running a full "intended configuration" job, Golden Config provides a simple web UI at `/plugins/golden-config/generate-intended-config/` and a REST API at `/api/plugins/golden-config/generate-intended-config/`.

Here's an example of how to request the rendered configuration for a device using the REST API:
Note that this tool is only intended to render Jinja2 templates and does not apply any [configuration post-processing](./app_feature_config_postprocessing.md).

```no-highlight
curl -s -X GET \
-H "Accept: application/json" \
http://nautobot/api/plugins/golden-config/generate-intended-config/?device_id=231b8765-054d-4abe-bdbf-cd60e049cd8d
```
Using this tool to render a configuration will automatically retrieve the latest commit from the Jinja2 templates Git repository before rendering the template.

#### Web UI

The returned response will contain the rendered configuration for the specified device, the GraphQL data that was used, and if applicable, a diff of the most recent intended config that was generated by the **Intended Configuration** job. The web UI provides a simple form to interact with this REST API. You can access the web UI by clicking on "Generate Intended Config" in the "Tools" section of the Golden Config navigation menu.
The web UI provides a user-friendly form to interact with the rendering process. You can access the web UI by clicking on "Generate Intended Config" in the "Tools" section of the Golden Config navigation menu.

For more advanced use cases, the REST API and web UI also accept a `graphql_query_id` parameter to specify a custom GraphQL query to use when rendering the configuration. If a `graphql_query_id` is not provided, the default query configured in the Device's Golden Config settings will be used.
For more advanced use cases, the form accepts an optional "GraphQL Query" to specify a custom GraphQL query to use when rendering the configuration. If a "GraphQL Query" is not provided, the default query configured in the Device's Golden Config settings will be used.

Starting in Nautobot v2.4.2, this UI also allows you to supply a "Git Repository Branch" to specify the branch of the Jinja2 templates Git repository to use when rendering the configuration. If the branch is not provided, the configured branch of the Golden Config Setting's Jinja template Git repository will be used.

![Intended Configuration Web UI](../images/generate-intended-config-ui.png#only-light)
![Intended Configuration Web UI](../images/generate-intended-config-ui-dark.png#only-dark)

Calling this API endpoint automatically performs a `git pull`, retrieving the latest commit from the Jinja2 templates Git repository before rendering the template.
#### REST API

The REST API accepts query parameters for `device_id`, an optional `graphql_query_id` and an optional `branch` if running Nautobot v2.4.2 or later.

Here's an example of how to request the rendered configuration for a device using the REST API:

```no-highlight
curl -s -X GET \
-H "Accept: application/json" \
http://nautobot/api/plugins/golden-config/generate-intended-config/?device_id=231b8765-054d-4abe-bdbf-cd60e049cd8d
```

Note that this API is only intended to render Jinja2 templates and does not apply any [configuration post-processing](./app_feature_config_postprocessing.md).
The returned response will contain the rendered configuration for the specified device, the GraphQL data that was used, and if applicable, a diff of the most recent intended config that was generated by the **Intended Configuration** job.

## Adding Jinja2 Filters to the Environment.

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ nav:
- Extending the App: "dev/extending.md"
- Contributing to the App: "dev/contributing.md"
- Development Environment: "dev/dev_environment.md"
- Release Checklist: "dev/release_checklist.md"
- Architecture Decision Records: "dev/arch_decision.md"
- Code Reference:
- "dev/code_reference/index.md"
Expand Down
38 changes: 33 additions & 5 deletions nautobot_golden_config/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""REST API serializer capabilities for graphql app."""
"""API serializers for nautobot_golden_config."""

# pylint: disable=too-many-ancestors
from nautobot.core.api.serializers import NautobotModelSerializer
from nautobot.apps.api import NautobotModelSerializer, TaggedModelSerializerMixin
from nautobot.apps.utils import GitRepo
from nautobot.dcim.api.serializers import DeviceSerializer
from nautobot.dcim.models import Device
from nautobot.extras.api.mixins import TaggedModelSerializerMixin
from nautobot.extras.api.serializers import GitRepositorySerializer
from nautobot.extras.datasources.git import ensure_git_repository, get_repo_from_url_to_path_and_from_branch
from nautobot.extras.models import GitRepository
from rest_framework import serializers

from nautobot_golden_config import models
Expand All @@ -18,14 +21,17 @@ class GraphQLSerializer(serializers.Serializer): # pylint: disable=abstract-met


class ComplianceFeatureSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
"""Serializer for ComplianceFeature object."""
"""ComplianceFeature Serializer."""

class Meta:
"""Set Meta Data for ComplianceFeature, will serialize all fields."""
"""Meta attributes."""

model = models.ComplianceFeature
fields = "__all__"

# Option for disabling write for certain fields:
# read_only_fields = []


class ComplianceRuleSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
"""Serializer for ComplianceRule object."""
Expand Down Expand Up @@ -134,3 +140,25 @@ class GenerateIntendedConfigSerializer(serializers.Serializer): # pylint: disab
graphql_data = serializers.JSONField(read_only=True)
diff = serializers.CharField(read_only=True)
diff_lines = serializers.ListField(read_only=True, child=serializers.CharField())


class GitRepositoryWithBranchesSerializer(GitRepositorySerializer): # pylint: disable=nb-sub-class-name
"""Serializer for extras.GitRepository with remote branches field."""

remote_branches = serializers.SerializerMethodField()

def get_remote_branches(self, obj):
"""Return a list of branches for the GitRepository."""
ensure_git_repository(obj)
from_url, to_path, _ = get_repo_from_url_to_path_and_from_branch(obj)
repo_helper = GitRepo(to_path, from_url)
repo_helper.repo.remotes.origin.fetch()
return [
ref.name[7:] # removeprefix("origin/")
for ref in repo_helper.repo.remotes.origin.refs
if ref.name != "origin/HEAD"
]

class Meta: # noqa: D106 # undocumented-public-nested-class
model = GitRepository
fields = "__all__"
10 changes: 8 additions & 2 deletions nautobot_golden_config/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""API for Custom Jobs ."""
"""Django API urlpatterns declaration for nautobot_golden_config app."""

from django.urls import path
from nautobot.core.api.routers import OrderedDefaultRouter
from nautobot.apps.api import OrderedDefaultRouter

from nautobot_golden_config.api import views

router = OrderedDefaultRouter()
# add the name of your api endpoint, usually hyphenated model name in plural, e.g. "my-model-classes"
router.APIRootView = views.GoldenConfigRootView
router.register("compliance-feature", views.ComplianceFeatureViewSet)
router.register("compliance-rule", views.ComplianceRuleViewSet)
Expand All @@ -29,5 +30,10 @@
views.GenerateIntendedConfigView.as_view(),
name="generate_intended_config",
),
path(
"git-repository-branches/<pk>/",
views.GitRepositoryBranchesView.as_view(),
name="git_repository_branches",
),
]
urlpatterns += router.urls
Loading

0 comments on commit f072552

Please sign in to comment.