diff --git a/charts/site-workflows/templates/sensor-ironic-port-delete.yaml b/charts/site-workflows/templates/sensor-ironic-port-delete.yaml index 453dffadd..ed6d6ac0c 100644 --- a/charts/site-workflows/templates/sensor-ironic-port-delete.yaml +++ b/charts/site-workflows/templates/sensor-ironic-port-delete.yaml @@ -60,11 +60,11 @@ spec: # defines the parameters being replaced above arguments: parameters: - - name: vlan_group_uuid + - name: physical_network - name: force - value: false + value: "false" - name: dry_run - value: false + value: "false" # references the workflow workflowTemplateRef: name: undersync-switch diff --git a/python/understack-workflows/understack_workflows/main/undersync_switch.py b/python/understack-workflows/understack_workflows/main/undersync_switch.py index 40432ef0d..b2c336c15 100644 --- a/python/understack-workflows/understack_workflows/main/undersync_switch.py +++ b/python/understack-workflows/understack_workflows/main/undersync_switch.py @@ -20,12 +20,12 @@ def call_undersync(args): try: logger.debug( "Syncing switches in vlan group %s args.dry_run=%s args.force=%s", - args.vlan_group_uuid, + args.physical_network, args.dry_run, args.force, ) return undersync.sync_devices( - args.vlan_group_uuid, + args.physical_network, dry_run=args.dry_run, force=args.force, ) @@ -40,10 +40,10 @@ def argument_parser(): description="Trigger undersync run for a set of switches.", ) parser.add_argument( - "--vlan_group_uuid", + "--physical-network", type=str, required=True, - help="UUID of Nautobot VlanGroup containing the switches to Undersync", + help="Port physical_network / Nautobot VLANGroup", ) parser.add_argument( "--force", diff --git a/python/understack-workflows/understack_workflows/undersync/client.py b/python/understack-workflows/understack_workflows/undersync/client.py index 1651bb4b7..8f0a61aa4 100644 --- a/python/understack-workflows/understack_workflows/undersync/client.py +++ b/python/understack-workflows/understack_workflows/undersync/client.py @@ -1,4 +1,5 @@ from functools import cached_property +from urllib.parse import quote import requests @@ -13,13 +14,13 @@ def __init__( self.token = auth_token self.api_url = api_url - def sync_devices(self, vlan_group_uuid: str, force=False, dry_run=False): + def sync_devices(self, physical_network: str, force=False, dry_run=False): if dry_run: - return self.dry_run(vlan_group_uuid) + return self.dry_run(physical_network) elif force: - return self.force(vlan_group_uuid) + return self.force(physical_network) else: - return self.sync(vlan_group_uuid) + return self.sync(physical_network) @cached_property def client(self): @@ -30,17 +31,20 @@ def client(self): } return session - def sync(self, uuids: str) -> requests.Response: - response = self.client.post(f"{self.api_url}/v1/vlan-group/{uuids}/sync") + def sync(self, physical_network: str) -> requests.Response: + physnet = quote(physical_network, safe="") + response = self.client.post(f"{self.api_url}/v1/vlan-group/{physnet}/sync") response.raise_for_status() return response - def dry_run(self, uuids: str) -> requests.Response: - response = self.client.post(f"{self.api_url}/v1/vlan-group/{uuids}/dry-run") + def dry_run(self, physical_network: str) -> requests.Response: + physnet = quote(physical_network, safe="") + response = self.client.post(f"{self.api_url}/v1/vlan-group/{physnet}/dry-run") response.raise_for_status() return response - def force(self, uuids: str) -> requests.Response: - response = self.client.post(f"{self.api_url}/v1/vlan-group/{uuids}/force") + def force(self, physical_network: str) -> requests.Response: + physnet = quote(physical_network, safe="") + response = self.client.post(f"{self.api_url}/v1/vlan-group/{physnet}/force") response.raise_for_status() return response diff --git a/workflows/argo-events/workflowtemplates/undersync-switch.yaml b/workflows/argo-events/workflowtemplates/undersync-switch.yaml index 3d855a5b6..736fc45a0 100644 --- a/workflows/argo-events/workflowtemplates/undersync-switch.yaml +++ b/workflows/argo-events/workflowtemplates/undersync-switch.yaml @@ -4,24 +4,64 @@ metadata: annotations: workflows.argoproj.io/title: Requests an Undersync run on a pair of switches workflows.argoproj.io/description: | + Requests an Undersync run for a switch pair identified by `physical_network`. + + Parameters: + + - `physical_network`: required switch pair / physical network identifier + - `force`: push non-safe changes, without this config drift in non-safe areas won't apply + - `dry_run`: show the intended changes without applying them + + To test this workflow you can run it with the following: + + ``` + argo -n argo-events submit --from workflowtemplate/undersync-switch \ + -p physical_network=physnet1 -p force=false -p dry_run=false + ``` + Defined in `workflows/argo-events/workflowtemplates/undersync-switch.yaml` kind: WorkflowTemplate spec: entrypoint: undersync-switch serviceAccountName: workflow + arguments: + parameters: + - name: physical_network + description: Name of the physical_network (a.k.a. VLAN Group, e.g. "a1-1-network"), tells Undersync which switch pair to configure. + - name: force + description: | + Override safety guardrails when "Change requires approval" + When force=true it disables undersync safety features that would otherwise guard against taking the switch offline, guard against operating on the wrong switch (e.g. DNS snafu), allow the NOC to suspend operations, etc. + When the guardrails are preventing a change from being pushed to the switch, undersync will respond with an error that includes a status like "Change requires approval". + This parameter should never be needed in normal operations. + default: "false" + enum: + - "true" + - "false" + - name: dry_run + description: Preview the changes without making any updates. + default: "false" + enum: + - "true" + - "false" templates: - name: undersync-switch + inputs: + parameters: + - name: physical_network + - name: force + - name: dry_run container: image: ghcr.io/rackerlabs/understack/ironic-nautobot-client:latest command: - undersync-switch args: - - --vlan_group_uuid - - "{{workflow.parameters.vlan_group_uuid}}" + - --physical-network + - "{{inputs.parameters.physical_network}}" - --dry-run - - "{{workflow.parameters.dry_run}}" + - "{{inputs.parameters.dry_run}}" - --force - - "{{workflow.parameters.force}}" + - "{{inputs.parameters.force}}" volumeMounts: - mountPath: /etc/nb-token/ name: nb-token @@ -35,11 +75,6 @@ spec: secretKeyRef: name: nautobot-token key: url - inputs: - parameters: - - name: vlan_group_uuid - - name: force - - name: dry_run volumes: - name: nb-token secret: