diff --git a/heat/engine/resources/aws/ec2/network_interface.py b/heat/engine/resources/aws/ec2/network_interface.py index cbb756755..7cb95a5b0 100644 --- a/heat/engine/resources/aws/ec2/network_interface.py +++ b/heat/engine/resources/aws/ec2/network_interface.py @@ -13,6 +13,7 @@ from heat.common.i18n import _ from heat.engine import attributes +from heat.engine import constraints from heat.engine import properties from heat.engine import resource @@ -60,7 +61,10 @@ class NetworkInterface(resource.Resource): SUBNET_ID: properties.Schema( properties.Schema.STRING, _('Subnet ID to associate with this interface.'), - required=True + required=True, + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), TAGS: properties.Schema( properties.Schema.LIST, diff --git a/heat/engine/resources/aws/ec2/route_table.py b/heat/engine/resources/aws/ec2/route_table.py index a3b0de6dd..2557da204 100644 --- a/heat/engine/resources/aws/ec2/route_table.py +++ b/heat/engine/resources/aws/ec2/route_table.py @@ -12,6 +12,7 @@ # under the License. from heat.common.i18n import _ +from heat.engine import constraints from heat.engine import properties from heat.engine import resource from heat.engine.resources.aws.ec2 import vpc @@ -120,7 +121,10 @@ class SubnetRouteTableAssociation(resource.Resource): SUBNET_ID: properties.Schema( properties.Schema.STRING, _('Subnet ID.'), - required=True + required=True, + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), } diff --git a/heat/engine/resources/openstack/neutron/loadbalancer.py b/heat/engine/resources/openstack/neutron/loadbalancer.py index b5052f803..645e72c7c 100644 --- a/heat/engine/resources/openstack/neutron/loadbalancer.py +++ b/heat/engine/resources/openstack/neutron/loadbalancer.py @@ -215,14 +215,20 @@ class Pool(neutron.NeutronResource): support_status=support.SupportStatus( support.DEPRECATED, _('Use property %s.') % SUBNET), - required=False + required=False, + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), SUBNET: properties.Schema( properties.Schema.STRING, _('The subnet for the port on which the members ' 'of the pool will be connected.'), 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( properties.Schema.STRING, @@ -264,7 +270,10 @@ class Pool(neutron.NeutronResource): ), VIP_SUBNET: properties.Schema( properties.Schema.STRING, - _('Subnet of the vip.') + _('Subnet of the vip.'), + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), VIP_ADDRESS: properties.Schema( properties.Schema.STRING, diff --git a/heat/engine/resources/openstack/neutron/port.py b/heat/engine/resources/openstack/neutron/port.py index 803beff03..4d16717c9 100644 --- a/heat/engine/resources/openstack/neutron/port.py +++ b/heat/engine/resources/openstack/neutron/port.py @@ -110,13 +110,19 @@ class Port(neutron.NeutronResource): properties.Schema.STRING, support_status=support.SupportStatus( support.DEPRECATED, - _('Use property %s.') % FIXED_IP_SUBNET) + _('Use property %s.') % FIXED_IP_SUBNET), + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), FIXED_IP_SUBNET: properties.Schema( properties.Schema.STRING, _('Subnet in which to allocate the IP address for ' '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( properties.Schema.STRING, diff --git a/heat/engine/resources/openstack/neutron/router.py b/heat/engine/resources/openstack/neutron/router.py index ba3913d10..6e7a47c2c 100644 --- a/heat/engine/resources/openstack/neutron/router.py +++ b/heat/engine/resources/openstack/neutron/router.py @@ -276,12 +276,18 @@ class RouterInterface(neutron.NeutronResource): properties.Schema.STRING, support_status=support.SupportStatus( support.DEPRECATED, - _('Use property %s.') % SUBNET) + _('Use property %s.') % SUBNET), + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), SUBNET: properties.Schema( properties.Schema.STRING, _('The subnet, either subnet or port should be ' - 'specified.') + 'specified.'), + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), PORT_ID: properties.Schema( properties.Schema.STRING, diff --git a/heat/engine/resources/openstack/neutron/vpnservice.py b/heat/engine/resources/openstack/neutron/vpnservice.py index 58853423a..fa808f78e 100644 --- a/heat/engine/resources/openstack/neutron/vpnservice.py +++ b/heat/engine/resources/openstack/neutron/vpnservice.py @@ -62,13 +62,19 @@ class VPNService(neutron.NeutronResource): support_status=support.SupportStatus( support.DEPRECATED, _('Use property %s.') % SUBNET), - required=False + required=False, + constraints=[ + constraints.CustomConstraint('neutron.subnet') + ] ), SUBNET: properties.Schema( properties.Schema.STRING, _('Subnet in which the vpn service will be created.'), 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( properties.Schema.STRING, diff --git a/heat/tests/common.py b/heat/tests/common.py index f27a4baf9..fd712f6f7 100644 --- a/heat/tests/common.py +++ b/heat/tests/common.py @@ -196,3 +196,7 @@ class HeatTestCase(testscenarios.WithScenarios, def stub_TroveFlavorConstraint_validate(self): validate = self.patchobject(trove.FlavorConstraint, 'validate') validate.return_value = True + + def stub_SubnetConstraint_validate(self): + validate = self.patchobject(neutron.SubnetConstraint, 'validate') + validate.return_value = True diff --git a/heat/tests/test_instance_network.py b/heat/tests/test_instance_network.py index 84c6c006c..307a34ee4 100644 --- a/heat/tests/test_instance_network.py +++ b/heat/tests/test_instance_network.py @@ -216,7 +216,7 @@ class instancesTest(common.HeatTestCase): nova.NovaClientPlugin._create().AndReturn(self.fc) self._mock_get_image_id_success(image_id, 1) - + self.stub_SubnetConstraint_validate() self.m.StubOutWithMock(instance, 'neutron') instance.neutron().MultipleTimes().AndReturn(FakeNeutron()) @@ -273,6 +273,7 @@ class instancesTest(common.HeatTestCase): metadata = instance.metadata_get() self._mock_get_image_id_success(image_id, 1) + self.stub_SubnetConstraint_validate() self.m.StubOutWithMock(nic, 'neutron') nic.neutron().MultipleTimes().AndReturn(FakeNeutron()) diff --git a/heat/tests/test_network_interface.py b/heat/tests/test_network_interface.py index df8e0fb18..0cfe9dfb1 100644 --- a/heat/tests/test_network_interface.py +++ b/heat/tests/test_network_interface.py @@ -114,6 +114,7 @@ class NetworkInterfaceTest(common.HeatTestCase): nic_rsrc = my_stack['my_nic'] self.mock_show_subnet() + self.stub_SubnetConstraint_validate() self.mock_create_network_interface() update_props = {} diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py index f703e4184..5e3f75541 100644 --- a/heat/tests/test_neutron.py +++ b/heat/tests/test_neutron.py @@ -1783,7 +1783,7 @@ class NeutronRouterTest(common.HeatTestCase): stack = utils.parse_stack(t) subnet_key = 'subnet_id' router_key = 'router_id' - + self.stub_SubnetConstraint_validate() if resolve_router: neutronV20.find_resourceid_by_name_or_id( mox.IsA(neutronclient.Client), @@ -1811,6 +1811,7 @@ class NeutronRouterTest(common.HeatTestCase): self.m.VerifyAll() def test_router_interface_with_old_data(self): + self.stub_SubnetConstraint_validate() neutronclient.Client.add_interface_router( '3e46229d-8fce-4733-819a-b5fe630550f8', {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'} @@ -2281,6 +2282,7 @@ class NeutronFloatingIPTest(common.HeatTestCase): def test_port(self): self.stub_NetworkConstraint_validate() + self.stub_SubnetConstraint_validate() neutronV20.find_resourceid_by_name_or_id( mox.IsA(neutronclient.Client), 'network', @@ -2393,7 +2395,7 @@ class NeutronFloatingIPTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub1234' - ).AndReturn('sub1234') + ).MultipleTimes().AndReturn('sub1234') neutronclient.Client.create_floatingip({ 'floatingip': {'floating_network_id': u'abcd1234'} }).AndReturn({'floatingip': { @@ -2575,7 +2577,7 @@ class NeutronFloatingIPTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub1234' - ).AndReturn('sub1234') + ).MultipleTimes().AndReturn('sub1234') neutronclient.Client.create_port({'port': { 'network_id': u'xyz1234', 'fixed_ips': [ @@ -2745,7 +2747,7 @@ class NeutronPortTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub1234' - ).AndReturn('sub1234') + ).MultipleTimes().AndReturn('sub1234') neutronclient.Client.create_port({'port': { 'network_id': u'net1234', @@ -2892,7 +2894,7 @@ class NeutronPortTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub1234' - ).AndReturn('sub1234') + ).MultipleTimes().AndReturn('sub1234') neutronclient.Client.create_port({'port': port_prop}).AndReturn( {'port': { "status": "BUILD", @@ -3256,7 +3258,7 @@ class NeutronPortTest(common.HeatTestCase): "status": "ACTIVE", "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" }}) - + self.stub_SubnetConstraint_validate() self.stub_NetworkConstraint_validate() neutronclient.Client.update_port( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', diff --git a/heat/tests/test_neutron_loadbalancer.py b/heat/tests/test_neutron_loadbalancer.py index 84145a579..4804a03b4 100644 --- a/heat/tests/test_neutron_loadbalancer.py +++ b/heat/tests/test_neutron_loadbalancer.py @@ -384,6 +384,7 @@ class PoolTest(common.HeatTestCase): stvippsn = copy.deepcopy(stvipvsn) stvippsn['vip']['subnet_id'] = 'sub123' + self.stub_SubnetConstraint_validate() if resolve_neutron and with_vip_subnet: neutronV20.find_resourceid_by_name_or_id( @@ -443,7 +444,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { @@ -483,7 +484,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { @@ -519,7 +520,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { @@ -557,7 +558,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { @@ -585,7 +586,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { 'subnet_id': 'sub123', 'protocol': u'HTTP', @@ -641,15 +642,17 @@ class PoolTest(common.HeatTestCase): stack = utils.parse_stack(snippet) resource_defns = stack.t.resource_definitions(stack) resource = loadbalancer.Pool('pool', resource_defns['pool'], stack) - + self.stub_SubnetConstraint_validate() + self.m.ReplayAll() self.assertIsNone(resource.validate()) + self.m.VerifyAll() def test_properties_are_prepared_for_session_persistence(self): neutronV20.find_resourceid_by_name_or_id( mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { @@ -800,7 +803,7 @@ class PoolTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_pool({ 'pool': { 'subnet_id': 'sub123', 'protocol': u'HTTP', @@ -1063,6 +1066,7 @@ class PoolUpdateHealthMonitorsTest(common.HeatTestCase): 'delay': 3, 'max_retries': 5, 'type': u'HTTP', 'timeout': 10, 'admin_state_up': True}} ).AndReturn({'health_monitor': {'id': '6666'}}) + self.stub_SubnetConstraint_validate() neutronclient.Client.create_pool({ 'pool': { 'subnet_id': 'sub123', 'protocol': u'HTTP', diff --git a/heat/tests/test_neutron_vpnservice.py b/heat/tests/test_neutron_vpnservice.py index 9804e64e4..d1d31ef5d 100644 --- a/heat/tests/test_neutron_vpnservice.py +++ b/heat/tests/test_neutron_vpnservice.py @@ -174,6 +174,7 @@ class VPNServiceTest(common.HeatTestCase): self.stub_keystoneclient() def create_vpnservice(self, resolve_neutron=True, resolve_router=True): + self.stub_SubnetConstraint_validate() if resolve_neutron: neutronV20.find_resourceid_by_name_or_id( mox.IsA(neutronclient.Client), @@ -222,7 +223,7 @@ class VPNServiceTest(common.HeatTestCase): mox.IsA(neutronclient.Client), 'subnet', 'sub123' - ).AndReturn('sub123') + ).MultipleTimes().AndReturn('sub123') neutronclient.Client.create_vpnservice(self.VPN_SERVICE_CONF).AndRaise( exceptions.NeutronClientException()) diff --git a/heat/tests/test_vpc.py b/heat/tests/test_vpc.py index b20c00e80..90e6980a4 100644 --- a/heat/tests/test_vpc.py +++ b/heat/tests/test_vpc.py @@ -643,6 +643,7 @@ Resources: self.mock_create_network() self.mock_create_subnet() self.mock_show_subnet() + self.stub_SubnetConstraint_validate() self.mock_create_network_interface() self.mock_show_network_interface() self.mock_delete_network_interface() @@ -670,6 +671,7 @@ Resources: self.mock_create_network() self.mock_create_subnet() self.mock_show_subnet() + self.stub_SubnetConstraint_validate() self.mock_create_network_interface() self.mock_delete_network_interface() self.mock_delete_subnet() @@ -692,6 +694,7 @@ Resources: self.mock_create_network() self.mock_create_subnet() self.mock_show_subnet() + self.stub_SubnetConstraint_validate() self.mock_create_network_interface(security_groups=None) self.mock_delete_network_interface() self.mock_delete_subnet() @@ -770,6 +773,7 @@ Resources: self.mock_create_network() self.mock_create_subnet() self.mock_create_route_table() + self.stub_SubnetConstraint_validate() self.mock_create_association() self.mock_create_gateway_attachment() self.mock_delete_gateway_attachment() @@ -825,6 +829,7 @@ Resources: self.mock_create_network() self.mock_create_subnet() self.mock_create_route_table() + self.stub_SubnetConstraint_validate() self.mock_create_association() self.mock_delete_association() self.mock_delete_route_table()