diff --git a/heat/engine/resources/openstack/neutron/floatingip.py b/heat/engine/resources/openstack/neutron/floatingip.py index 16c3b97691..723783ccaf 100644 --- a/heat/engine/resources/openstack/neutron/floatingip.py +++ b/heat/engine/resources/openstack/neutron/floatingip.py @@ -37,9 +37,11 @@ class FloatingIP(neutron.NeutronResource): PROPERTIES = ( FLOATING_NETWORK_ID, FLOATING_NETWORK, VALUE_SPECS, PORT_ID, FIXED_IP_ADDRESS, FLOATING_IP_ADDRESS, + DNS_NAME, DNS_DOMAIN, ) = ( 'floating_network_id', 'floating_network', 'value_specs', 'port_id', 'fixed_ip_address', 'floating_ip_address', + 'dns_name', 'dns_domain', ) ATTRIBUTES = ( @@ -109,6 +111,24 @@ class FloatingIP(neutron.NeutronResource): ], support_status=support.SupportStatus(version='5.0.0'), ), + DNS_NAME: properties.Schema( + properties.Schema.STRING, + _('DNS name associated with floating ip.'), + update_allowed=True, + constraints=[ + constraints.CustomConstraint('rel_dns_name') + ], + support_status=support.SupportStatus(version='7.0.0'), + ), + DNS_DOMAIN: properties.Schema( + properties.Schema.STRING, + _('DNS domain associated with floating ip.'), + update_allowed=True, + constraints=[ + constraints.CustomConstraint('dns_domain') + ], + support_status=support.SupportStatus(version='7.0.0'), + ), } attributes_schema = { diff --git a/heat/engine/resources/openstack/neutron/net.py b/heat/engine/resources/openstack/neutron/net.py index 9febf3a9bd..57043a5e04 100644 --- a/heat/engine/resources/openstack/neutron/net.py +++ b/heat/engine/resources/openstack/neutron/net.py @@ -29,9 +29,11 @@ class Net(neutron.NeutronResource): PROPERTIES = ( NAME, VALUE_SPECS, ADMIN_STATE_UP, TENANT_ID, SHARED, DHCP_AGENT_IDS, PORT_SECURITY_ENABLED, QOS_POLICY, + DNS_DOMAIN, ) = ( 'name', 'value_specs', 'admin_state_up', 'tenant_id', 'shared', 'dhcp_agent_ids', 'port_security_enabled', 'qos_policy', + 'dns_domain', ) ATTRIBUTES = ( @@ -101,6 +103,15 @@ class Net(neutron.NeutronResource): update_allowed=True, support_status=support.SupportStatus(version='6.0.0') ), + DNS_DOMAIN: properties.Schema( + properties.Schema.STRING, + _('DNS domain associated with this network.'), + constraints=[ + constraints.CustomConstraint('dns_domain') + ], + update_allowed=True, + support_status=support.SupportStatus(version='7.0.0') + ), } attributes_schema = { diff --git a/heat/engine/resources/openstack/neutron/port.py b/heat/engine/resources/openstack/neutron/port.py index acf8d6d7e1..687554b1b2 100644 --- a/heat/engine/resources/openstack/neutron/port.py +++ b/heat/engine/resources/openstack/neutron/port.py @@ -42,10 +42,10 @@ class Port(neutron.NeutronResource): PROPERTIES = ( NAME, NETWORK_ID, NETWORK, FIXED_IPS, SECURITY_GROUPS, - REPLACEMENT_POLICY, DEVICE_ID, DEVICE_OWNER + REPLACEMENT_POLICY, DEVICE_ID, DEVICE_OWNER, DNS_NAME, ) = ( 'name', 'network_id', 'network', 'fixed_ips', 'security_groups', - 'replacement_policy', 'device_id', 'device_owner' + 'replacement_policy', 'device_id', 'device_owner', 'dns_name', ) EXTRA_PROPERTIES = ( @@ -74,12 +74,12 @@ class Port(neutron.NeutronResource): ADMIN_STATE_UP_ATTR, DEVICE_ID_ATTR, DEVICE_OWNER_ATTR, FIXED_IPS_ATTR, MAC_ADDRESS_ATTR, NAME_ATTR, NETWORK_ID_ATTR, SECURITY_GROUPS_ATTR, STATUS, TENANT_ID, ALLOWED_ADDRESS_PAIRS_ATTR, SUBNETS_ATTR, - PORT_SECURITY_ENABLED_ATTR, QOS_POLICY_ATTR, + PORT_SECURITY_ENABLED_ATTR, QOS_POLICY_ATTR, DNS_ASSIGNMENT, ) = ( 'admin_state_up', 'device_id', 'device_owner', 'fixed_ips', 'mac_address', 'name', 'network_id', 'security_groups', 'status', 'tenant_id', 'allowed_address_pairs', 'subnets', - 'port_security_enabled', 'qos_policy_id', + 'port_security_enabled', 'qos_policy_id', 'dns_assignment', ) properties_schema = { @@ -194,6 +194,15 @@ class Port(neutron.NeutronResource): 'fixed since Liberty.'), previous_status=support.SupportStatus(version='2014.2')) ), + DNS_NAME: properties.Schema( + properties.Schema.STRING, + _('DNS name associated with the port.'), + update_allowed=True, + constraints=[ + constraints.CustomConstraint('dns_name') + ], + support_status=support.SupportStatus(version='7.0.0'), + ), } # NOTE(prazumovsky): properties_schema has been separated because some @@ -343,6 +352,11 @@ class Port(neutron.NeutronResource): type=attributes.Schema.STRING, support_status=support.SupportStatus(version='6.0.0'), ), + DNS_ASSIGNMENT: attributes.Schema( + _("The DNS assigned to this port."), + type=attributes.Schema.MAP, + support_status=support.SupportStatus(version='7.0.0'), + ), } def translation_rules(self, props): diff --git a/heat/tests/openstack/neutron/test_neutron_floating_ip.py b/heat/tests/openstack/neutron/test_neutron_floating_ip.py index 26a8415574..eff54398ec 100644 --- a/heat/tests/openstack/neutron/test_neutron_floating_ip.py +++ b/heat/tests/openstack/neutron/test_neutron_floating_ip.py @@ -563,6 +563,36 @@ class NeutronFloatingIPTest(common.HeatTestCase): self.m.VerifyAll() + def test_floatingip_create_specify_dns(self): + neutronV20.find_resourceid_by_name_or_id( + mox.IsA(neutronclient.Client), + 'network', + 'abcd1234', + cmd_resource=None, + ).MultipleTimes().AndReturn('abcd1234') + self.stub_NetworkConstraint_validate() + neutronclient.Client.create_floatingip({ + 'floatingip': {'floating_network_id': u'abcd1234', + 'dns_name': 'myvm', + 'dns_domain': 'openstack.org.'} + }).AndReturn({'floatingip': { + 'status': 'ACTIVE', + 'id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', + 'floating_ip_address': '172.24.4.98' + }}) + + self.m.ReplayAll() + t = template_format.parse(neutron_floating_template) + props = t['resources']['floating_ip']['properties'] + props['dns_name'] = 'myvm' + props['dns_domain'] = 'openstack.org.' + stack = utils.parse_stack(t) + fip = stack['floating_ip'] + scheduler.TaskRunner(fip.create)() + self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state) + + self.m.VerifyAll() + def test_floatip_port(self): t = template_format.parse(neutron_floating_no_assoc_template) t['resources']['port_floating']['properties']['network'] = "xyz1234" diff --git a/heat/tests/openstack/neutron/test_neutron_net.py b/heat/tests/openstack/neutron/test_neutron_net.py index 7cde996113..245375fe73 100644 --- a/heat/tests/openstack/neutron/test_neutron_net.py +++ b/heat/tests/openstack/neutron/test_neutron_net.py @@ -40,6 +40,7 @@ resources: dhcp_agent_ids: - 28c25a04-3f73-45a7-a2b4-59e183943ddc port_security_enabled: False + dns_domain: openstack.org. subnet: type: OS::Neutron::Subnet @@ -120,6 +121,7 @@ class NeutronNetTest(common.HeatTestCase): 'admin_state_up': True, 'tenant_id': 'c1210485b2424d48804aad5d39c61b8f', 'port_security_enabled': False, + 'dns_domain': 'openstack.org.', 'shared': True} }).AndReturn({"network": { "status": "BUILD", diff --git a/heat/tests/openstack/neutron/test_neutron_port.py b/heat/tests/openstack/neutron/test_neutron_port.py index ca5e8c0206..e689aea96d 100644 --- a/heat/tests/openstack/neutron/test_neutron_port.py +++ b/heat/tests/openstack/neutron/test_neutron_port.py @@ -339,7 +339,7 @@ class NeutronPortTest(common.HeatTestCase): scheduler.TaskRunner(port.create)() self.m.VerifyAll() - def _mock_create_with_security_groups(self, port_prop): + def _mock_create_with_props(self, port_prop): neutronV20.find_resourceid_by_name_or_id( mox.IsA(neutronclient.Client), 'network', @@ -358,9 +358,14 @@ class NeutronPortTest(common.HeatTestCase): "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"}}) neutronclient.Client.show_port( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' - ).AndReturn({'port': { + ).MultipleTimes().AndReturn({'port': { "status": "ACTIVE", - "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" + "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766", + "dns_assignment": { + "hostname": "my-vm", + "ip_address": "10.0.0.15", + "fqdn": "my-vm.openstack.org."} + }}) self.m.ReplayAll() @@ -383,13 +388,35 @@ class NeutronPortTest(common.HeatTestCase): 'admin_state_up': True, 'device_owner': u'network:dhcp'} - self._mock_create_with_security_groups(port_prop) + self._mock_create_with_props(port_prop) port = stack['port'] scheduler.TaskRunner(port.create)() self.m.VerifyAll() + def test_port_with_dns_name(self): + t = template_format.parse(neutron_port_template) + t['resources']['port']['properties']['dns_name'] = 'myvm' + stack = utils.parse_stack(t) + + port_prop = { + 'network_id': u'net1234', + 'dns_name': 'myvm', + 'fixed_ips': [ + {'subnet_id': u'sub1234', 'ip_address': u'10.0.3.21'} + ], + 'name': utils.PhysName(stack.name, 'port'), + 'admin_state_up': True, + 'device_owner': u'network:dhcp'} + + self._mock_create_with_props(port_prop) + port = stack['port'] + scheduler.TaskRunner(port.create)() + self.assertEqual('my-vm.openstack.org.', + port.FnGetAtt('dns_assignment')['fqdn']) + self.m.VerifyAll() + def test_security_groups_empty_list(self): t = template_format.parse(neutron_port_template) t['resources']['port']['properties']['security_groups'] = [] @@ -406,7 +433,7 @@ class NeutronPortTest(common.HeatTestCase): 'device_owner': u'network:dhcp' } - self._mock_create_with_security_groups(port_prop) + self._mock_create_with_props(port_prop) port = stack['port'] scheduler.TaskRunner(port.create)()