Skip to content

feat: Add enroll-netdev Argo workflow to enroll network devices PUC-1761#2144

Merged
nidzrai merged 1 commit into
mainfrom
argo-netdev-enroll
Jul 16, 2026
Merged

feat: Add enroll-netdev Argo workflow to enroll network devices PUC-1761#2144
nidzrai merged 1 commit into
mainfrom
argo-netdev-enroll

Conversation

@nidzrai

@nidzrai nidzrai commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Implemented enroll-netdev WorkflowTemplate and Python entrypoint following the enroll-server pattern.

Validated in iad-dev by pointing rax-dev-iad3-dev-argo-events-workflows at this branch and using the pr workflow image.

~ 🐍 openstack on ☁️  uc-dev-infra(baremetal) took 4s
❯ openstack baremetal node show fake-netdev-test
+------------------------+--------------------------------------+
| Field                  | Value                                |
+------------------------+--------------------------------------+
| uuid                   | 17f00775-f4c1-405f-83ab-685cb0aeb354 |
| created_at             | 2026-07-16T15:07:48+00:00            |
| updated_at             | 2026-07-16T15:07:51+00:00            |
| automated_clean        | False                                |
| bios_interface         | no-bios                              |
| boot_interface         | ipxe                                 |
| boot_mode              | None                                 |
| clean_step             | {}                                   |
| conductor_group        |                                      |
| console_enabled        | False                                |
| console_interface      | no-console                           |
| disable_power_off      | False                                |
| deploy_interface       | noop                                 |
| deploy_step            | {}                                   |
| description            | None                                 |
| driver                 | netdev                               |
| driver_info            | {}                                   |
| driver_internal_info   | {}                                   |
| extra                  | {}                                   |
| fault                  | None                                 |
| firmware_interface     | no-firmware                          |
| health                 | None                                 |
| inspection_finished_at | None                                 |
| inspection_started_at  | None                                 |
| inspect_interface      | no-inspect                           |
| instance_info          | {}                                   |
| instance_name          | None                                 |
| instance_uuid          | None                                 |
| last_error             | None                                 |
| lessee                 | None                                 |
| maintenance            | False                                |
| maintenance_reason     | None                                 |
| management_interface   | fake                                 |
| name                   | fake-netdev-test                     |
| network_data           | {}                                   |
| network_interface      | neutron                              |
| owner                  | 32e02632f4f04415bab5895d1e7247b7     |
| parent_node            | None                                 |
| power_interface        | fake                                 |
| power_state            | None                                 |
| properties             | {}                                   |
| protected              | False                                |
| protected_reason       | None                                 |
| provision_state        | available                            |
| provision_updated_at   | 2026-07-16T15:07:51+00:00            |
| raid_config            | {}                                   |
| raid_interface         | no-raid                              |
| rescue_interface       | no-rescue                            |
| reservation            | None                                 |
| resource_class         | generic                              |
| retired                | False                                |
| retired_reason         | None                                 |
| secure_boot            | None                                 |
| service_step           | {}                                   |
| shard                  | None                                 |
| storage_interface      | noop                                 |
| target_power_state     | None                                 |
| target_provision_state | None                                 |
| target_raid_config     | {}                                   |
| traits                 | []                                   |
| vendor_interface       | no-vendor                            |
| conductor              | 1327175-hp3                          |
| allocation_uuid        | None                                 |
| chassis_uuid           | None                                 |
+------------------------+--------------------------------------+

~ 🐍 openstack on ☁️  uc-dev-infra(baremetal) took 4s
❯ openstack baremetal node show fake-netdev-test2 -c provision_state -c resource_class -c extra
+-----------------+-------------------------------------+
| Field           | Value                               |
+-----------------+-------------------------------------+
| extra           | {'external_cmdb_id': 'fake-cmdb-1'} |
| provision_state | available                           |
| resource_class  | fake-class                          |
+-----------------+-------------------------------------+ 

Happy Path Log

~ 🐍 openstack took 17s
❯ argo -n argo-events logs @latest -f
Flag --oidc-use-pkce has been deprecated, use --oidc-pkce-method instead. For the most providers, you don't need to set the flag.
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:03 +0000 - understack_workflows.main.enroll_netdev - INFO - Starting enroll-netdev workflow name=fake-netdev-test2 physical_network=fake-physnet resource_class=fake-class
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:03 +0000 - understack_workflows.main.enroll_netdev - INFO - Recording external_cmdb_id=fake-cmdb-1 on the Ironic node
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:04 +0000 - understack_workflows.main.enroll_netdev - INFO - Creating netdev Ironic node name=fake-netdev-test2 driver=netdev resource_class=fake-class automated_clean=false
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:05 +0000 - understack_workflows.main.enroll_netdev - INFO - Created netdev Ironic node name=fake-netdev-test2 uuid=a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:05 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Creating baremetal port name=fake-netdev-test2:port1 mac=02:de:ad:be:ef:03 physical_network=fake-physnet switch_id=00:00:00:00:00:00 switch_info=fake-switch-1 port_id=FakeEth1/1 category=network
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:05 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Created baremetal port name=fake-netdev-test2:port1 uuid=144baaf7-cd64-4c26-829b-ef4185199f1a
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:05 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Creating baremetal port name=fake-netdev-test2:port2 mac=02:de:ad:be:ef:04 physical_network=fake-physnet switch_id=00:00:00:00:00:00 switch_info=fake-switch-2 port_id=FakeEth1/2 category=network
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:06 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Created baremetal port name=fake-netdev-test2:port2 uuid=2e719423-80c3-435a-a5db-051e35e8e12b
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:06 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Requesting manage transition, expecting manageable
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:06 +0000 - understack_workflows.ironic_node - INFO - a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e requesting provision state manage
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:07 +0000 - understack_workflows.ironic_node - INFO - Waiting for node a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e to enter provision state manageable
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:07 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Node is manageable
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:07 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Requesting provide transition, expecting available
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:08 +0000 - understack_workflows.ironic_node - INFO - a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e requesting provision state provide
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:09 +0000 - understack_workflows.ironic_node - INFO - Waiting for node a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e to enter provision state available
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:09 +0000 - understack_workflows.main.enroll_netdev - INFO - [node:a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e] Node is available
enroll-netdev-kh2rr-enroll-netdev-2452634961: 2026-07-16 15:19:09 +0000 - understack_workflows.main.enroll_netdev - INFO - Completed enroll-netdev workflow name=fake-netdev-test2 node_uuid=a92ce5c6-6f73-4ad8-bc87-ab50dc98d04e
enroll-netdev-kh2rr-enroll-netdev-2452634961: time="2026-07-16T15:19:10.105Z" level=info msg="sub-process exited" argo=true error="<nil>"

Test evidence:

  • Submitted via argo -n argo-events submit --from wftmpl/enroll-netdev.
  • Node was created with driver netdev.
  • automated_clean is False.
  • Node reached available.
  • Default resource_class worked as generic.
  • Custom resource_class worked.
  • external_cmdb_id was recorded in node extra.
  • Two baremetal ports were created with:
    • category=network
    • placeholder switch_id=00:00:00:00:00:00
    • expected switch_info
    • expected port_id
    • expected physical_network
~ 🐍 openstack on ☁️  uc-dev-infra(baremetal) took 4s
❯ openstack baremetal port list --node fake-netdev-test --long
+----------+----------+------------+-------+-----------+----------+--------+-----------------------+----------------+-------------+------------------+------------+---------------+-------------+--------------+
| uuid     | address  | created_at | extra | node_uuid | category | vendor | local_link_connection | portgroup_uuid | pxe_enabled | physical_network | updated_at | internal_info | is_smartnic | name         |
+----------+----------+------------+-------+-----------+----------+--------+-----------------------+----------------+-------------+------------------+------------+---------------+-------------+--------------+
| ed4f8928 | 02:de:ad | 2026-07-   |       | 17f00775- | network  | None   | {'switch_id':         | None           | True        | fake-physnet     | None       | {}            | False       | fake-netdev- |
| -f073-   | :be:ef:0 | 16T15:07:4 |       | f4c1-     |          |        | '00:00:00:00:00:00',  |                |             |                  |            |               |             | test:port1   |
| 4a70-    | 1        | 8+00:00    |       | 405f-     |          |        | 'switch_info': 'fake- |                |             |                  |            |               |             |              |
| 920b-    |          |            |       | 83ab-     |          |        | switch-1', 'port_id': |                |             |                  |            |               |             |              |
| d30e91fc |          |            |       | 685cb0aeb |          |        | 'FakeEth1/1'}         |                |             |                  |            |               |             |              |
| ee33     |          |            |       | 354       |          |        |                       |                |             |                  |            |               |             |              |
| 529ff374 | 02:de:ad | 2026-07-   |       | 17f00775- | network  | None   | {'switch_id':         | None           | True        | fake-physnet     | None       | {}            | False       | fake-netdev- |
| -25f5-   | :be:ef:0 | 16T15:07:4 |       | f4c1-     |          |        | '00:00:00:00:00:00',  |                |             |                  |            |               |             | test:port2   |
| 482f-    | 2        | 9+00:00    |       | 405f-     |          |        | 'switch_info': 'fake- |                |             |                  |            |               |             |              |
| 9eb1-    |          |            |       | 83ab-     |          |        | switch-2', 'port_id': |                |             |                  |            |               |             |              |
| 28f2b4f7 |          |            |       | 685cb0aeb |          |        | 'FakeEth1/2'}         |                |             |                  |            |               |             |              |
| 3aa2     |          |            |       | 354       |          |        |                       |                |             |                  |            |               |             |              |
+----------+----------+------------+-------+-----------+----------+--------+-----------------------+----------------+-------------+------------------+------------+---------------+-------------+--------------+
(openstack)

Also tested failure behavior:

  • Invalid MAC fails with Ironic 400.
  • Duplicate MAC fails with Ironic 409.
  • These errors surface clearly in Argo logs.
enroll-netdev-ppcjx-enroll-netdev-1716104529:   File "/opt/venv/lib/python3.12/site-packages/ironicclient/common/http.py", line 472, in _http_request
enroll-netdev-ppcjx-enroll-netdev-1716104529:     raise exc.from_response(  # type: ignore[call-arg]
enroll-netdev-ppcjx-enroll-netdev-1716104529: ironicclient.common.apiclient.exceptions.Conflict: A port with MAC address 02:de:ad:be:ef:01 already exists. (HTTP 409) (Request-ID: req-18c46545-1a9b-40bd-bd9a-4804622c7857)
enroll-netdev-ppcjx-enroll-netdev-1716104529: time="2026-07-16T15:15:44.487Z" level=info msg="sub-process exited" argo=true error="<nil>"

Known limitation:

  • The workflow is not idempotent today. If a run partially succeeds and then fails, retrying with the same name/MAC can fail because the node or port already exists.
  • The workflow currently supports exactly two ports.

follow-up:
Can we keep this PR scoped to the current Jira requirement of two required ports, and create a follow-up to:

  1. make the workflow idempotent/find-or-create, and
  2. support a variable number of ports instead of only port1 and port2?

@nidzrai nidzrai force-pushed the argo-netdev-enroll branch 2 times, most recently from dcaa633 to b550e3a Compare July 16, 2026 15:54
@nidzrai nidzrai requested a review from a team July 16, 2026 15:57

@skrobul skrobul left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread python/understack-workflows/understack_workflows/main/enroll_netdev.py Outdated
Comment thread python/understack-workflows/understack_workflows/main/enroll_netdev.py Outdated
Comment thread python/understack-workflows/understack_workflows/main/enroll_netdev.py Outdated
Comment thread python/understack-workflows/understack_workflows/main/enroll_netdev.py Outdated
@nidzrai nidzrai force-pushed the argo-netdev-enroll branch from b550e3a to 0704c1a Compare July 16, 2026 16:19
@nidzrai nidzrai added this pull request to the merge queue Jul 16, 2026
Merged via the queue into main with commit 98e3936 Jul 16, 2026
61 checks passed
@nidzrai nidzrai deleted the argo-netdev-enroll branch July 16, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants