murano-deployment/heat-patches/0001-Added-support-for-Allo...

169 lines
6.1 KiB
Diff

From 94350f3206d067e7c9012ac5fb4c40555949d95c Mon Sep 17 00:00:00 2001
From: Timur Sufiev <tsufiev@mirantis.com>
Date: Thu, 5 Dec 2013 19:43:57 +0400
Subject: [PATCH] Added support for Allow-Address-Pairs feature
Added support for feature called Allow-Address-Pairs introduced in
Ie73b3886c5be8e1fc4ade86a0cfb854267f345ac
Implements: blueprint allowed-address-pairs
Ported from: icehouse.
---
heat/engine/resources/neutron/port.py | 19 +++++++-
heat/tests/test_neutron.py | 84 +++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/heat/engine/resources/neutron/port.py b/heat/engine/resources/neutron/port.py
index 06c219a..b12b74a 100644
--- a/heat/engine/resources/neutron/port.py
+++ b/heat/engine/resources/neutron/port.py
@@ -29,6 +29,9 @@ class Port(neutron.NeutronResource):
fixed_ip_schema = {'subnet_id': {'Type': 'String'},
'ip_address': {'Type': 'String'}}
+ address_pair_schema = {'mac_address': {'Type': 'String'},
+ 'ip_address': {'Type': 'String', 'Required': True}}
+
properties_schema = {'network_id': {'Type': 'String',
'Required': True},
'name': {'Type': 'String'},
@@ -41,7 +44,13 @@ class Port(neutron.NeutronResource):
'Schema': fixed_ip_schema}},
'mac_address': {'Type': 'String'},
'device_id': {'Type': 'String'},
- 'security_groups': {'Type': 'List'}}
+ 'security_groups': {'Type': 'List'},
+ 'allowed_address_pairs': {
+ 'Type': 'List',
+ 'Schema': {'Type': 'Map',
+ 'Schema': address_pair_schema}}
+ }
+
attributes_schema = {
"admin_state_up": _("The administrative state of this port."),
"device_id": _("Unique identifier for the device."),
@@ -53,6 +62,8 @@ class Port(neutron.NeutronResource):
"security_groups": _("A list of security groups for the port."),
"status": _("The status of the port."),
"tenant_id": _("Tenant owning the port"),
+ "allowed_address_pairs": _("Additional mac/ip address pairs allowed "
+ "to pass through a port"),
"show": _("All attributes."),
}
@@ -79,6 +90,12 @@ class Port(neutron.NeutronResource):
if value is None:
fixed_ip.pop(key)
+ # delete empty MAC addresses so that Neutron validation code
+ # wouldn't fail as it not accepts Nones
+ for pair in props.get('allowed_address_pairs', []):
+ if 'mac_address' in pair and pair['mac_address'] is None:
+ del pair['mac_address']
+
if self.properties['security_groups']:
props['security_groups'] = self.get_secgroup_uuids(
self.stack, self.properties, 'security_groups', self.name,
diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py
index eb5b295..15d9a2d 100644
--- a/heat/tests/test_neutron.py
+++ b/heat/tests/test_neutron.py
@@ -171,6 +171,26 @@ neutron_port_template = '''
}
'''
+neutron_port_with_address_pair_template = '''
+{
+ "AWSTemplateFormatVersion" : "2010-09-09",
+ "Description" : "Template to test Neutron resources",
+ "Parameters" : {},
+ "Resources" : {
+ "port": {
+ "Type": "OS::Neutron::Port",
+ "Properties": {
+ "network_id": "abcd1234",
+ "allowed_address_pairs": [{
+ "ip_address": "10.0.3.21",
+ "mac_address": "00-B0-D0-86-BB-F7"
+ }]
+ }
+ }
+ }
+}
+'''
+
class NeutronTest(HeatTestCase):
@@ -1147,3 +1167,67 @@ class NeutronPortTest(HeatTestCase):
port = stack['port']
scheduler.TaskRunner(port.create)()
self.m.VerifyAll()
+
+ def test_allowed_address_pair(self):
+ clients.OpenStackClients.keystone().AndReturn(
+ fakes.FakeKeystoneClient())
+ neutronclient.Client.create_port({'port': {
+ 'network_id': u'abcd1234',
+ 'allowed_address_pairs': [{
+ 'ip_address': u'10.0.3.21',
+ 'mac_address': u'00-B0-D0-86-BB-F7'
+ }],
+ 'name': utils.PhysName('test_stack', 'port'),
+ 'admin_state_up': True}}
+ ).AndReturn({'port': {
+ "status": "BUILD",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+ neutronclient.Client.show_port(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndReturn({'port': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+
+ self.m.ReplayAll()
+
+ t = template_format.parse(neutron_port_with_address_pair_template)
+ stack = utils.parse_stack(t)
+
+ port = stack['port']
+ scheduler.TaskRunner(port.create)()
+ self.m.VerifyAll()
+
+ def test_missing_mac_address(self):
+ clients.OpenStackClients.keystone().AndReturn(
+ fakes.FakeKeystoneClient())
+ neutronclient.Client.create_port({'port': {
+ 'network_id': u'abcd1234',
+ 'allowed_address_pairs': [{
+ 'ip_address': u'10.0.3.21',
+ }],
+ 'name': utils.PhysName('test_stack', 'port'),
+ 'admin_state_up': True}}
+ ).AndReturn({'port': {
+ "status": "BUILD",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+ neutronclient.Client.show_port(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndReturn({'port': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+
+ self.m.ReplayAll()
+
+ t = template_format.parse(neutron_port_with_address_pair_template)
+ t['Resources']['port']['Properties']['allowed_address_pairs'][0].pop(
+ 'mac_address'
+ )
+ stack = utils.parse_stack(t)
+
+ port = stack['port']
+ scheduler.TaskRunner(port.create)()
+ self.m.VerifyAll()
--
1.8.3.2