From a41be43ad6bf69b778dfef4e627aef27a597c51f Mon Sep 17 00:00:00 2001 From: Nicholas Kuechler Date: Fri, 21 Mar 2025 16:57:19 -0500 Subject: [PATCH] feat: Adds 'uc-diff projects' to diff all projects --- .../diff_nautobot_understack/cli.py | 20 ++++++++++++-- .../project/adapters/nautobot_tenant.py | 26 +++++++++++++++++++ .../project/adapters/openstack_project.py | 22 ++++++++++++++++ .../diff_nautobot_understack/project/main.py | 14 ++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/python/diff-nautobot-understack/diff_nautobot_understack/cli.py b/python/diff-nautobot-understack/diff_nautobot_understack/cli.py index ef3bd7de1..98d64501c 100644 --- a/python/diff-nautobot-understack/diff_nautobot_understack/cli.py +++ b/python/diff-nautobot-understack/diff_nautobot_understack/cli.py @@ -10,6 +10,9 @@ from diff_nautobot_understack.network.main import ( openstack_network_diff_from_ucvni_network, ) +from diff_nautobot_understack.project.main import ( + openstack_all_projects_diff_from_nautobot_tenant, +) from diff_nautobot_understack.project.main import ( openstack_project_diff_from_nautobot_tenant, ) @@ -62,6 +65,19 @@ def tabular_output(diffs, title, id_column_name): console.print(table) +@app.command() +def projects( + debug: bool = typer.Option(False, "--debug", "-v", help="Enable debug mode"), + output_format: str = typer.Option( + "json", "--format", help="Available formats json, table" + ), +): + """OpenStack projects ⟹ Nautobot tenants""" + settings.debug = debug + diff_result = openstack_all_projects_diff_from_nautobot_tenant() + display_output(diff_result, "project", output_format) + + @app.command() def project( name: str, @@ -70,7 +86,7 @@ def project( "json", "--format", help="Available formats json, table" ), ): - """Nautobot tenants ⟹ Openstack projects""" + """OpenStack projects ⟹ Nautobot tenants""" settings.debug = debug diff_result = openstack_project_diff_from_nautobot_tenant(os_project=name) display_output(diff_result, "project", output_format) @@ -83,7 +99,7 @@ def network( "json", "--format", help="Available formats json, table" ), ): - """Nautobot ucvnis ⟹ Openstack networks""" + """OpenStack networks ⟹ Nautobot UCVNIs""" settings.debug = debug diff_result = openstack_network_diff_from_ucvni_network() display_output(diff_result, "network", output_format) diff --git a/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/nautobot_tenant.py b/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/nautobot_tenant.py index 094a1fc9c..850becdb4 100644 --- a/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/nautobot_tenant.py +++ b/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/nautobot_tenant.py @@ -35,3 +35,29 @@ def load(self): description=tenant.get("description"), ) ) + + +class Tenants(Adapter): + """All tenants.""" + + project = models.ProjectModel + + top_level = ["project"] + type = "Tenant" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.api_client = API() + + def load(self): + url = "/api/tenancy/tenants/?include=relationships" + tenants_response = self.api_client.make_api_request(url, paginated=True) + + for tenant in tenants_response: + self.add( + self.project( + id=_remove_hyphens(tenant.get("id")), + name=tenant.get("name"), + description=tenant.get("description"), + ) + ) diff --git a/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/openstack_project.py b/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/openstack_project.py index 64c8ae8a6..1cf5f0590 100644 --- a/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/openstack_project.py +++ b/python/diff-nautobot-understack/diff_nautobot_understack/project/adapters/openstack_project.py @@ -32,3 +32,25 @@ def load(self): description=os_project.description, ) ) + + +class Projects(Adapter): + project = models.ProjectModel + + top_level = ["project"] + type = "OpenstackProject" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + openstack_api = API() + self.cloud = openstack_api.cloud_connection + + def load(self): + for os_project in self.cloud.identity.projects(): + self.add( + self.project( + id=os_project.id, + name=os_project.name, + description=os_project.description, + ) + ) diff --git a/python/diff-nautobot-understack/diff_nautobot_understack/project/main.py b/python/diff-nautobot-understack/diff_nautobot_understack/project/main.py index a749f2554..65a139dbc 100644 --- a/python/diff-nautobot-understack/diff_nautobot_understack/project/main.py +++ b/python/diff-nautobot-understack/diff_nautobot_understack/project/main.py @@ -2,7 +2,9 @@ from diffsync.enum import DiffSyncFlags from diff_nautobot_understack.project.adapters.nautobot_tenant import Tenant +from diff_nautobot_understack.project.adapters.nautobot_tenant import Tenants from diff_nautobot_understack.project.adapters.openstack_project import Project +from diff_nautobot_understack.project.adapters.openstack_project import Projects from diff_nautobot_understack.settings import app_settings as settings @@ -17,3 +19,15 @@ def openstack_project_diff_from_nautobot_tenant(os_project=None) -> Diff: openstack_project, flags=DiffSyncFlags.CONTINUE_ON_FAILURE ) return tenant_destination_openstack_project_source + + +def openstack_all_projects_diff_from_nautobot_tenant() -> Diff: + openstack_project = Projects() + openstack_project.load() + + nautobot_tenant = Tenants() + nautobot_tenant.load() + tenant_destination_openstack_project_source = nautobot_tenant.diff_from( + openstack_project, flags=DiffSyncFlags.CONTINUE_ON_FAILURE + ) + return tenant_destination_openstack_project_source