Skip to content

Commit

Permalink
Fixed issue with dynamic groups not being called in 2.3.0. (#798)
Browse files Browse the repository at this point in the history
* Fixed issue with dynamic groups not being called in 2.3.0.
* Pylint updates, add experimental conditional re-cache dynamic groups
* Fixed issue where compliance amongst other fields were not being updated when Django 4.2 was installed.
  • Loading branch information
itdependsnetworks authored Sep 3, 2024
1 parent 2e39e7d commit feac7f2
Show file tree
Hide file tree
Showing 18 changed files with 2,170 additions and 1,895 deletions.
1 change: 0 additions & 1 deletion changes/786.housekeeping

This file was deleted.

1 change: 0 additions & 1 deletion changes/788.housekeeping

This file was deleted.

28 changes: 23 additions & 5 deletions docs/admin/release_notes/version_2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@
- Hide Compliance tab if no compliance result exists.


### Added

- [#1501](https://github.com/nautobot/nautobot-app-golden-config/issues/1501) - Add Support for XML Compliance
## v2.1.2 2024-08

### Fixed

- [#723](https://github.com/nautobot/nautobot-app-golden-config/issues/723) - Hide compliance tab in device view if no compliance results exist.
- [#792](https://github.com/nautobot/nautobot-app-golden-config/issues/792) - Fixed issue with dynamic groups not being called in 2.3.0.
- [#800](https://github.com/nautobot/nautobot-app-golden-config/issues/800) - Fixed issue where compliance amongst other fields were not being updated when Django 4.2 was installed.

### Changed

- [#792](https://github.com/nautobot/nautobot-app-golden-config/issues/792) - Added an experimental `_manual_dynamic_group_mgmt` config to collect feedback on appropriate methodology, use at your own risk!!.

## v2.1.1
### Housekeeping

- [#786](https://github.com/nautobot/nautobot-app-golden-config/issues/786) - Fixed incorrect test data setup for `test_tags_filter()` test for `ConfigPlanFilterTestCase`.
- [#788](https://github.com/nautobot/nautobot-app-golden-config/issues/788) - Rebaked from the cookie `nautobot-app-v2.3.0`.

## v2.1.1 - 2024-07

### Fixed

Expand All @@ -33,3 +40,14 @@
### Housekeeping

- [#769](https://github.com/nautobot/nautobot-app-golden-config/issues/769) - Added view tests for ConfigComplianceUIViewSet.


## v2.1.0 - 2024-05

### Added

- [#708](https://github.com/nautobot/nautobot-app-golden-config/issues/708) - Add Support for XML Compliance

### Fixed

- [#723](https://github.com/nautobot/nautobot-app-golden-config/issues/723) - Hide compliance tab in device view if no compliance results exist.
9 changes: 5 additions & 4 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mkdocs==1.5.2
mkdocs-material==9.2.4
mkdocs==1.6.0
mkdocs-material==9.5.32
markdown-version-annotations==1.0.1
mkdocstrings-python==1.5.2
mkdocstrings==0.22.0
griffe==1.1.1
mkdocstrings-python==1.10.8
mkdocstrings==0.25.2
4 changes: 2 additions & 2 deletions docs/user/app_getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ Using the previous example, everything will use the napalm dispatcher, this is i
}
```

Using the previous example, everything will use the napalm dispatcher **except** forinet, which would use netmiko.
Using the previous example, everything will use the napalm dispatcher **except** fortinet, which would use netmiko.

```json
# DEFAULT_FRAMEWORK
Expand All @@ -321,7 +321,7 @@ Using the previous example, everything will use the napalm dispatcher **except**
}
```

Using the previous example, everything will use the napalm dispatcher **except** forinet **and** when using the `get_config` method for `arista_eos` and `cisco_nxos`, use netmiko.
Using the previous example, everything will use the napalm dispatcher **except** fortinet **and** when using the `get_config` method for `arista_eos` and `cisco_nxos`, use netmiko.

As you can see, you now have the flexibility to control which network_driver will use which framework for every method, as each constance setting is sanely named to match the method name (e.g. `GET_CONFIG_FRAMEWORK` maps the `get_config` method). Additionally, if the current `network_driver` and associated `network_driver_mappings` is not sufficient as is, you can extend the [NETWORK DRIVER](https://docs.nautobot.com/projects/core/en/stable/user-guide/administration/configuration/optional-settings/#network_drivers) settings as well.

Expand Down
3 changes: 3 additions & 0 deletions nautobot_golden_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class GoldenConfig(NautobotAppConfig):
"per_feature_width": 13,
"per_feature_height": 4,
"get_custom_compliance": None,
# This is an experimental and undocumented setting that will change in the future!!
# Use at your own risk!!!!!
"_manual_dynamic_group_mgmt": False,
"jinja_env": {
"undefined": "jinja2.StrictUndefined",
"trim_blocks": True,
Expand Down
2 changes: 1 addition & 1 deletion nautobot_golden_config/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class Meta:
fields = "__all__"


class ConfigToPushSerializer(DeviceSerializer):
class ConfigToPushSerializer(DeviceSerializer): # pylint: disable=nb-sub-class-name
"""Serializer for ConfigToPush view."""

config = serializers.SerializerMethodField()
Expand Down
29 changes: 9 additions & 20 deletions nautobot_golden_config/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,7 @@ class Meta:

model = models.GoldenConfig
distinct = True
fields = [
"id",
"backup_config",
"backup_last_attempt_date",
"backup_last_success_date",
"intended_config",
"intended_last_attempt_date",
"intended_last_success_date",
"compliance_config",
"compliance_last_attempt_date",
"compliance_last_success_date",
]
fields = "__all__"


class ConfigComplianceFilterSet(GoldenConfigFilterSet): # pylint: disable=too-many-ancestors
Expand All @@ -156,7 +145,7 @@ class Meta:
"""Meta class attributes for ConfigComplianceFilter."""

model = models.ConfigCompliance
fields = ["id", "compliance", "actual", "intended", "missing", "extra", "ordered", "compliance_int", "rule"]
fields = "__all__"


class ComplianceFeatureFilterSet(NautobotFilterSet):
Expand All @@ -175,7 +164,7 @@ class Meta:
"""Boilerplate filter Meta data for compliance feature."""

model = models.ComplianceFeature
fields = ["id", "name", "slug", "description"]
fields = "__all__"


class ComplianceRuleFilterSet(NautobotFilterSet):
Expand All @@ -200,7 +189,7 @@ class Meta:
"""Boilerplate filter Meta data for compliance rule."""

model = models.ComplianceRule
fields = ["feature", "id"]
fields = "__all__"


class ConfigRemoveFilterSet(NautobotFilterSet):
Expand All @@ -225,7 +214,7 @@ class Meta:
"""Boilerplate filter Meta data for Config Remove."""

model = models.ConfigRemove
fields = ["id", "name"]
fields = "__all__"


class ConfigReplaceFilterSet(NautobotFilterSet):
Expand All @@ -250,7 +239,7 @@ class Meta:
"""Boilerplate filter Meta data for Config Replace."""

model = models.ConfigReplace
fields = ["id", "name"]
fields = "__all__"


class GoldenConfigSettingFilterSet(NautobotFilterSet):
Expand All @@ -260,7 +249,7 @@ class Meta:
"""Boilerplate filter Meta data for Config Remove."""

model = models.GoldenConfigSetting
fields = ["id", "name", "slug", "weight", "backup_repository", "intended_repository", "jinja_repository"]
fields = "__all__"


class RemediationSettingFilterSet(NautobotFilterSet):
Expand Down Expand Up @@ -293,7 +282,7 @@ class Meta:
"""Boilerplate filter Meta data for Remediation Setting."""

model = models.RemediationSetting
fields = ["id", "remediation_type"]
fields = "__all__"


class ConfigPlanFilterSet(NautobotFilterSet):
Expand Down Expand Up @@ -433,4 +422,4 @@ class Meta:
"""Boilerplate filter Meta data for Config Plan."""

model = models.ConfigPlan
fields = ["id", "created", "change_control_id", "plan_type", "tags"]
fields = "__all__"
59 changes: 7 additions & 52 deletions nautobot_golden_config/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# ConfigCompliance


class DeviceRelatedFilterForm(NautobotFilterForm):
class DeviceRelatedFilterForm(NautobotFilterForm): # pylint: disable=nb-no-model-found
"""Base FilterForm for below FilterForms."""

tenant_group_id = forms.DynamicModelMultipleChoiceField(
Expand Down Expand Up @@ -95,18 +95,6 @@ class DeviceRelatedFilterForm(NautobotFilterForm):
)


class GoldenConfigForm(NautobotModelForm):
"""Filter Form for ComplianceFeature instances."""

slug = forms.SlugField() # TODO: 2.1: Change from slugs once django-pivot is figured out

class Meta:
"""Boilerplate form Meta data for compliance feature."""

model = models.ComplianceFeature
fields = ("name", "slug", "description", "tags")


class GoldenConfigFilterForm(DeviceRelatedFilterForm):
"""Filter Form for GoldenConfig."""

Expand Down Expand Up @@ -144,16 +132,6 @@ class Meta:
nullable_fields = []


class ConfigComplianceForm(NautobotModelForm):
"""Filter Form for ConfigCompliance instances."""

class Meta:
"""Boilerplate form Meta data for compliance feature."""

model = models.ConfigCompliance
fields = []


class ConfigComplianceFilterForm(DeviceRelatedFilterForm):
"""Filter Form for ConfigCompliance instances."""

Expand Down Expand Up @@ -204,17 +182,7 @@ class Meta:
"""Boilerplate form Meta data for compliance rule."""

model = models.ComplianceRule
fields = (
"platform",
"feature",
"description",
"config_ordered",
"config_type",
"match_config",
"custom_compliance",
"config_remediation",
"tags",
)
fields = "__all__"


class ComplianceRuleFilterForm(NautobotFilterForm):
Expand Down Expand Up @@ -263,7 +231,7 @@ class Meta:
"""Boilerplate form Meta data for compliance feature."""

model = models.ComplianceFeature
fields = ("name", "slug", "description", "tags")
fields = "__all__"


class ComplianceFeatureFilterForm(NautobotFilterForm):
Expand Down Expand Up @@ -300,13 +268,7 @@ class Meta:
"""Boilerplate form Meta data for removal feature."""

model = models.ConfigRemove
fields = (
"platform",
"name",
"description",
"regex",
"tags",
)
fields = "__all__"


class ConfigRemoveFilterForm(NautobotFilterForm):
Expand Down Expand Up @@ -347,14 +309,7 @@ class Meta:
"""Boilerplate form Meta data for removal feature."""

model = models.ConfigReplace
fields = (
"platform",
"name",
"description",
"regex",
"replace",
"tags",
)
fields = "__all__"


class ConfigReplaceFilterForm(NautobotFilterForm):
Expand Down Expand Up @@ -548,7 +503,7 @@ class Meta:
fields = "__all__"


class ConfigPlanUpdateForm(NautobotModelForm):
class ConfigPlanUpdateForm(NautobotModelForm): # pylint: disable=nb-sub-class-name
"""Form for ConfigPlan instances."""

status = forms.DynamicModelChoiceField(
Expand All @@ -563,7 +518,7 @@ class Meta:
"""Boilerplate form Meta data for ConfigPlan."""

model = models.ConfigPlan
fields = (
fields = ( # pylint: disable=nb-use-fields-all
"change_control_id",
"change_control_url",
"status",
Expand Down
14 changes: 13 additions & 1 deletion nautobot_golden_config/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@
generate_config_set_from_manual,
)
from nautobot_golden_config.utilities.git import GitRepo
from nautobot_golden_config.utilities.helper import get_device_to_settings_map, get_job_filter
from nautobot_golden_config.utilities.helper import (
get_device_to_settings_map,
get_job_filter,
update_dynamic_groups_cache,
)

InventoryPluginRegister.register("nautobot-inventory", NautobotORMInventory)

Expand Down Expand Up @@ -478,6 +482,8 @@ def _generate_config_plan_from_manual(self):

def run(self, **data):
"""Run config plan generation process."""
self.logger.debug("Updating Dynamic Group Cache.")
update_dynamic_groups_cache()
self.logger.debug("Starting config plan generation job.")
self._validate_inputs(data)
try:
Expand Down Expand Up @@ -518,6 +524,8 @@ def __init__(self, *args, **kwargs):

def run(self, **data): # pylint: disable=arguments-differ
"""Run config plan deployment process."""
self.logger.debug("Updating Dynamic Group Cache.")
update_dynamic_groups_cache()
self.logger.debug("Starting config plan deployment job.")
self.data = data
config_deployment(self)
Expand All @@ -539,6 +547,8 @@ def __init__(self, *args, **kwargs):

def receive_job_button(self, obj):
"""Run config plan deployment process."""
self.logger.debug("Updating Dynamic Group Cache.")
update_dynamic_groups_cache()
self.logger.debug("Starting config plan deployment job.")
self.data = {"debug": False, "config_plan": ConfigPlan.objects.filter(id=obj.id)}
config_deployment(self)
Expand All @@ -556,6 +566,8 @@ class Meta:

def run(self):
"""Run GoldenConfig sync."""
self.logger.debug("Updating Dynamic Group Cache.")
update_dynamic_groups_cache()
self.logger.debug("Starting sync of GoldenConfig with DynamicGroup membership.")
gc_dynamic_group_device_pks = GoldenConfig.get_dynamic_group_device_pks()
gc_device_pks = GoldenConfig.get_golden_config_device_ids()
Expand Down
7 changes: 7 additions & 0 deletions nautobot_golden_config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,13 @@ def save(self, *args, **kwargs):
self.remediation_on_save()
self.full_clean()

# This accounts for django 4.2 `Setting update_fields in Model.save() may now be required` change
# in behavior
if kwargs.get("update_fields"):
kwargs["update_fields"].update(
{"compliance", "compliance_int", "ordered", "missing", "extra", "remediation"}
)

super().save(*args, **kwargs)


Expand Down
6 changes: 3 additions & 3 deletions nautobot_golden_config/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class Meta(BaseTable.Meta):
# All other fields (ConfigCompliance names) are constructed dynamically at instantiation time - see views.py


class ConfigComplianceGlobalFeatureTable(BaseTable):
class ConfigComplianceGlobalFeatureTable(BaseTable): # pylint: disable=nb-sub-class-name
"""Table for feature compliance report."""

name = Column(accessor="rule__feature__slug", verbose_name="Feature")
Expand All @@ -213,7 +213,7 @@ class Meta(BaseTable.Meta):
]


class ConfigComplianceDeleteTable(BaseTable):
class ConfigComplianceDeleteTable(BaseTable): # pylint: disable=nb-sub-class-name
"""Table for device compliance report."""

feature = Column(accessor="rule__feature__name", verbose_name="Feature")
Expand All @@ -226,7 +226,7 @@ class Meta(BaseTable.Meta):
fields = ("device", "feature")


class DeleteGoldenConfigTable(BaseTable):
class DeleteGoldenConfigTable(BaseTable): # pylint: disable=nb-sub-class-name
"""
Table used in bulk delete confirmation.
Expand Down
Loading

0 comments on commit feac7f2

Please sign in to comment.