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

implement plan_result and deploy_result #594

Merged
merged 5 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 0 additions & 23 deletions nautobot_golden_config/filter_extensions.py

This file was deleted.

19 changes: 17 additions & 2 deletions nautobot_golden_config/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,17 @@ class Meta:
class ConfigPlanFilterSet(NautobotFilterSet):
"""Inherits Base Class BaseFilterSet."""

# @staticmethod
# def _get_filter_lookup_dict(existing_filter):
# """Extend method to account for isnull on datetime types."""
# # Choose the lookup expression map based on the filter type

# lookup_map = NautobotFilterSet._get_filter_lookup_dict(existing_filter)
# if existing_filter == lookup_map["config_plan"]
# if isinstance(existing_filter, MultiValueDateTimeFilter):
# lookup_map.update({"isnull": "isnull"})
# return lookup_map

q = django_filters.CharFilter(
method="search",
label="Search",
Expand All @@ -424,9 +435,13 @@ class ConfigPlanFilterSet(NautobotFilterSet):
to_field_name="name",
label="Feature Name",
)
job_result_id = django_filters.ModelMultipleChoiceFilter(
plan_result_id = django_filters.ModelMultipleChoiceFilter(
queryset=JobResult.objects.filter(config_plan__isnull=False).distinct(),
label="Plan JobResult ID",
)
deploy_result_id = django_filters.ModelMultipleChoiceFilter(
queryset=JobResult.objects.filter(config_plan__isnull=False).distinct(),
label="JobResult ID",
label="Deploy JobResult ID",
)
change_control_id = django_filters.CharFilter(
field_name="change_control_id",
Expand Down
15 changes: 11 additions & 4 deletions nautobot_golden_config/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,12 +552,19 @@ class ConfigPlanFilterForm(NautobotFilterForm):
to_field_name="name",
)
change_control_id = forms.CharField(required=False, label="Change Control ID")
job_result_id = utilities_forms.DynamicModelMultipleChoiceField(
plan_result_id = utilities_forms.DynamicModelMultipleChoiceField(
queryset=JobResult.objects.all(),
query_params={"nautobot_golden_config_config_plan_null": True},
label="Job Result",
query_params={"name": "plugins/nautobot_golden_config.jobs/GenerateConfigPlans"},
label="Plan Result",
required=False,
display_field="id",
display_field="created",
)
deploy_result_id = utilities_forms.DynamicModelMultipleChoiceField(
queryset=JobResult.objects.all(),
query_params={"name": "plugins/nautobot_golden_config.jobs/DeployConfigPlans"},
label="Deploy Result",
required=False,
display_field="created",
)
status = utilities_forms.DynamicModelMultipleChoiceField(
required=False,
Expand Down
4 changes: 2 additions & 2 deletions nautobot_golden_config/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def _generate_config_plan_from_feature(self):
change_control_id=self._change_control_id,
change_control_url=self._change_control_url,
status=self._status,
job_result=self.job_result,
plan_result=self.job_result,
)
config_plan.feature.set(features)
config_plan.validated_save()
Expand All @@ -325,7 +325,7 @@ def _generate_config_plan_from_manual(self):
change_control_id=self._change_control_id,
change_control_url=self._change_control_url,
status=self._status,
job_result=self.job_result,
plan_result=self.job_result,
)
self.log_success(obj=config_plan, message=f"Config plan created for {device} with manual commands.")

Expand Down
22 changes: 0 additions & 22 deletions nautobot_golden_config/migrations/0027_auto_20230912_1731.py

This file was deleted.

40 changes: 40 additions & 0 deletions nautobot_golden_config/migrations/0027_auto_20230915_1657.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Django 3.2.20 on 2023-09-15 16:57

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("extras", "0058_jobresult_add_time_status_idxs"),
("nautobot_golden_config", "0026_configplan"),
]

operations = [
migrations.AlterModelOptions(
name="remediationsetting",
options={"ordering": ("platform", "remediation_type")},
),
migrations.RenameField(
model_name="configplan",
old_name="job_result",
new_name="plan_result",
),
migrations.AddField(
model_name="configplan",
name="deploy_result",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name="config_plan_deploy_result",
to="extras.jobresult",
),
),
migrations.AlterField(
model_name="configplan",
name="change_control_id",
field=models.CharField(blank=True, default="", max_length=50),
preserve_default=False,
),
]
13 changes: 11 additions & 2 deletions nautobot_golden_config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from nautobot.utilities.utils import serialize_object, serialize_object_v2
from netutils.config.compliance import feature_compliance
from netutils.lib_mapper import HIERCONFIG_LIB_MAPPER_REVERSE

from nautobot_golden_config.choices import ComplianceRuleConfigTypeChoice, ConfigPlanTypeChoice, RemediationTypeChoice
from nautobot_golden_config.utilities.constant import ENABLE_SOTAGG, PLUGIN_CFG
from nautobot_golden_config.utilities.utils import get_platform
Expand Down Expand Up @@ -865,11 +866,19 @@ class ConfigPlan(PrimaryModel): # pylint: disable=too-many-ancestors
related_name="config_plan",
blank=True,
)
job_result = models.ForeignKey(
plan_result = models.ForeignKey(
to="extras.JobResult",
on_delete=models.CASCADE,
related_name="config_plan",
verbose_name="Job Result",
verbose_name="Plan Result",
)
deploy_result = models.ForeignKey(
to="extras.JobResult",
on_delete=models.PROTECT,
related_name="config_plan_deploy_result",
verbose_name="Deploy Result",
blank=True,
null=True,
)
change_control_id = models.CharField(
max_length=50,
Expand Down
5 changes: 3 additions & 2 deletions nautobot_golden_config/nornir_plays/config_deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
InventoryPluginRegister.register("nautobot-inventory", NautobotORMInventory)


def run_deployment(task: Task, logger: NornirLogger, commit: bool, config_plan_qs) -> Result:
def run_deployment(task: Task, logger: NornirLogger, commit: bool, config_plan_qs, deploy_job_result) -> Result:
"""Deploy configurations to device."""
obj = task.host.data["obj"]
plans_to_deploy = config_plan_qs.filter(device=obj)
plans_to_deploy.update(deploy_result=deploy_job_result.job_result)
consolidated_config_set = "\n".join(plans_to_deploy.values_list("config_set", flat=True))
logger.log_debug(f"Consolidated config set: {consolidated_config_set}")
# TODO: We should add post-processing rendering here
Expand Down Expand Up @@ -67,7 +68,6 @@ def config_deployment(job_result, data, commit):
now = datetime.now()
logger = NornirLogger(__name__, job_result, data.get("debug"))
logger.log_debug("Starting config deployment")

config_plan_qs = data["config_plan"]
if config_plan_qs.filter(status__slug="not-approved").exists():
logger.log_failure(
Expand Down Expand Up @@ -99,6 +99,7 @@ def config_deployment(job_result, data, commit):
logger=logger,
commit=commit,
config_plan_qs=config_plan_qs,
deploy_job_result=job_result,
)
except Exception as err:
logger.log_failure(obj=None, message=f"Failed to initialize Nornir: {err}")
Expand Down
35 changes: 18 additions & 17 deletions nautobot_golden_config/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,11 @@
from django.utils.html import format_html
from django_tables2 import Column, LinkColumn, TemplateColumn
from django_tables2.utils import A

from nautobot.extras.tables import StatusTableMixin
from nautobot.utilities.tables import (
BaseTable,
ToggleColumn,
TagColumn,
)
from nautobot_golden_config import models
from nautobot_golden_config.utilities.constant import (
ENABLE_BACKUP,
ENABLE_COMPLIANCE,
ENABLE_INTENDED,
CONFIG_FEATURES,
)
from nautobot.utilities.tables import BaseTable, TagColumn, ToggleColumn

from nautobot_golden_config import models
from nautobot_golden_config.utilities.constant import CONFIG_FEATURES, ENABLE_BACKUP, ENABLE_COMPLIANCE, ENABLE_INTENDED

ALL_ACTIONS = """
{% if backup == True %}
Expand Down Expand Up @@ -496,8 +486,17 @@ class ConfigPlanTable(StatusTableMixin, BaseTable):

pk = ToggleColumn()
device = LinkColumn("plugins:nautobot_golden_config:configplan", args=[A("pk")])
job_result = TemplateColumn(
template_code="""<a href="{% url 'extras:jobresult' pk=record.job_result.pk %}" <i class="mdi mdi-clipboard-text-play-outline"></i></a> """
plan_result = TemplateColumn(
template_code="""<a href="{% url 'extras:jobresult' pk=record.plan_result.pk %}" <i class="mdi mdi-clipboard-text-play-outline"></i></a> """
)
deploy_result = TemplateColumn(
template_code="""
{% if record.deploy_result %}
<a href="{% url 'extras:jobresult' pk=record.deploy_result.pk %}" <i class="mdi mdi-clipboard-text-play-outline"></i></a>
{% else %}
&mdash;
{% endif %}
"""
)
config_set = TemplateColumn(template_code=CONFIG_SET_BUTTON, verbose_name="Config Set", orderable=False)
tags = TagColumn(url_name="plugins:nautobot_golden_config:configplan_list")
Expand All @@ -514,7 +513,8 @@ class Meta(BaseTable.Meta):
"feature",
"change_control_id",
"change_control_url",
"job_result",
"plan_result",
"deploy_result",
"config_set",
"status",
"tags",
Expand All @@ -527,7 +527,8 @@ class Meta(BaseTable.Meta):
"feature",
"change_control_id",
"change_control_url",
"job_result",
"plan_result",
"deploy_result",
"config_set",
"status",
)
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

function configPlanCount(jobResultId) {
return new Promise(function(resolve, reject) {
var configPlanApi = `/api/plugins/golden-config/config-plan/?job_result_id=${jobResultId}`;
var configPlanApi = `/api/plugins/golden-config/config-plan/?plan_result_id=${jobResultId}`;
$.ajax({
url: configPlanApi,
type: "GET",
Expand Down Expand Up @@ -108,7 +108,7 @@
}

var jobClass = "plugins/nautobot_golden_config.jobs/GenerateConfigPlans";
var redirectUrlTemplate = "/plugins/golden-config/config-plan/?job_result_id={jobData.result.id}";
var redirectUrlTemplate = "/plugins/golden-config/config-plan/?plan_result_id={jobData.result.id}";
var changeControlUrlInput = document.getElementById("id_change_control_url");
var startJobButton = document.getElementById("startJob");
var form = document.querySelector("form");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,17 @@
<td><a href="{{ object.change_control_url }}">{{ object.change_control_url|placeholder }}</a></td>
</tr>
<tr>
<td>Job Result</td>
<td><a href="{{ object.job_result.get_absolute_url }}">{{ object.job_result.status|placeholder }}</a></td>
<td>Plan Result</td>
<td><a href="{{ object.plan_result.get_absolute_url }}">{{ object.plan_result.status|title }}</a></td>
</tr>
<tr>
<td>Deploy Result</td>
{% if object.deploy_result %}
<td><a href="{{ object.deploy_result.get_absolute_url }}">{{ object.deploy_result.status|title }}</a>
{% else %}
<td>{{ object.deploy_result|placeholder }}</td>
{% endif %}
</td>
</tr>
<tr>
<td>Status</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h3 class="modal-title">{{ modal_title }}</h3>
<td><div id="jobStatus" style="display:none;"></div></td>
</tr>
<tr>
<td>Job Results: </td>
<td>Plan Results: </td>
<td><div id="jobResults" style="display:none;"></div></td>
</tr>
<tr>
Expand Down
3 changes: 2 additions & 1 deletion nautobot_golden_config/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from nautobot.extras.models import DynamicGroup, GitRepository, GraphQLQuery, Status
from nautobot.utilities.testing import APITestCase, APIViewTestCases
from rest_framework import status

from nautobot_golden_config.choices import RemediationTypeChoice
from nautobot_golden_config.models import ConfigPlan, GoldenConfigSetting, RemediationSetting

Expand Down Expand Up @@ -376,7 +377,7 @@ def setUpTestData(cls):
change_control_id=f"Test Change Control ID {cont}",
change_control_url=f"https://{cont}.example.com/",
status=not_approved_status,
job_result_id=job_result_ids[cont - 1],
plan_result_id=job_result_ids[cont - 1],
)
plan.feature.add(features[cont - 1])
plan.validated_save()
Expand Down
Loading