[SRU] Heat wrongly passing "no_fixed_ips" to Neutron
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
Ubuntu Cloud Archive | Status tracked in Epoxy | |||||
Antelope |
Fix Released
|
Undecided
|
Unassigned | |||
Bobcat |
Fix Released
|
Undecided
|
Unassigned | |||
Caracal |
Fix Released
|
Undecided
|
Unassigned | |||
Dalmatian |
Fix Released
|
Undecided
|
Unassigned | |||
Epoxy |
Fix Released
|
Undecided
|
Unassigned | |||
Yoga |
Fix Released
|
Undecided
|
Unassigned | |||
heat (Ubuntu) | Status tracked in Plucky | |||||
Jammy |
Fix Released
|
Undecided
|
Unassigned | |||
Noble |
Fix Released
|
Undecided
|
Unassigned | |||
Oracular |
Fix Released
|
Undecided
|
Unassigned | |||
Plucky |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
====== SRU TEMPLATE AT THE BOTTOM ======
Summary:
--------
When creating an instance via the "OS::Nova::Server" resource type in a Heat template, specifying a network and a subnet to get a port created on the instance, it fails as below:
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.924 5089 ERROR heat.engine.
2024-10-21 15:11:27.933 5089 INFO heat.engine.stack [req-e5c2d5d4-
The reason why this fails is because for ports without fixed IPs, Neutron expects "fixed_ips = []" as it does not understand "no_fixed_ips", but when a subnet is specified, _create_
Now, _prepare_
First extra_props is checked and in our case is not None. Then port_extra_keys gets populated with neutron_
from heat/engine/
...
EXTRA_
) = (
)
...
from heat/engine/
...
def _prepare_
kwargs = {'network_id': self._get_
fixed_ip = net_data.
subnet = net_data.
body = {}
if fixed_ip:
if subnet:
# we should add fixed_ips only if subnet or ip were provided
if body:
if security_groups:
extra_props = net_data.
if extra_props is not None:
specs = extra_props.
if specs:
for key in port_extra_keys:
if extra_props.
if allowed_
for pair in allowed_
```
Again, the reason why this fails is because for ports without fixed IPs, Neutron expects "fixed_ips = []" as it does not understand "no_fixed_ips", so Heat should not be passing that. Commit [1] where the "no_fixed_ips" feature was introduced in Heat, added logic to avoid passing "no_fixed_ips" to Neutron, but that logic was never added for the case where the port is requested to be created via "OS::Nova::Server" (and there could be other edge cases missing this logic too)
[1] https:/
Reproducer:
-----------
Here's a template reproducing the issue:
heat_template_
resources:
server_test:
type: OS::Nova::Server
properties:
name: server_test
config_drive: true
flavor: m1.small
image: "focal-raw"
networks:
- network: 0924ec50-
subnet: cb49c91d-
Openstack versions affected:
-------
>= Wallaby
Potential diff for a fix:
-------
index 794406457.
--- a/heat/
+++ b/heat/
@@ -120,6 +120,8 @@ class ServerNetworkMi
# we should add fixed_ips only if subnet or ip were provided
if body:
+ if net_data.
+ kwargs.
if security_groups:
@@ -133,6 +135,7 @@ class ServerNetworkMi
+ port_extra_
for key in port_extra_keys:
if extra_props.
============
SRU TEMPLATE
============
===============
SRU DESCRIPTION
===============
[Impact]
A mishandling of port parameters in the Nova class when creating instances is causing the issue where the user cannot specify a network + subnet + no specific IP combination to create a VM. Typically users would specify only the network when creating VMs where the specific IP or port doesn't matter, but if the network has multiple subnets, then the user has to specify the desired subnet, triggering the issue because the current code is incorrectly expecting an IP to be also specified in such case, not considering the scenario where the IP wouldn't be specified:
body = {}
if fixed_ip:
body[
if subnet:
body[
# we should add fixed_ips only if subnet or ip were provided
if body:
kwargs.
So if a subnet is specified, the logic is coded to use a fixed ip, not allowing the no_fixed_ips scenario. The fix overrides the logic to not use a fixed_ip in such case:
if net_data.
kwargs.
[Test case]
1) Deploy OpenStack with Heat
2) Copy the following template adjusting the image, flavor, network and subnet IDs accordingly:
heat_template_
resources:
server_test:
type: OS::Nova::Server
properties:
name: server_test
flavor: 6
image: "cirros-0.4.0"
networks:
- network: cdac5ad3-
subnet: 68150f54-
3) deploy the template using:
openstack stack create -t template.yaml stack1
4) Check the status using "openstack stack list". Stack creation should fail, and upon running "openstack stack show" you should see the following error message (except for a different req-ID):
| stack_status_reason | Resource CREATE failed: BadRequest: resources.
| | Neutron server returns request_ids: ['req-b3a2a896-
5) Install fixed package
6) Retry step (4) and it should succeed creating the stack
[Regression Potential]
The code change is affecting the path of creating all VMs. This default path is being tested upstream and it passed CI. The code modifications introduces behavioral changes on the specific situations, specifically when specifying a subnet. This code path is being tested in the SRU. Given the current coverage, we can assume any potential regression has its scope limited to the affected scenario that causes the bug, or to the scenario where a subnet is specified along with an IP/port. However, the code logic seems to be mutually exclusive at [0], indicating that the parameters that lead to one scenario shouldn't cause influence the behavior of the other, therefore we can further assume that the scope of the change is further limited to only this scenario.
[Other Info]
None.
summary: |
- Heat wrongly passing "no_fixed_ips" to Neutron + [SRU] Heat wrongly passing "no_fixed_ips" to Neutron |
description: | updated |
tags: | added: verification-yoga-needed |
Changed in cloud-archive: | |
status: | New → Fix Committed |
tags: |
added: verification-needed removed: verification-done |
Status changed to 'Confirmed' because the bug affects multiple users.