Skip to content

Models

nautobot_golden_config.models

Django Models for tracking the configuration compliance per feature and device.

ComplianceFeature

Bases: PrimaryModel

ComplianceFeature details.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class ComplianceFeature(PrimaryModel):  # pylint: disable=too-many-ancestors
    """ComplianceFeature details."""

    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True)
    description = models.CharField(max_length=200, blank=True)

    csv_headers = ["name", "slug", "description"]

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (self.name, self.slug, self.description)

    class Meta:
        """Meta information for ComplianceFeature model."""

        ordering = ("slug",)

    def __str__(self):
        """Return a sane string representation of the instance."""
        return self.slug

    def get_absolute_url(self):
        """Absolute url for the ComplianceFeature instance."""
        return reverse("plugins:nautobot_golden_config:compliancefeature", args=[self.pk])

Meta

Meta information for ComplianceFeature model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Meta information for ComplianceFeature model."""

    ordering = ("slug",)

__str__()

Return a sane string representation of the instance.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """Return a sane string representation of the instance."""
    return self.slug

get_absolute_url()

Absolute url for the ComplianceFeature instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):
    """Absolute url for the ComplianceFeature instance."""
    return reverse("plugins:nautobot_golden_config:compliancefeature", args=[self.pk])

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (self.name, self.slug, self.description)

ComplianceRule

Bases: PrimaryModel

ComplianceRule details.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class ComplianceRule(PrimaryModel):  # pylint: disable=too-many-ancestors
    """ComplianceRule details."""

    feature = models.ForeignKey(to="ComplianceFeature", on_delete=models.CASCADE, blank=False, related_name="feature")

    platform = models.ForeignKey(
        to="dcim.Platform",
        on_delete=models.CASCADE,
        related_name="compliance_rules",
        null=False,
        blank=False,
    )
    description = models.CharField(
        max_length=200,
        blank=True,
    )
    config_ordered = models.BooleanField(
        null=False,
        blank=False,
        verbose_name="Configured Ordered",
        help_text="Whether or not the configuration order matters, such as in ACLs.",
    )
    match_config = models.TextField(
        null=True,
        blank=True,
        verbose_name="Config to Match",
        help_text="The config to match that is matched based on the parent most configuration. e.g. `router bgp` or `ntp`.",
    )
    config_type = models.CharField(
        max_length=20,
        default=ComplianceRuleTypeChoice.TYPE_CLI,
        choices=ComplianceRuleTypeChoice,
        help_text="Whether the config is in cli or json/structured format.",
    )

    csv_headers = ["platform", "feature", "description", "config_ordered", "match_config", "config_type"]

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (
            self.platform.slug,
            self.feature.name,
            self.description,
            self.config_ordered,
            self.match_config,
            self.config_type,
        )

    class Meta:
        """Meta information for ComplianceRule model."""

        ordering = ("platform", "feature__name")
        unique_together = (
            "feature",
            "platform",
        )

    def __str__(self):
        """Return a sane string representation of the instance."""
        return f"{self.platform} - {self.feature.name}"

    def get_absolute_url(self):
        """Absolute url for the ComplianceRule instance."""
        return reverse("plugins:nautobot_golden_config:compliancerule", args=[self.pk])

    def clean(self):
        """Verify that if cli, then match_config is set."""
        if self.config_type == ComplianceRuleTypeChoice.TYPE_CLI and not self.match_config:
            raise ValidationError("CLI configuration set, but no configuration set to match.")

Meta

Meta information for ComplianceRule model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Meta information for ComplianceRule model."""

    ordering = ("platform", "feature__name")
    unique_together = (
        "feature",
        "platform",
    )

__str__()

Return a sane string representation of the instance.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """Return a sane string representation of the instance."""
    return f"{self.platform} - {self.feature.name}"

clean()

Verify that if cli, then match_config is set.

Source code in nautobot_golden_config/models.py
def clean(self):
    """Verify that if cli, then match_config is set."""
    if self.config_type == ComplianceRuleTypeChoice.TYPE_CLI and not self.match_config:
        raise ValidationError("CLI configuration set, but no configuration set to match.")

get_absolute_url()

Absolute url for the ComplianceRule instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):
    """Absolute url for the ComplianceRule instance."""
    return reverse("plugins:nautobot_golden_config:compliancerule", args=[self.pk])

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (
        self.platform.slug,
        self.feature.name,
        self.description,
        self.config_ordered,
        self.match_config,
        self.config_type,
    )

ConfigCompliance

Bases: PrimaryModel

Configuration compliance details.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_links",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class ConfigCompliance(PrimaryModel):  # pylint: disable=too-many-ancestors
    """Configuration compliance details."""

    device = models.ForeignKey(to="dcim.Device", on_delete=models.CASCADE, help_text="The device", blank=False)
    rule = models.ForeignKey(to="ComplianceRule", on_delete=models.CASCADE, blank=False, related_name="rule")
    compliance = models.BooleanField(null=True, blank=True)
    actual = models.JSONField(blank=True, help_text="Actual Configuration for feature")
    intended = models.JSONField(blank=True, help_text="Intended Configuration for feature")
    missing = models.JSONField(blank=True, help_text="Configuration that should be on the device.")
    extra = models.JSONField(blank=True, help_text="Configuration that should not be on the device.")
    ordered = models.BooleanField(default=True)
    # Used for django-pivot, both compliance and compliance_int should be set.
    compliance_int = models.IntegerField(null=True, blank=True)

    csv_headers = ["Device Name", "Feature", "Compliance"]

    def get_absolute_url(self):
        """Return absolute URL for instance."""
        return reverse("plugins:nautobot_golden_config:configcompliance", args=[self.pk])

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (self.device.name, self.rule.feature.name, self.compliance)

    def to_objectchange(self, action, related_object=None, object_data_extra=None, object_data_exclude=None):
        """Remove actual and intended configuration from changelog."""
        if not object_data_exclude:
            object_data_exclude = ["actual", "intended"]
        return ObjectChange(
            changed_object=self,
            object_repr=str(self),
            action=action,
            object_data=serialize_object(self, extra=object_data_extra, exclude=object_data_exclude),
            object_data_v2=serialize_object_v2(self),
            related_object=related_object,
        )

    class Meta:
        """Set unique together fields for model."""

        ordering = ["device"]
        unique_together = ("device", "rule")

    def __str__(self):
        """String representation of a the compliance."""
        return f"{self.device} -> {self.rule} -> {self.compliance}"

    def save(self, *args, **kwargs):
        """The actual configuration compliance happens here, but the details for actual compliance job would be found in FUNC_MAPPER."""
        if self.rule.config_type == ComplianceRuleTypeChoice.TYPE_CUSTOM and not FUNC_MAPPER.get(
            ComplianceRuleTypeChoice.TYPE_CUSTOM
        ):
            raise ValidationError(
                "Custom type provided, but no `get_custom_compliance` config set, please contact system admin."
            )

        compliance_details = FUNC_MAPPER[self.rule.config_type](obj=self)
        if self.rule.config_type == ComplianceRuleTypeChoice.TYPE_CUSTOM:
            _verify_get_custom_compliance_data(compliance_details)

        self.compliance = compliance_details["compliance"]
        self.compliance_int = compliance_details["compliance_int"]
        self.ordered = compliance_details["ordered"]
        self.missing = compliance_details["missing"]
        self.extra = compliance_details["extra"]

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

Meta

Set unique together fields for model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Set unique together fields for model."""

    ordering = ["device"]
    unique_together = ("device", "rule")

__str__()

String representation of a the compliance.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """String representation of a the compliance."""
    return f"{self.device} -> {self.rule} -> {self.compliance}"

get_absolute_url()

Return absolute URL for instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):
    """Return absolute URL for instance."""
    return reverse("plugins:nautobot_golden_config:configcompliance", args=[self.pk])

save(args, kwargs)

The actual configuration compliance happens here, but the details for actual compliance job would be found in FUNC_MAPPER.

Source code in nautobot_golden_config/models.py
def save(self, *args, **kwargs):
    """The actual configuration compliance happens here, but the details for actual compliance job would be found in FUNC_MAPPER."""
    if self.rule.config_type == ComplianceRuleTypeChoice.TYPE_CUSTOM and not FUNC_MAPPER.get(
        ComplianceRuleTypeChoice.TYPE_CUSTOM
    ):
        raise ValidationError(
            "Custom type provided, but no `get_custom_compliance` config set, please contact system admin."
        )

    compliance_details = FUNC_MAPPER[self.rule.config_type](obj=self)
    if self.rule.config_type == ComplianceRuleTypeChoice.TYPE_CUSTOM:
        _verify_get_custom_compliance_data(compliance_details)

    self.compliance = compliance_details["compliance"]
    self.compliance_int = compliance_details["compliance_int"]
    self.ordered = compliance_details["ordered"]
    self.missing = compliance_details["missing"]
    self.extra = compliance_details["extra"]

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

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (self.device.name, self.rule.feature.name, self.compliance)

to_objectchange(action, related_object=None, object_data_extra=None, object_data_exclude=None)

Remove actual and intended configuration from changelog.

Source code in nautobot_golden_config/models.py
def to_objectchange(self, action, related_object=None, object_data_extra=None, object_data_exclude=None):
    """Remove actual and intended configuration from changelog."""
    if not object_data_exclude:
        object_data_exclude = ["actual", "intended"]
    return ObjectChange(
        changed_object=self,
        object_repr=str(self),
        action=action,
        object_data=serialize_object(self, extra=object_data_extra, exclude=object_data_exclude),
        object_data_v2=serialize_object_v2(self),
        related_object=related_object,
    )

ConfigRemove

Bases: PrimaryModel

ConfigRemove for Regex Line Removals from Backup Configuration Model defintion.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_links",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class ConfigRemove(PrimaryModel):  # pylint: disable=too-many-ancestors
    """ConfigRemove for Regex Line Removals from Backup Configuration Model defintion."""

    name = models.CharField(max_length=255, null=False, blank=False)
    platform = models.ForeignKey(
        to="dcim.Platform",
        on_delete=models.CASCADE,
        related_name="backup_line_remove",
        null=False,
        blank=False,
    )
    description = models.CharField(
        max_length=200,
        blank=True,
    )
    regex = models.CharField(
        max_length=200,
        verbose_name="Regex Pattern",
        help_text="Regex pattern used to remove a line from the backup configuration.",
    )

    clone_fields = ["platform", "description", "regex"]
    csv_headers = ["name", "platform", "description", "regex"]

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (self.name, self.platform.slug, self.regex)

    class Meta:
        """Meta information for ConfigRemove model."""

        ordering = ("platform", "name")
        unique_together = ("name", "platform")

    def __str__(self):
        """Return a simple string if model is called."""
        return self.name

    def get_absolute_url(self):  # pylint: disable=no-self-use
        """Return absolute URL for instance."""
        return reverse("plugins:nautobot_golden_config:configremove", args=[self.pk])

Meta

Meta information for ConfigRemove model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Meta information for ConfigRemove model."""

    ordering = ("platform", "name")
    unique_together = ("name", "platform")

__str__()

Return a simple string if model is called.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """Return a simple string if model is called."""
    return self.name

get_absolute_url()

Return absolute URL for instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):  # pylint: disable=no-self-use
    """Return absolute URL for instance."""
    return reverse("plugins:nautobot_golden_config:configremove", args=[self.pk])

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (self.name, self.platform.slug, self.regex)

ConfigReplace

Bases: PrimaryModel

ConfigReplace for Regex Line Replacements from Backup Configuration Model defintion.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_links",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class ConfigReplace(PrimaryModel):  # pylint: disable=too-many-ancestors
    """ConfigReplace for Regex Line Replacements from Backup Configuration Model defintion."""

    name = models.CharField(max_length=255, null=False, blank=False)
    platform = models.ForeignKey(
        to="dcim.Platform",
        on_delete=models.CASCADE,
        related_name="backup_line_replace",
        null=False,
        blank=False,
    )
    description = models.CharField(
        max_length=200,
        blank=True,
    )
    regex = models.CharField(
        max_length=200,
        verbose_name="Regex Pattern to Substitute",
        help_text="Regex pattern that will be found and replaced with 'replaced text'.",
    )
    replace = models.CharField(
        max_length=200,
        verbose_name="Replaced Text",
        help_text="Text that will be inserted in place of Regex pattern match.",
    )

    clone_fields = ["platform", "description", "regex", "replace"]
    csv_headers = ["name", "platform", "description", "regex", "replace"]

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (self.name, self.platform.slug, self.description, self.regex, self.replace)

    class Meta:
        """Meta information for ConfigReplace model."""

        ordering = ("platform", "name")
        unique_together = ("name", "platform")

    def get_absolute_url(self):
        """Return absolute URL for instance."""
        return reverse("plugins:nautobot_golden_config:configreplace", args=[self.pk])

    def __str__(self):
        """Return a simple string if model is called."""
        return self.name

Meta

Meta information for ConfigReplace model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Meta information for ConfigReplace model."""

    ordering = ("platform", "name")
    unique_together = ("name", "platform")

__str__()

Return a simple string if model is called.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """Return a simple string if model is called."""
    return self.name

get_absolute_url()

Return absolute URL for instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):
    """Return absolute URL for instance."""
    return reverse("plugins:nautobot_golden_config:configreplace", args=[self.pk])

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (self.name, self.platform.slug, self.description, self.regex, self.replace)

GoldenConfig

Bases: PrimaryModel

Configuration Management Model.

Source code in nautobot_golden_config/models.py
@extras_features(
    "custom_fields",
    "custom_links",
    "custom_validators",
    "export_templates",
    "graphql",
    "relationships",
    "webhooks",
)
class GoldenConfig(PrimaryModel):  # pylint: disable=too-many-ancestors
    """Configuration Management Model."""

    device = models.ForeignKey(
        to="dcim.Device",
        on_delete=models.CASCADE,
        help_text="device",
        blank=False,
    )
    backup_config = models.TextField(blank=True, help_text="Full backup config for device.")
    backup_last_attempt_date = models.DateTimeField(null=True)
    backup_last_success_date = models.DateTimeField(null=True)

    intended_config = models.TextField(blank=True, help_text="Intended config for the device.")
    intended_last_attempt_date = models.DateTimeField(null=True)
    intended_last_success_date = models.DateTimeField(null=True)

    compliance_config = models.TextField(blank=True, help_text="Full config diff for device.")
    compliance_last_attempt_date = models.DateTimeField(null=True)
    compliance_last_success_date = models.DateTimeField(null=True)

    csv_headers = [
        "Device Name",
        "backup attempt",
        "backup successful",
        "intended attempt",
        "intended successful",
        "compliance attempt",
        "compliance successful",
    ]

    def to_csv(self):
        """Indicates model fields to return as csv."""
        return (
            self.device,
            self.backup_last_attempt_date,
            self.backup_last_success_date,
            self.intended_last_attempt_date,
            self.intended_last_success_date,
            self.compliance_last_attempt_date,
            self.compliance_last_success_date,
        )

    def to_objectchange(self, action, related_object=None, object_data_extra=None, object_data_exclude=None):
        """Remove actual and intended configuration from changelog."""
        if not object_data_exclude:
            object_data_exclude = ["backup_config", "intended_config", "compliance_config"]
        return ObjectChange(
            changed_object=self,
            object_repr=str(self),
            action=action,
            object_data=serialize_object(self, extra=object_data_extra, exclude=object_data_exclude),
            object_data_v2=serialize_object_v2(self),
            related_object=related_object,
        )

    class Meta:
        """Set unique together fields for model."""

        ordering = ["device"]

    def __str__(self):
        """String representation of a the compliance."""
        return f"{self.device}"

Meta

Set unique together fields for model.

Source code in nautobot_golden_config/models.py
class Meta:
    """Set unique together fields for model."""

    ordering = ["device"]

__str__()

String representation of a the compliance.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """String representation of a the compliance."""
    return f"{self.device}"

to_csv()

Indicates model fields to return as csv.

Source code in nautobot_golden_config/models.py
def to_csv(self):
    """Indicates model fields to return as csv."""
    return (
        self.device,
        self.backup_last_attempt_date,
        self.backup_last_success_date,
        self.intended_last_attempt_date,
        self.intended_last_success_date,
        self.compliance_last_attempt_date,
        self.compliance_last_success_date,
    )

to_objectchange(action, related_object=None, object_data_extra=None, object_data_exclude=None)

Remove actual and intended configuration from changelog.

Source code in nautobot_golden_config/models.py
def to_objectchange(self, action, related_object=None, object_data_extra=None, object_data_exclude=None):
    """Remove actual and intended configuration from changelog."""
    if not object_data_exclude:
        object_data_exclude = ["backup_config", "intended_config", "compliance_config"]
    return ObjectChange(
        changed_object=self,
        object_repr=str(self),
        action=action,
        object_data=serialize_object(self, extra=object_data_extra, exclude=object_data_exclude),
        object_data_v2=serialize_object_v2(self),
        related_object=related_object,
    )

GoldenConfigSetting

Bases: PrimaryModel

GoldenConfigSetting Model defintion. This provides global configs instead of via configs.py.

Source code in nautobot_golden_config/models.py
@extras_features(
    "graphql",
)
class GoldenConfigSetting(PrimaryModel):  # pylint: disable=too-many-ancestors
    """GoldenConfigSetting Model defintion. This provides global configs instead of via configs.py."""

    name = models.CharField(max_length=100, unique=True, blank=False)
    slug = models.SlugField(max_length=100, unique=True, blank=False)
    weight = models.PositiveSmallIntegerField(default=1000, blank=False)
    description = models.CharField(
        max_length=200,
        blank=True,
    )
    backup_repository = models.ForeignKey(
        to="extras.GitRepository",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="backup_repository",
        limit_choices_to={"provided_contents__contains": "nautobot_golden_config.backupconfigs"},
    )
    backup_path_template = models.CharField(
        max_length=255,
        null=False,
        blank=True,
        verbose_name="Backup Path in Jinja Template Form",
        help_text="The Jinja path representation of where the backup file will be found. The variable `obj` is available as the device instance object of a given device, as is the case for all Jinja templates. e.g. `{{obj.site.slug}}/{{obj.name}}.cfg`",
    )
    intended_repository = models.ForeignKey(
        to="extras.GitRepository",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="intended_repository",
        limit_choices_to={"provided_contents__contains": "nautobot_golden_config.intendedconfigs"},
    )
    intended_path_template = models.CharField(
        max_length=255,
        null=False,
        blank=True,
        verbose_name="Intended Path in Jinja Template Form",
        help_text="The Jinja path representation of where the generated file will be places. e.g. `{{obj.site.slug}}/{{obj.name}}.cfg`",
    )
    jinja_repository = models.ForeignKey(
        to="extras.GitRepository",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="jinja_template",
        limit_choices_to={"provided_contents__contains": "nautobot_golden_config.jinjatemplate"},
    )
    jinja_path_template = models.CharField(
        max_length=255,
        null=False,
        blank=True,
        verbose_name="Template Path in Jinja Template Form",
        help_text="The Jinja path representation of where the Jinja template can be found. e.g. `{{obj.platform.slug}}.j2`",
    )
    backup_test_connectivity = models.BooleanField(
        null=False,
        default=True,
        verbose_name="Backup Test",
        help_text="Whether or not to pretest the connectivity of the device by verifying there is a resolvable IP that can connect to port 22.",
    )
    sot_agg_query = models.ForeignKey(
        to="extras.GraphQLQuery",
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="sot_aggregation",
    )
    dynamic_group = models.OneToOneField(
        to="extras.DynamicGroup",
        on_delete=models.PROTECT,
        related_name="golden_config_setting",
    )

    def get_absolute_url(self):  # pylint: disable=no-self-use
        """Return absolute URL for instance."""
        return reverse("plugins:nautobot_golden_config:goldenconfigsetting", args=[self.slug])

    def __str__(self):
        """Return a simple string if model is called."""
        return f"Golden Config Setting - {self.name}"

    @property
    def scope(self):
        """Returns filter from DynamicGroup."""
        if self.dynamic_group:
            return self.dynamic_group.filter
        return {}

    @scope.setter
    def scope(self, value):
        """Create DynamicGroup based on original scope JSON data."""
        if hasattr(self, "dynamic_group"):
            self.dynamic_group.filter = value
            self.dynamic_group.validated_save()
        else:
            name = f"GoldenConfigSetting {self.name} scope"
            content_type = ContentType.objects.get(app_label="dcim", model="device")
            dynamic_group = DynamicGroup.objects.create(
                name=name,
                slug=slugify(name),
                filter=value,
                content_type=content_type,
                description="Automatically generated for nautobot_golden_config GoldenConfigSetting.",
            )
            self.dynamic_group = dynamic_group
            self.validated_save()

    class Meta:
        """Set unique fields for model.

        Provide ordering used in tables and get_device_to_settings_map.
        Sorting on weight is performed from the highest weight value to the lowest weight value.
        This is to ensure only one plugin settings could be applied per single device based on priority and name.
        """

        verbose_name = "Golden Config Setting"
        ordering = ["-weight", "name"]  # Refer to weight comment in class docstring.

    def clean(self):
        """Validate the scope and GraphQL query."""
        super().clean()

        if ENABLE_SOTAGG and not self.sot_agg_query:
            raise ValidationError("A GraphQL query must be defined when `ENABLE_SOTAGG` is True")

        if self.sot_agg_query:
            LOGGER.debug("GraphQL - test  query start with: `%s`", GRAPHQL_STR_START)
            if not str(self.sot_agg_query.query.lstrip()).startswith(GRAPHQL_STR_START):
                raise ValidationError(f"The GraphQL query must start with exactly `{GRAPHQL_STR_START}`")

    def get_queryset(self):
        """Generate a Device QuerySet from the filter."""
        return self.dynamic_group.members

    def device_count(self):
        """Return the number of devices in the group."""
        return self.dynamic_group.count

    def get_url_to_filtered_device_list(self):
        """Get url to all devices that are matching the filter."""
        return self.dynamic_group.get_group_members_url()

scope writable property

Returns filter from DynamicGroup.

Meta

Set unique fields for model.

Provide ordering used in tables and get_device_to_settings_map. Sorting on weight is performed from the highest weight value to the lowest weight value. This is to ensure only one plugin settings could be applied per single device based on priority and name.

Source code in nautobot_golden_config/models.py
class Meta:
    """Set unique fields for model.

    Provide ordering used in tables and get_device_to_settings_map.
    Sorting on weight is performed from the highest weight value to the lowest weight value.
    This is to ensure only one plugin settings could be applied per single device based on priority and name.
    """

    verbose_name = "Golden Config Setting"
    ordering = ["-weight", "name"]  # Refer to weight comment in class docstring.

__str__()

Return a simple string if model is called.

Source code in nautobot_golden_config/models.py
def __str__(self):
    """Return a simple string if model is called."""
    return f"Golden Config Setting - {self.name}"

clean()

Validate the scope and GraphQL query.

Source code in nautobot_golden_config/models.py
def clean(self):
    """Validate the scope and GraphQL query."""
    super().clean()

    if ENABLE_SOTAGG and not self.sot_agg_query:
        raise ValidationError("A GraphQL query must be defined when `ENABLE_SOTAGG` is True")

    if self.sot_agg_query:
        LOGGER.debug("GraphQL - test  query start with: `%s`", GRAPHQL_STR_START)
        if not str(self.sot_agg_query.query.lstrip()).startswith(GRAPHQL_STR_START):
            raise ValidationError(f"The GraphQL query must start with exactly `{GRAPHQL_STR_START}`")

device_count()

Return the number of devices in the group.

Source code in nautobot_golden_config/models.py
def device_count(self):
    """Return the number of devices in the group."""
    return self.dynamic_group.count

get_absolute_url()

Return absolute URL for instance.

Source code in nautobot_golden_config/models.py
def get_absolute_url(self):  # pylint: disable=no-self-use
    """Return absolute URL for instance."""
    return reverse("plugins:nautobot_golden_config:goldenconfigsetting", args=[self.slug])

get_queryset()

Generate a Device QuerySet from the filter.

Source code in nautobot_golden_config/models.py
def get_queryset(self):
    """Generate a Device QuerySet from the filter."""
    return self.dynamic_group.members

get_url_to_filtered_device_list()

Get url to all devices that are matching the filter.

Source code in nautobot_golden_config/models.py
def get_url_to_filtered_device_list(self):
    """Get url to all devices that are matching the filter."""
    return self.dynamic_group.get_group_members_url()