Skip to content

Commit 3d18f99

Browse files
PUC-1758: remove physical_network fallback lookup
1 parent 83bdc54 commit 3d18f99

6 files changed

Lines changed: 907 additions & 54 deletions

File tree

components/images-openstack.yaml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ images:
3434
ironic_retrive_swift_config: "ghcr.io/rackerlabs/understack/openstack-client:2025.2"
3535

3636
# neutron
37-
neutron_db_sync: "ghcr.io/rackerlabs/understack/neutron:2026.1"
38-
neutron_dhcp: "ghcr.io/rackerlabs/understack/neutron:2026.1"
39-
neutron_l3: "ghcr.io/rackerlabs/understack/neutron:2026.1"
40-
neutron_l2gw: "ghcr.io/rackerlabs/understack/neutron:2026.1"
41-
neutron_linuxbridge_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1"
42-
neutron_metadata: "ghcr.io/rackerlabs/understack/neutron:2026.1"
43-
neutron_ovn_metadata: "ghcr.io/rackerlabs/understack/neutron:2026.1"
44-
neutron_openvswitch_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1"
45-
neutron_server: "ghcr.io/rackerlabs/understack/neutron:2026.1"
46-
neutron_rpc_server: "ghcr.io/rackerlabs/understack/neutron:2026.1"
47-
neutron_bagpipe_bgp: "ghcr.io/rackerlabs/understack/neutron:2026.1"
48-
neutron_netns_cleanup_cron: "ghcr.io/rackerlabs/understack/neutron:2026.1"
37+
neutron_db_sync: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
38+
neutron_dhcp: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
39+
neutron_l3: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
40+
neutron_l2gw: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
41+
neutron_linuxbridge_agent: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
42+
neutron_metadata: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
43+
neutron_ovn_metadata: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
44+
neutron_openvswitch_agent: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
45+
neutron_server: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
46+
neutron_rpc_server: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
47+
neutron_bagpipe_bgp: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
48+
neutron_netns_cleanup_cron: "ghcr.io/rackerlabs/understack/neutron:pr-2145"
4949

5050
# nova
5151
nova_api: "ghcr.io/rackerlabs/understack/nova:2026.1"

python/neutron-understack/neutron_understack/neutron_understack_mech.py

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,6 @@ def _update_port_baremetal(self, context: PortContext) -> None:
266266
port = context.current
267267

268268
vlan_group_name = port[portbindings.PROFILE].get("physical_network")
269-
if vlan_group_name is None:
270-
local_link_info = utils.local_link_from_binding_profile(
271-
port[portbindings.PROFILE]
272-
)
273-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
274-
local_link_info
275-
)
276269

277270
if current_vif_unbound and original_vif_other:
278271
self._tenant_network_port_cleanup(context)
@@ -329,13 +322,6 @@ def _delete_port_baremetal(self, context: PortContext) -> None:
329322
port = context.current
330323

331324
vlan_group_name = port[portbindings.PROFILE].get("physical_network")
332-
if vlan_group_name is None:
333-
local_link_info = utils.local_link_from_binding_profile(
334-
port[portbindings.PROFILE]
335-
)
336-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
337-
local_link_info
338-
)
339325

340326
if vlan_group_name and is_provisioning_network(port["network_id"]):
341327
# Signals end of the provisioning / cleaning cycle, so we
@@ -387,19 +373,19 @@ def _bind_port_segment(self, context: PortContext, segment):
387373
port = context.current
388374

389375
vlan_group_name = port[portbindings.PROFILE].get("physical_network")
390-
if vlan_group_name is None:
391-
local_link_info = utils.local_link_from_binding_profile(
392-
port[portbindings.PROFILE]
393-
)
394-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
395-
local_link_info
396-
)
397376

398377
if not vlan_group_name:
399378
LOG.error(
400-
"bind_port_segment: no physical_network found for baremetal "
401-
"port with mac address: %(mac)s",
402-
{"mac": mac_address},
379+
"bind_port_segment: physical_network is required in binding_profile "
380+
"for baremetal port binding, but was not found. "
381+
"port_id=%(port_id)s mac_address=%(mac)s network_id=%(network_id)s. "
382+
"Please ensure the port's binding_profile contains physical_network "
383+
"in local_link_information.",
384+
{
385+
"port_id": port["id"],
386+
"mac": mac_address,
387+
"network_id": network_id,
388+
},
403389
)
404390
return
405391

python/neutron-understack/neutron_understack/tests/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,14 @@ def binding_profile(request, port_id) -> str:
199199
req = getattr(request, "param", {})
200200
return json.dumps(
201201
{
202+
"physical_network": req.get("physical_network", "physnet"),
202203
"local_link_information": [
203204
{
204205
"port_id": req.get("port_id", str(port_id)),
205206
"switch_id": "11:22:33:44:55:66",
206207
"switch_info": "a1-1-1.iad3.rackspace.net",
207208
}
208-
]
209+
],
209210
}
210211
)
211212

python/neutron-understack/neutron_understack/tests/test_neutron_understack_mech.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,24 @@ def test_refuses_unsupported_vnic_type(
250250

251251
port_context.continue_binding.assert_not_called()
252252

253-
@pytest.mark.usefixtures("_ironic_baremetal_port_physical_network")
254-
def test_does_not_bind_when_physical_network_not_found(
253+
def test_fails_when_physical_network_missing(
255254
self, mocker, port_context, understack_driver
256255
):
257-
understack_driver.ironic_client.baremetal_port_physical_network.return_value = (
258-
None
259-
)
256+
"""Port binding fails when physical_network is absent from binding_profile.
257+
258+
This enforces that physical_network must be present for binding to succeed.
259+
"""
260+
# Remove physical_network from binding_profile to test hard requirement
261+
binding_profile_dict = port_context.current[portbindings.PROFILE].copy()
262+
binding_profile_dict.pop("physical_network", None)
263+
port_context.current[portbindings.PROFILE] = binding_profile_dict
264+
260265
mocker.patch.object(port_context, "continue_binding")
261266
port_context._prepare_to_bind(port_context.network.network_segments)
262267

263268
understack_driver.bind_port(port_context)
264269

270+
# Binding should not proceed without physical_network
265271
port_context.continue_binding.assert_not_called()
266272

267273
@pytest.mark.parametrize("port_dict", [{"trunk": True}], indirect=True)

python/neutron-understack/neutron_understack/trunk.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,16 @@ def _add_subports_networks_to_parent_port_switchport(
182182
binding_host = parent_port.bindings[0].host
183183

184184
vlan_group_name = binding_profile.get("physical_network")
185-
if vlan_group_name is None:
186-
local_link_info = utils.local_link_from_binding_profile(binding_profile)
187-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
188-
local_link_info
185+
if not vlan_group_name:
186+
raise exc.BadRequest(
187+
resource="port",
188+
msg=(
189+
"physical_network is required in binding_profile for baremetal "
190+
f"port trunk configuration. Port {parent_port.id} does not have "
191+
"physical_network in its binding_profile. "
192+
"Please ensure the port's binding_profile contains "
193+
"physical_network in local_link_information."
194+
),
189195
)
190196

191197
self._handle_segment_allocation(subports, vlan_group_name, binding_host)
@@ -211,10 +217,17 @@ def _clean_parent_port_switchport_config(
211217
binding_host = parent_port_obj.bindings[0].host
212218

213219
vlan_group_name = binding_profile.get("physical_network")
214-
if vlan_group_name is None:
215-
local_link_info = utils.local_link_from_binding_profile(binding_profile)
216-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
217-
local_link_info
220+
if not vlan_group_name:
221+
port_id = parent_port_obj.id
222+
raise exc.BadRequest(
223+
resource="port",
224+
msg=(
225+
"physical_network is required in binding_profile for baremetal "
226+
f"port trunk configuration. Port {port_id} does not have "
227+
"physical_network in its binding_profile. "
228+
"Please ensure the port's binding_profile contains "
229+
"physical_network in local_link_information."
230+
),
218231
)
219232
self._handle_subports_removal(
220233
binding_profile=binding_profile,
@@ -265,10 +278,17 @@ def subports_added_post(self, resource, event, trunk_plugin, payload):
265278
if utils.parent_port_is_bound(parent_port):
266279
binding_profile = parent_port.bindings[0].profile
267280
vlan_group_name = binding_profile.get("physical_network")
268-
if vlan_group_name is None:
269-
local_link_info = utils.local_link_from_binding_profile(binding_profile)
270-
vlan_group_name = self.ironic_client.baremetal_port_physical_network(
271-
local_link_info
281+
if not vlan_group_name:
282+
port_id = parent_port.id
283+
raise exc.BadRequest(
284+
resource="port",
285+
msg=(
286+
"physical_network is required in binding_profile for "
287+
f"baremetal port trunk configuration. Port {port_id} does not "
288+
"have physical_network in its binding_profile. "
289+
"Please ensure the port's binding_profile contains "
290+
"physical_network in local_link_information."
291+
),
272292
)
273293
LOG.debug("subports_added_post found vlan_group_name=%s", vlan_group_name)
274294
self.undersync.sync(vlan_group_name)

0 commit comments

Comments
 (0)