diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py index e1b43633fa..8ebd63c709 100644 --- a/heat/engine/resources/openstack/nova/server.py +++ b/heat/engine/resources/openstack/nova/server.py @@ -1269,6 +1269,18 @@ class Server(stack_user.StackUser): for network in networks: networks_with_port = (networks_with_port or network.get(self.NETWORK_PORT)) + if (network.get(self.NETWORK_ID) is None + and network.get(self.NETWORK_PORT) is None + and network.get(self.NETWORK_UUID) is None): + msg = _('One of the properties "%(id)s", "%(port_id)s", ' + '"%(uuid)s" should be set for the ' + 'specified network of server "%(server)s".' + '') % dict(id=self.NETWORK_ID, + port_id=self.NETWORK_PORT, + uuid=self.NETWORK_UUID, + server=self.name) + raise exception.StackValidationFailed(message=msg) + if network.get(self.NETWORK_UUID) and network.get(self.NETWORK_ID): msg = _('Properties "%(uuid)s" and "%(id)s" are both set ' 'to the network "%(network)s" for the server ' diff --git a/heat/tests/test_server.py b/heat/tests/test_server.py index 9405449ec6..ebc9a77da0 100644 --- a/heat/tests/test_server.py +++ b/heat/tests/test_server.py @@ -1076,6 +1076,111 @@ class ServersTest(common.HeatTestCase): six.text_type(ex)) self.m.VerifyAll() + def test_server_validate_with_network_empty_ref(self): + stack_name = 'srv_net' + (tmpl, stack) = self._setup_test_stack(stack_name) + tmpl['Resources']['WebServer']['Properties']['networks'] = ( + [{'network': ''}]) + + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('server_validate_with_networks', + resource_defns['WebServer'], stack) + + self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') + nova.NovaClientPlugin._create().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.stub_NetworkConstraint_validate() + self.m.ReplayAll() + + self.assertIsNone(server.validate()) + self.m.VerifyAll() + + def test_server_validate_with_only_fixed_ip(self): + stack_name = 'srv_net' + (tmpl, stack) = self._setup_test_stack(stack_name) + # create an server with 'uuid' and 'network' properties + tmpl['Resources']['WebServer']['Properties']['networks'] = ( + [{'fixed_ip': '10.0.0.99'}]) + + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('server_validate_with_networks', + resource_defns['WebServer'], stack) + + self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') + nova.NovaClientPlugin._create().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.stub_NetworkConstraint_validate() + self.m.ReplayAll() + + ex = self.assertRaises(exception.StackValidationFailed, + server.validate) + self.assertIn(_('One of the properties "network", "port", "uuid" ' + 'should be set for the specified network of server ' + '"%s".') % server.name, + six.text_type(ex)) + self.m.VerifyAll() + + def test_server_validate_with_port_fixed_ip(self): + stack_name = 'srv_net' + (tmpl, stack) = self._setup_test_stack(stack_name) + tmpl['Resources']['WebServer']['Properties']['networks'] = ( + [{'port': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + 'fixed_ip': '10.0.0.99'}]) + + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('server_validate_with_networks', + resource_defns['WebServer'], stack) + + self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') + nova.NovaClientPlugin._create().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.stub_NetworkConstraint_validate() + self.stub_PortConstraint_validate() + self.m.ReplayAll() + + self.assertIsNone(server.validate()) + self.m.VerifyAll() + + def test_server_validate_with_uuid_fixed_ip(self): + stack_name = 'srv_net' + (tmpl, stack) = self._setup_test_stack(stack_name) + tmpl['Resources']['WebServer']['Properties']['networks'] = ( + [{'uuid': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + 'fixed_ip': '10.0.0.99'}]) + + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('server_validate_with_networks', + resource_defns['WebServer'], stack) + + self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') + nova.NovaClientPlugin._create().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.stub_NetworkConstraint_validate() + self.m.ReplayAll() + + self.assertIsNone(server.validate()) + self.m.VerifyAll() + + def test_server_validate_with_network_fixed_ip(self): + stack_name = 'srv_net' + (tmpl, stack) = self._setup_test_stack(stack_name) + tmpl['Resources']['WebServer']['Properties']['networks'] = ( + [{'network': 'public', + 'fixed_ip': '10.0.0.99'}]) + + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('server_validate_with_networks', + resource_defns['WebServer'], stack) + + self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') + nova.NovaClientPlugin._create().AndReturn(self.fc) + self._mock_get_image_id_success('F17-x86_64-gold', 'image_id') + self.stub_NetworkConstraint_validate() + self.m.ReplayAll() + + self.assertIsNone(server.validate()) + self.m.VerifyAll() + def test_server_validate_net_security_groups(self): # Test that if network 'ports' are assigned security groups are # not, because they'll be ignored