diff --git a/development/docker-compose.test-designs.yml b/development/docker-compose.test-designs.yml new file mode 100644 index 00000000..af1dd803 --- /dev/null +++ b/development/docker-compose.test-designs.yml @@ -0,0 +1,9 @@ +--- +version: "3.8" +services: + nautobot: + volumes: + - "../nautobot_design_builder/tests/designs:/opt/nautobot/jobs" + worker: + volumes: + - "../nautobot_design_builder/tests/designs:/opt/nautobot/jobs" diff --git a/docs/admin/release_notes/version_1.1.md b/docs/admin/release_notes/version_1.1.md index 4dac29db..f75f6532 100644 --- a/docs/admin/release_notes/version_1.1.md +++ b/docs/admin/release_notes/version_1.1.md @@ -17,3 +17,5 @@ - Renamed `nautobot_design_builder.design.Builder` to `nautobot_design_builder.Environment` - aliased original name with deprecation warning. - Any designs that set `OneToOne` relationships (such as device `primary_ip4`) may now need a `deferred: true` statement in their design for those fields. Previously, `OneToOne` relationships were always deferred and this is usually unnecessary. Any deferrals must now be explicit. + +- Design reports are now saved to the file `report.md` for Nautobot 2.x installations. diff --git a/nautobot_design_builder/design_job.py b/nautobot_design_builder/design_job.py index dcd2e55f..966d4535 100644 --- a/nautobot_design_builder/design_job.py +++ b/nautobot_design_builder/design_job.py @@ -49,6 +49,7 @@ def __init__(self, *args, **kwargs): # TODO: Remove this when we no longer support Nautobot 1.x self.rendered = None self.failed = False + self.report = None super().__init__(*args, **kwargs) @@ -67,10 +68,13 @@ def post_implementation(self, context: Context, environment: Environment): def post_run(self): """Method that will run after the main Nautobot job has executed.""" + # TODO: This is not supported in Nautobot 2 and the entire method + # should be removed once we no longer support Nautobot 1. if self.rendered: self.job_result.data["output"] = self.rendered self.job_result.data["designs"] = self.designs + self.job_result.data["report"] = self.report def render(self, context: Context, filename: str) -> str: """High level function to render the Jinja design templates into YAML. @@ -194,8 +198,10 @@ def run(self, **kwargs): # pylint: disable=arguments-differ,too-many-branches if commit: self.post_implementation(context, self.environment) if hasattr(self.Meta, "report"): - self.job_result.data["report"] = self.render_report(context, self.environment.journal) - self.log_success(message=self.job_result.data["report"]) + self.report = self.render_report(context, self.environment.journal) + self.log_success(message=self.report) + if nautobot_version >= "2.0": + self.save_design_file("report.md", self.report) else: transaction.savepoint_rollback(sid) self.log_info( diff --git a/nautobot_design_builder/tests/designs/test_designs.py b/nautobot_design_builder/tests/designs/test_designs.py index ebf2c8c0..a569e439 100644 --- a/nautobot_design_builder/tests/designs/test_designs.py +++ b/nautobot_design_builder/tests/designs/test_designs.py @@ -2,6 +2,7 @@ from nautobot_design_builder.design_job import DesignJob from nautobot_design_builder.ext import Extension +from nautobot_design_builder.util import nautobot_version class SimpleDesign(DesignJob): @@ -16,7 +17,7 @@ class SimpleDesignReport(DesignJob): """Simple design job that includes a post-implementation report.""" class Meta: # pylint: disable=too-few-public-methods - name = "Simple Design" + name = "Simple Design with Report" design_file = "templates/simple_design.yaml.j2" report = "templates/simple_report.md.j2" @@ -25,7 +26,7 @@ class MultiDesignJob(DesignJob): """Design job that is implemented from multiple design files.""" class Meta: # pylint: disable=too-few-public-methods - name = "Simple Design" + name = "Multi File Design" design_files = [ "templates/simple_design.yaml.j2", "templates/simple_design_2.yaml.j2", @@ -36,7 +37,7 @@ class MultiDesignJobWithError(DesignJob): """Design job that includes an error (for unit testing).""" class Meta: # pylint: disable=too-few-public-methods - name = "Simple Design" + name = "Multi File Design with Error" design_files = [ "templates/simple_design.yaml.j2", "templates/simple_design.yaml.j2", @@ -72,3 +73,17 @@ class DesignWithValidationError(DesignJob): class Meta: # pylint: disable=too-few-public-methods name = "Design with validation errors" design_file = "templates/design_with_validation_error.yaml.j2" + + +if nautobot_version >= "2.0": + from nautobot.apps.jobs import register_jobs # pylint: disable=import-error, no-name-in-module + + register_jobs( + SimpleDesign, + SimpleDesignReport, + MultiDesignJob, + MultiDesignJobWithError, + DesignJobWithExtensions, + DesignWithRefError, + DesignWithValidationError, + ) diff --git a/nautobot_design_builder/tests/test_design_job.py b/nautobot_design_builder/tests/test_design_job.py index 14e114d7..d585e637 100644 --- a/nautobot_design_builder/tests/test_design_job.py +++ b/nautobot_design_builder/tests/test_design_job.py @@ -31,7 +31,7 @@ def test_simple_design_report(self): job = self.get_mocked_job(test_designs.SimpleDesignReport) job.run(data={}, commit=True) self.assertJobSuccess(job) - self.assertEqual("Report output", job.job_result.data["report"]) # pylint: disable=unsubscriptable-object + self.assertEqual("Report output", job.report) def test_multiple_design_files(self): job = self.get_mocked_job(test_designs.MultiDesignJob)