Merge "Allow creating a Neutron port without fixed ips"

This commit is contained in:
Zuul 2021-03-15 18:44:39 +00:00 committed by Gerrit Code Review
commit af0dd44dab
3 changed files with 84 additions and 20 deletions

View File

@ -14,6 +14,7 @@
from oslo_log import log as logging from oslo_log import log as logging
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
from heat.common import exception
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine import attributes from heat.engine import attributes
from heat.engine import constraints from heat.engine import constraints
@ -53,11 +54,11 @@ class Port(neutron.NeutronResource):
EXTRA_PROPERTIES = ( EXTRA_PROPERTIES = (
VALUE_SPECS, ADMIN_STATE_UP, MAC_ADDRESS, VALUE_SPECS, ADMIN_STATE_UP, MAC_ADDRESS,
ALLOWED_ADDRESS_PAIRS, VNIC_TYPE, QOS_POLICY, ALLOWED_ADDRESS_PAIRS, VNIC_TYPE, QOS_POLICY,
PORT_SECURITY_ENABLED, PROPAGATE_UPLINK_STATUS, PORT_SECURITY_ENABLED, PROPAGATE_UPLINK_STATUS, NO_FIXED_IPS,
) = ( ) = (
'value_specs', 'admin_state_up', 'mac_address', 'value_specs', 'admin_state_up', 'mac_address',
'allowed_address_pairs', 'binding:vnic_type', 'qos_policy', 'allowed_address_pairs', 'binding:vnic_type', 'qos_policy',
'port_security_enabled', 'propagate_uplink_status', 'port_security_enabled', 'propagate_uplink_status', 'no_fixed_ips',
) )
_FIXED_IP_KEYS = ( _FIXED_IP_KEYS = (
@ -313,6 +314,13 @@ class Port(neutron.NeutronResource):
update_allowed=True, update_allowed=True,
support_status=support.SupportStatus(version='15.0.0') support_status=support.SupportStatus(version='15.0.0')
), ),
NO_FIXED_IPS: properties.Schema(
properties.Schema.BOOLEAN,
_('Flag to disable all fixed ips on the port.'),
update_allowed=True,
support_status=support.SupportStatus(version='16.0.0'),
default=False
),
} }
# Need to update properties_schema with other properties before # Need to update properties_schema with other properties before
@ -442,6 +450,14 @@ class Port(neutron.NeutronResource):
) )
] ]
def validate(self):
super(Port, self).validate()
fixed_ips = self.properties.get(self.FIXED_IPS)
no_fixed_ips = self.properties.get(self.NO_FIXED_IPS, False)
if fixed_ips and no_fixed_ips:
raise exception.ResourcePropertyConflict(self.FIXED_IPS,
self.NO_FIXED_IPS)
def add_dependencies(self, deps): def add_dependencies(self, deps):
super(Port, self).add_dependencies(deps) super(Port, self).add_dependencies(deps)
# Depend on any Subnet in this template with the same # Depend on any Subnet in this template with the same
@ -480,24 +496,28 @@ class Port(neutron.NeutronResource):
self.set_tags(tags) self.set_tags(tags)
def _prepare_port_properties(self, props, prepare_for_update=False): def _prepare_port_properties(self, props, prepare_for_update=False):
if self.FIXED_IPS in props: if not props.pop(self.NO_FIXED_IPS, False):
fixed_ips = props[self.FIXED_IPS] if self.FIXED_IPS in props:
if fixed_ips: fixed_ips = props[self.FIXED_IPS]
for fixed_ip in fixed_ips: if fixed_ips:
for key, value in list(fixed_ip.items()): for fixed_ip in fixed_ips:
if value is None: for key, value in list(fixed_ip.items()):
fixed_ip.pop(key) if value is None:
if self.FIXED_IP_SUBNET in fixed_ip: fixed_ip.pop(key)
fixed_ip[ if self.FIXED_IP_SUBNET in fixed_ip:
'subnet_id'] = fixed_ip.pop(self.FIXED_IP_SUBNET) fixed_ip['subnet_id'] = \
else: fixed_ip.pop(self.FIXED_IP_SUBNET)
# Passing empty list would have created a port without else:
# fixed_ips during CREATE and released the existing # Passing empty list would have created a port without
# fixed_ips during UPDATE (default neutron behaviour). # fixed_ips during CREATE and released the existing
# However, for backward compatibility we will let neutron # fixed_ips during UPDATE (default neutron behaviour).
# assign ip for CREATE and leave the assigned ips during # However, for backward compatibility we will let neutron
# UPDATE by not passing it. ref bug #1538473. # assign ip for CREATE and leave the assigned ips during
del props[self.FIXED_IPS] # UPDATE by not passing it. ref bug #1538473.
del props[self.FIXED_IPS]
else:
props[self.FIXED_IPS] = []
# delete empty MAC addresses so that Neutron validation code # delete empty MAC addresses so that Neutron validation code
# wouldn't fail as it not accepts Nones # wouldn't fail as it not accepts Nones
if self.ALLOWED_ADDRESS_PAIRS in props: if self.ALLOWED_ADDRESS_PAIRS in props:

View File

@ -56,6 +56,17 @@ resources:
''' '''
neutron_port_with_no_fixed_ips_template = '''
heat_template_version: 2015-04-30
description: Template to test port Neutron resource
resources:
port:
type: OS::Neutron::Port
properties:
network: abcd1234
no_fixed_ips: true
'''
neutron_port_security_template = ''' neutron_port_security_template = '''
heat_template_version: 2015-04-30 heat_template_version: 2015-04-30
description: Template to test port Neutron resource description: Template to test port Neutron resource
@ -224,6 +235,34 @@ class NeutronPortTest(common.HeatTestCase):
'device_owner': '' 'device_owner': ''
}}) }})
def test_no_fixed_ips(self):
t = template_format.parse(neutron_port_with_no_fixed_ips_template)
stack = utils.parse_stack(t)
self.find_mock.return_value = 'abcd1234'
self.create_mock.return_value = {'port': {
"status": "BUILD",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
}}
self.port_show_mock.return_value = {'port': {
"status": "ACTIVE",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
}}
port = stack['port']
scheduler.TaskRunner(port.create)()
self.create_mock.assert_called_once_with({'port': {
'network_id': u'abcd1234',
'name': utils.PhysName(stack.name, 'port'),
'fixed_ips': [],
'admin_state_up': True,
'binding:vnic_type': 'normal',
'device_id': '',
'device_owner': ''
}})
def test_port_security_enabled(self): def test_port_security_enabled(self):
t = template_format.parse(neutron_port_security_template) t = template_format.parse(neutron_port_security_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)

View File

@ -0,0 +1,5 @@
---
features:
- |
Now the ``OS::Neutron::Port`` type supports the ``no_fixed_ips`` property,
which allows users to create a network port without any fixed ips.