diff --git a/python/understack-workflows/understack_workflows/main/sync_keystone.py b/python/understack-workflows/understack_workflows/main/sync_keystone.py index 3a326b751..56dea9e1f 100644 --- a/python/understack-workflows/understack_workflows/main/sync_keystone.py +++ b/python/understack-workflows/understack_workflows/main/sync_keystone.py @@ -19,6 +19,8 @@ _EXIT_API_ERROR = 1 _EXIT_EVENT_UNKNOWN = 2 +OUTSIDE_NETWORK_NAME = "OUTSIDE" + class Event(StrEnum): ProjectCreate = "identity.project.created" @@ -70,6 +72,48 @@ def is_valid_domain( return ret +def _create_outside_network(conn: Connection, project_id: uuid.UUID): + network = _find_outside_network(conn, project_id) + if network: + logger.info( + "%s Network %s already exists for this tenant", + OUTSIDE_NETWORK_NAME, + network.id, + ) + else: + payload = { + "project_id": project_id, + "name": OUTSIDE_NETWORK_NAME, + "router:external": False, + } + network = conn.network.create_network(**payload) # type: ignore + logger.info( + "Created %s Network %s for tenant", OUTSIDE_NETWORK_NAME, network.id + ) + conn.network.create_rbac_policy( # type: ignore + object_type="network", + object_id=network.id, + action="access_as_external", + target_project_id=project_id, + ) + + +def _delete_outside_network(conn: Connection, project_id: uuid.UUID): + network = _find_outside_network(conn, project_id) + if network: + conn.delete_network(network.id) + logger.info( + "Deleted %s Network %s for this tenant", OUTSIDE_NETWORK_NAME, network.id + ) + + +def _find_outside_network(conn, project_id): + return conn.network.find_network( # type: ignore + project_id=project_id, + name_or_id=OUTSIDE_NETWORK_NAME, + ) + + def handle_project_create( conn: Connection, nautobot: Nautobot, project_id: uuid.UUID ) -> int: @@ -80,6 +124,7 @@ def handle_project_create( ten = ten_api.create( id=str(project_id), name=project.name, description=project.description ) + _create_outside_network(conn, project_id) except Exception: logger.exception( "Unable to create project %s / %s", str(project_id), project.name @@ -113,6 +158,8 @@ def handle_project_update( project_id, existing_tenant.last_updated, # type: ignore ) + + _create_outside_network(conn, project_id) except Exception: logger.exception( "Unable to update project %s / %s", str(project_id), project.name @@ -129,6 +176,8 @@ def handle_project_delete( if not ten: logger.warning("tenant %s does not exist, nothing to delete", project_id) return _EXIT_SUCCESS + + _delete_outside_network(conn, project_id) ten.delete() # type: ignore logger.info("deleted tenant %s", project_id) return _EXIT_SUCCESS