Skip to content
Open
Show file tree
Hide file tree
Changes from 10 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 .github/workflows/upstream_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
app_branch: "main"
- nautobot_branch: "ltm-2.4"
app_branch: "ltm-2.4"
# - nautobot_branch: "next-4.0"
# app_branch: "next-4.0"
# - nautobot_branch: "next-4.0"
# app_branch: "next-4.0"
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_GOLDEN_CONFIG"
Expand Down
1 change: 1 addition & 0 deletions changes/984.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added per-`GoldenConfigSetting` enable flags (`enable_backup`, `enable_intended`, `enable_compliance`, `enable_plan`, `enable_deploy`) so each feature can be toggled on a per-Setting basis. The model fields default to the existing plugin-level `enable_*` settings to preserve backwards compatibility.
1 change: 1 addition & 0 deletions changes/984.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Golden Config jobs now route each device through its highest-weighted `GoldenConfigSetting` and honor that Setting's per-feature `enable_*` flag. Devices skipped because the winning Setting has the feature disabled log an `E3038` warning naming the Setting and weight; jobs with no eligible devices log a single `E3039` warning per feature. All in-scope Settings' repositories are still synced (so read-only consumers stay current), but only enabled Settings' repos are committed and pushed.
2 changes: 1 addition & 1 deletion development/development.env
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ ENABLE_BACKUP=True
ENABLE_SOTAGG=True
ENABLE_POSTPROCESSING=True
ENABLE_PLAN=True
ENABLE_DEPLOY=True
ENABLE_DEPLOY=False
Comment thread
jeffkala marked this conversation as resolved.
Outdated
ALLOWED_OS=all
21 changes: 21 additions & 0 deletions docs/user/app_use_cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,31 @@ To update existing settings click on one of the `Settings` name.
|Jinja Path|A Jinja template which defines the path (within the repository) and name of the Jinja template file. e.g. `{{obj.platform.network_driver}}/{{obj.role.name}}/main.j2`|
|Dynamic Group|The scope of devices on which Golden Config's jobs can operate. |
|GraphQL Query|A query that is evaluated and used to render the config. The query must start with `query ($device_id: ID!)`.|
|Enable Backup|Whether the Backup Configurations job runs for devices owned by this Setting. Defaults to `True`. When `False`, devices owned by this Setting are skipped by the Backup job and an `E3038` warning is logged.|
|Enable Intended|Whether the Generate Intended Configurations job runs for devices owned by this Setting. Defaults to `True`. The Setting cannot be saved with this enabled unless `Sot agg query`, `Jinja repository`, `Jinja Template Path`, `Intended repository`, and `Intended Path Template` are all set.|
|Enable Compliance|Whether the Perform Configuration Compliance job runs for devices owned by this Setting. Defaults to `True`.|
|Enable Config Plan|Whether Config Plan generation is permitted for devices owned by this Setting. Defaults to `True`.|
|Enable Deploy|Whether Deploy Config Plans is permitted for devices owned by this Setting. Defaults to `True`.|
Comment thread
jeffkala marked this conversation as resolved.
Outdated

!!! note
Each of these will be further detailed in their respective sections.

#### Feature-Enable Resolution Across Multiple Settings

A single device may match the Dynamic Group criteria for more than one Golden Config Setting. To ensure each device is assigned to only one setting when it belongs to multiple Dynamic Groups, Golden Config applies the following rules:

* **Highest-weighted Setting wins per device.** Each device is calculated independently to apply the Golden Config Setting with the highest `weight`. A device may be a member of multiple Dynamic Groups (via Golden Config setting), but the highest weighted setting is used. If two Settings share the same weight, the Setting with the lower-sorted `name` wins, it is up to the operator to ensure if a device is part of multiple Golden Config settings that the settings `weights` are different.
* **No per-feature fallback.** All features; backup, intended, deploys, etc. are **only** used from the winning setting as described above.
* **Skip logging.** When a job runs against a device whose winning Setting has the corresponding feature disabled, an `E3038` warning is emitted naming the winning Setting and its weight so operators can locate the responsible record.

#### All-In-One Jobs and Disabled Features

The two "Execute All Golden Configuration Jobs" jobs (single-device and multi-device) iterate through Backup, Intended, and Compliance in order. For each play they run only the subset of devices whose winning Setting has the corresponding feature enabled:

* If a play has zero eligible devices the play is skipped with an `E3039` warning and the next play continues.
* The job does not abort the remaining plays when one feature is disabled — partial execution is intentional so operators can disable a feature on a Setting without losing the other features for that Setting's devices.
* If `fail_job_on_task_failure=True` is checked on the form, the job still fails at the end when any executed play raised an error, but skipped (disabled) plays do not count as failures.
Comment thread
jeffkala marked this conversation as resolved.

#### Dynamic Group

!!! note
Expand Down
67 changes: 29 additions & 38 deletions nautobot_golden_config/datasources.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
ConfigReplace,
RemediationSetting,
)
from nautobot_golden_config.utilities.constant import ENABLE_BACKUP, ENABLE_COMPLIANCE, ENABLE_INTENDED
from nautobot_golden_config.utilities.helper import get_error_message


Expand Down Expand Up @@ -231,43 +230,35 @@ def update_git_gc_properties(golden_config_path, job_result, gc_config_item): #
continue


datasource_contents = []
if ENABLE_INTENDED or ENABLE_COMPLIANCE:
datasource_contents.append(
(
"extras.gitrepository",
DatasourceContent(
name="intended configs",
content_identifier="nautobot_golden_config.intendedconfigs",
icon="mdi-file-document-outline",
callback=refresh_git_intended,
),
)
)
if ENABLE_INTENDED:
datasource_contents.append(
(
"extras.gitrepository",
DatasourceContent(
name="jinja templates",
content_identifier="nautobot_golden_config.jinjatemplate",
icon="mdi-text-box-check-outline",
callback=refresh_git_jinja,
),
)
)
if ENABLE_BACKUP or ENABLE_COMPLIANCE:
datasource_contents.append(
(
"extras.gitrepository",
DatasourceContent(
name="backup configs",
content_identifier="nautobot_golden_config.backupconfigs",
icon="mdi-file-code",
callback=refresh_git_backup,
),
)
)
datasource_contents = [
(
"extras.gitrepository",
DatasourceContent(
name="intended configs",
content_identifier="nautobot_golden_config.intendedconfigs",
icon="mdi-file-document-outline",
callback=refresh_git_intended,
),
),
(
"extras.gitrepository",
DatasourceContent(
name="jinja templates",
content_identifier="nautobot_golden_config.jinjatemplate",
icon="mdi-text-box-check-outline",
callback=refresh_git_jinja,
),
),
(
"extras.gitrepository",
DatasourceContent(
name="backup configs",
content_identifier="nautobot_golden_config.backupconfigs",
icon="mdi-file-code",
callback=refresh_git_backup,
),
),
]

datasource_contents.append(
(
Expand Down
10 changes: 9 additions & 1 deletion nautobot_golden_config/details.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,15 @@ def hyperlinked_field_with_icon(url, title, icon_class="mdi mdi-text-box-check-o
label="General Settings",
section=ui.SectionChoices.LEFT_HALF,
weight=100,
fields=("weight", "description"),
fields=(
"weight",
"description",
"enable_backup",
"enable_intended",
"enable_compliance",
"enable_plan",
"enable_deploy",
),
),
ui.KeyValueTablePanel(
section=ui.SectionChoices.LEFT_HALF,
Expand Down
10 changes: 10 additions & 0 deletions nautobot_golden_config/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,11 @@ class GoldenConfigSettingFilterForm(NautobotFilterForm):
queryset=GitRepository.objects.filter(provided_contents__contains="nautobot_golden_config.jinjatemplate"),
required=False,
)
enable_backup = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_intended = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_compliance = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_plan = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_deploy = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())


class GoldenConfigSettingBulkEditForm(NautobotBulkEditForm):
Expand All @@ -447,6 +452,11 @@ class GoldenConfigSettingBulkEditForm(NautobotBulkEditForm):
pk = django_forms.ModelMultipleChoiceField(
queryset=models.GoldenConfigSetting.objects.all(), widget=django_forms.MultipleHiddenInput
)
enable_backup = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_intended = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_compliance = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_plan = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())
enable_deploy = django_forms.NullBooleanField(required=False, widget=forms.BulkEditNullBooleanSelect())

class Meta:
"""Boilerplate form Meta data for GoldenConfigSetting."""
Expand Down
Loading
Loading