Apply neutron subnet constraint

Apply neutron subnet custom constraint for
resources.

Change-Id: Ia0cf775a1e96848806b7050b434f7813b61db96a
Implements: blueprint apply-neutron-constraints
This commit is contained in:
huangtianhua 2014-11-20 12:10:46 +08:00
parent ecdc6e5543
commit 378ffbf1b7
13 changed files with 80 additions and 27 deletions

View File

@ -13,6 +13,7 @@
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 properties from heat.engine import properties
from heat.engine import resource from heat.engine import resource
@ -60,7 +61,10 @@ class NetworkInterface(resource.Resource):
SUBNET_ID: properties.Schema( SUBNET_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Subnet ID to associate with this interface.'), _('Subnet ID to associate with this interface.'),
required=True required=True,
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
TAGS: properties.Schema( TAGS: properties.Schema(
properties.Schema.LIST, properties.Schema.LIST,

View File

@ -12,6 +12,7 @@
# under the License. # under the License.
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine import constraints
from heat.engine import properties from heat.engine import properties
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.aws.ec2 import vpc from heat.engine.resources.aws.ec2 import vpc
@ -120,7 +121,10 @@ class SubnetRouteTableAssociation(resource.Resource):
SUBNET_ID: properties.Schema( SUBNET_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Subnet ID.'), _('Subnet ID.'),
required=True required=True,
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
} }

View File

@ -215,14 +215,20 @@ class Pool(neutron.NeutronResource):
support_status=support.SupportStatus( support_status=support.SupportStatus(
support.DEPRECATED, support.DEPRECATED,
_('Use property %s.') % SUBNET), _('Use property %s.') % SUBNET),
required=False required=False,
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
SUBNET: properties.Schema( SUBNET: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('The subnet for the port on which the members ' _('The subnet for the port on which the members '
'of the pool will be connected.'), 'of the pool will be connected.'),
required=False, required=False,
support_status=support.SupportStatus(version='2014.2') support_status=support.SupportStatus(version='2014.2'),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
LB_METHOD: properties.Schema( LB_METHOD: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
@ -264,7 +270,10 @@ class Pool(neutron.NeutronResource):
), ),
VIP_SUBNET: properties.Schema( VIP_SUBNET: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Subnet of the vip.') _('Subnet of the vip.'),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
VIP_ADDRESS: properties.Schema( VIP_ADDRESS: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,

View File

@ -110,13 +110,19 @@ class Port(neutron.NeutronResource):
properties.Schema.STRING, properties.Schema.STRING,
support_status=support.SupportStatus( support_status=support.SupportStatus(
support.DEPRECATED, support.DEPRECATED,
_('Use property %s.') % FIXED_IP_SUBNET) _('Use property %s.') % FIXED_IP_SUBNET),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
FIXED_IP_SUBNET: properties.Schema( FIXED_IP_SUBNET: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Subnet in which to allocate the IP address for ' _('Subnet in which to allocate the IP address for '
'this port.'), 'this port.'),
support_status=support.SupportStatus(version='2014.2') support_status=support.SupportStatus(version='2014.2'),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
FIXED_IP_IP_ADDRESS: properties.Schema( FIXED_IP_IP_ADDRESS: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,

View File

@ -276,12 +276,18 @@ class RouterInterface(neutron.NeutronResource):
properties.Schema.STRING, properties.Schema.STRING,
support_status=support.SupportStatus( support_status=support.SupportStatus(
support.DEPRECATED, support.DEPRECATED,
_('Use property %s.') % SUBNET) _('Use property %s.') % SUBNET),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
SUBNET: properties.Schema( SUBNET: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('The subnet, either subnet or port should be ' _('The subnet, either subnet or port should be '
'specified.') 'specified.'),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
PORT_ID: properties.Schema( PORT_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,

View File

@ -62,13 +62,19 @@ class VPNService(neutron.NeutronResource):
support_status=support.SupportStatus( support_status=support.SupportStatus(
support.DEPRECATED, support.DEPRECATED,
_('Use property %s.') % SUBNET), _('Use property %s.') % SUBNET),
required=False required=False,
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
SUBNET: properties.Schema( SUBNET: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Subnet in which the vpn service will be created.'), _('Subnet in which the vpn service will be created.'),
required=False, required=False,
support_status=support.SupportStatus(version='2014.2') support_status=support.SupportStatus(version='2014.2'),
constraints=[
constraints.CustomConstraint('neutron.subnet')
]
), ),
ROUTER_ID: properties.Schema( ROUTER_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,

View File

@ -196,3 +196,7 @@ class HeatTestCase(testscenarios.WithScenarios,
def stub_TroveFlavorConstraint_validate(self): def stub_TroveFlavorConstraint_validate(self):
validate = self.patchobject(trove.FlavorConstraint, 'validate') validate = self.patchobject(trove.FlavorConstraint, 'validate')
validate.return_value = True validate.return_value = True
def stub_SubnetConstraint_validate(self):
validate = self.patchobject(neutron.SubnetConstraint, 'validate')
validate.return_value = True

View File

@ -216,7 +216,7 @@ class instancesTest(common.HeatTestCase):
nova.NovaClientPlugin._create().AndReturn(self.fc) nova.NovaClientPlugin._create().AndReturn(self.fc)
self._mock_get_image_id_success(image_id, 1) self._mock_get_image_id_success(image_id, 1)
self.stub_SubnetConstraint_validate()
self.m.StubOutWithMock(instance, 'neutron') self.m.StubOutWithMock(instance, 'neutron')
instance.neutron().MultipleTimes().AndReturn(FakeNeutron()) instance.neutron().MultipleTimes().AndReturn(FakeNeutron())
@ -273,6 +273,7 @@ class instancesTest(common.HeatTestCase):
metadata = instance.metadata_get() metadata = instance.metadata_get()
self._mock_get_image_id_success(image_id, 1) self._mock_get_image_id_success(image_id, 1)
self.stub_SubnetConstraint_validate()
self.m.StubOutWithMock(nic, 'neutron') self.m.StubOutWithMock(nic, 'neutron')
nic.neutron().MultipleTimes().AndReturn(FakeNeutron()) nic.neutron().MultipleTimes().AndReturn(FakeNeutron())

View File

@ -114,6 +114,7 @@ class NetworkInterfaceTest(common.HeatTestCase):
nic_rsrc = my_stack['my_nic'] nic_rsrc = my_stack['my_nic']
self.mock_show_subnet() self.mock_show_subnet()
self.stub_SubnetConstraint_validate()
self.mock_create_network_interface() self.mock_create_network_interface()
update_props = {} update_props = {}

View File

@ -1783,7 +1783,7 @@ class NeutronRouterTest(common.HeatTestCase):
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
subnet_key = 'subnet_id' subnet_key = 'subnet_id'
router_key = 'router_id' router_key = 'router_id'
self.stub_SubnetConstraint_validate()
if resolve_router: if resolve_router:
neutronV20.find_resourceid_by_name_or_id( neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
@ -1811,6 +1811,7 @@ class NeutronRouterTest(common.HeatTestCase):
self.m.VerifyAll() self.m.VerifyAll()
def test_router_interface_with_old_data(self): def test_router_interface_with_old_data(self):
self.stub_SubnetConstraint_validate()
neutronclient.Client.add_interface_router( neutronclient.Client.add_interface_router(
'3e46229d-8fce-4733-819a-b5fe630550f8', '3e46229d-8fce-4733-819a-b5fe630550f8',
{'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'} {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
@ -2281,6 +2282,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
def test_port(self): def test_port(self):
self.stub_NetworkConstraint_validate() self.stub_NetworkConstraint_validate()
self.stub_SubnetConstraint_validate()
neutronV20.find_resourceid_by_name_or_id( neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'network', 'network',
@ -2393,7 +2395,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub1234' 'sub1234'
).AndReturn('sub1234') ).MultipleTimes().AndReturn('sub1234')
neutronclient.Client.create_floatingip({ neutronclient.Client.create_floatingip({
'floatingip': {'floating_network_id': u'abcd1234'} 'floatingip': {'floating_network_id': u'abcd1234'}
}).AndReturn({'floatingip': { }).AndReturn({'floatingip': {
@ -2575,7 +2577,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub1234' 'sub1234'
).AndReturn('sub1234') ).MultipleTimes().AndReturn('sub1234')
neutronclient.Client.create_port({'port': { neutronclient.Client.create_port({'port': {
'network_id': u'xyz1234', 'network_id': u'xyz1234',
'fixed_ips': [ 'fixed_ips': [
@ -2745,7 +2747,7 @@ class NeutronPortTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub1234' 'sub1234'
).AndReturn('sub1234') ).MultipleTimes().AndReturn('sub1234')
neutronclient.Client.create_port({'port': { neutronclient.Client.create_port({'port': {
'network_id': u'net1234', 'network_id': u'net1234',
@ -2892,7 +2894,7 @@ class NeutronPortTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub1234' 'sub1234'
).AndReturn('sub1234') ).MultipleTimes().AndReturn('sub1234')
neutronclient.Client.create_port({'port': port_prop}).AndReturn( neutronclient.Client.create_port({'port': port_prop}).AndReturn(
{'port': { {'port': {
"status": "BUILD", "status": "BUILD",
@ -3256,7 +3258,7 @@ class NeutronPortTest(common.HeatTestCase):
"status": "ACTIVE", "status": "ACTIVE",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
}}) }})
self.stub_SubnetConstraint_validate()
self.stub_NetworkConstraint_validate() self.stub_NetworkConstraint_validate()
neutronclient.Client.update_port( neutronclient.Client.update_port(
'fc68ea2c-b60b-4b4f-bd82-94ec81110766', 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',

View File

@ -384,6 +384,7 @@ class PoolTest(common.HeatTestCase):
stvippsn = copy.deepcopy(stvipvsn) stvippsn = copy.deepcopy(stvipvsn)
stvippsn['vip']['subnet_id'] = 'sub123' stvippsn['vip']['subnet_id'] = 'sub123'
self.stub_SubnetConstraint_validate()
if resolve_neutron and with_vip_subnet: if resolve_neutron and with_vip_subnet:
neutronV20.find_resourceid_by_name_or_id( neutronV20.find_resourceid_by_name_or_id(
@ -443,7 +444,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
@ -483,7 +484,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
@ -519,7 +520,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
@ -557,7 +558,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
@ -585,7 +586,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
'subnet_id': 'sub123', 'protocol': u'HTTP', 'subnet_id': 'sub123', 'protocol': u'HTTP',
@ -641,15 +642,17 @@ class PoolTest(common.HeatTestCase):
stack = utils.parse_stack(snippet) stack = utils.parse_stack(snippet)
resource_defns = stack.t.resource_definitions(stack) resource_defns = stack.t.resource_definitions(stack)
resource = loadbalancer.Pool('pool', resource_defns['pool'], stack) resource = loadbalancer.Pool('pool', resource_defns['pool'], stack)
self.stub_SubnetConstraint_validate()
self.m.ReplayAll()
self.assertIsNone(resource.validate()) self.assertIsNone(resource.validate())
self.m.VerifyAll()
def test_properties_are_prepared_for_session_persistence(self): def test_properties_are_prepared_for_session_persistence(self):
neutronV20.find_resourceid_by_name_or_id( neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
@ -800,7 +803,7 @@ class PoolTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
'subnet_id': 'sub123', 'protocol': u'HTTP', 'subnet_id': 'sub123', 'protocol': u'HTTP',
@ -1063,6 +1066,7 @@ class PoolUpdateHealthMonitorsTest(common.HeatTestCase):
'delay': 3, 'max_retries': 5, 'type': u'HTTP', 'delay': 3, 'max_retries': 5, 'type': u'HTTP',
'timeout': 10, 'admin_state_up': True}} 'timeout': 10, 'admin_state_up': True}}
).AndReturn({'health_monitor': {'id': '6666'}}) ).AndReturn({'health_monitor': {'id': '6666'}})
self.stub_SubnetConstraint_validate()
neutronclient.Client.create_pool({ neutronclient.Client.create_pool({
'pool': { 'pool': {
'subnet_id': 'sub123', 'protocol': u'HTTP', 'subnet_id': 'sub123', 'protocol': u'HTTP',

View File

@ -174,6 +174,7 @@ class VPNServiceTest(common.HeatTestCase):
self.stub_keystoneclient() self.stub_keystoneclient()
def create_vpnservice(self, resolve_neutron=True, resolve_router=True): def create_vpnservice(self, resolve_neutron=True, resolve_router=True):
self.stub_SubnetConstraint_validate()
if resolve_neutron: if resolve_neutron:
neutronV20.find_resourceid_by_name_or_id( neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
@ -222,7 +223,7 @@ class VPNServiceTest(common.HeatTestCase):
mox.IsA(neutronclient.Client), mox.IsA(neutronclient.Client),
'subnet', 'subnet',
'sub123' 'sub123'
).AndReturn('sub123') ).MultipleTimes().AndReturn('sub123')
neutronclient.Client.create_vpnservice(self.VPN_SERVICE_CONF).AndRaise( neutronclient.Client.create_vpnservice(self.VPN_SERVICE_CONF).AndRaise(
exceptions.NeutronClientException()) exceptions.NeutronClientException())

View File

@ -643,6 +643,7 @@ Resources:
self.mock_create_network() self.mock_create_network()
self.mock_create_subnet() self.mock_create_subnet()
self.mock_show_subnet() self.mock_show_subnet()
self.stub_SubnetConstraint_validate()
self.mock_create_network_interface() self.mock_create_network_interface()
self.mock_show_network_interface() self.mock_show_network_interface()
self.mock_delete_network_interface() self.mock_delete_network_interface()
@ -670,6 +671,7 @@ Resources:
self.mock_create_network() self.mock_create_network()
self.mock_create_subnet() self.mock_create_subnet()
self.mock_show_subnet() self.mock_show_subnet()
self.stub_SubnetConstraint_validate()
self.mock_create_network_interface() self.mock_create_network_interface()
self.mock_delete_network_interface() self.mock_delete_network_interface()
self.mock_delete_subnet() self.mock_delete_subnet()
@ -692,6 +694,7 @@ Resources:
self.mock_create_network() self.mock_create_network()
self.mock_create_subnet() self.mock_create_subnet()
self.mock_show_subnet() self.mock_show_subnet()
self.stub_SubnetConstraint_validate()
self.mock_create_network_interface(security_groups=None) self.mock_create_network_interface(security_groups=None)
self.mock_delete_network_interface() self.mock_delete_network_interface()
self.mock_delete_subnet() self.mock_delete_subnet()
@ -770,6 +773,7 @@ Resources:
self.mock_create_network() self.mock_create_network()
self.mock_create_subnet() self.mock_create_subnet()
self.mock_create_route_table() self.mock_create_route_table()
self.stub_SubnetConstraint_validate()
self.mock_create_association() self.mock_create_association()
self.mock_create_gateway_attachment() self.mock_create_gateway_attachment()
self.mock_delete_gateway_attachment() self.mock_delete_gateway_attachment()
@ -825,6 +829,7 @@ Resources:
self.mock_create_network() self.mock_create_network()
self.mock_create_subnet() self.mock_create_subnet()
self.mock_create_route_table() self.mock_create_route_table()
self.stub_SubnetConstraint_validate()
self.mock_create_association() self.mock_create_association()
self.mock_delete_association() self.mock_delete_association()
self.mock_delete_route_table() self.mock_delete_route_table()