From 8d4c0e4ac2e52af0e1ec4952f31aed851d1815e9 Mon Sep 17 00:00:00 2001 From: Miguel Lavalle Date: Sat, 20 Feb 2016 01:04:36 +0000 Subject: [PATCH] Add DNS integration support to the client DNS integration has been added to Neutron. This commit complements that by adding --dns-name and --dns-domain arguments to create and update commands of networks, ports and floating IPs. Change-Id: I7a6ec05b6d7483fceb35f586ac476e8713904b59 Closes-Bug: #1547736 --- neutronclient/neutron/v2_0/dns.py | 67 +++++++++++++++++++ neutronclient/neutron/v2_0/floatingip.py | 5 ++ neutronclient/neutron/v2_0/network.py | 5 ++ neutronclient/neutron/v2_0/port.py | 5 ++ .../tests/unit/test_cli20_floatingips.py | 15 +++++ .../tests/unit/test_cli20_network.py | 29 ++++++++ neutronclient/tests/unit/test_cli20_port.py | 30 +++++++++ 7 files changed, 156 insertions(+) create mode 100644 neutronclient/neutron/v2_0/dns.py diff --git a/neutronclient/neutron/v2_0/dns.py b/neutronclient/neutron/v2_0/dns.py new file mode 100644 index 000000000..0cf7ec0b4 --- /dev/null +++ b/neutronclient/neutron/v2_0/dns.py @@ -0,0 +1,67 @@ +# Copyright (c) 2016 IBM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutronclient._i18n import _ + + +def add_dns_argument_create(parser, resource, attribute): + # Add dns_name and dns_domain support to network, port and floatingip + # create + argument = '--dns-%s' % attribute + parser.add_argument( + argument, + help=_('Assign DNS %(attribute)s to the %(resource)s ' + '(requires DNS integration ' + 'extension)') % {'attribute': attribute, 'resource': resource}) + + +def args2body_dns_create(parsed_args, resource, attribute): + # Add dns_name and dns_domain support to network, port and floatingip + # create + destination = 'dns_%s' % attribute + argument = getattr(parsed_args, destination) + if argument: + resource[destination] = argument + + +def add_dns_argument_update(parser, resource, attribute): + # Add dns_name and dns_domain support to network, port and floatingip + # update + argument = '--dns-%s' % attribute + no_argument = '--no-dns-%s' % attribute + dns_args = parser.add_mutually_exclusive_group() + dns_args.add_argument( + argument, + help=_('Assign DNS %(attribute)s to the %(resource)s ' + '(requires DNS integration ' + 'extension.)') % {'attribute': attribute, 'resource': resource}) + dns_args.add_argument( + no_argument, action='store_true', + help=_('Unassign DNS %(attribute)s from the %(resource)s ' + '(requires DNS integration ' + 'extension.)') % {'attribute': attribute, 'resource': resource}) + + +def args2body_dns_update(parsed_args, resource, attribute): + # Add dns_name and dns_domain support to network, port and floatingip + # update + destination = 'dns_%s' % attribute + no_destination = 'no_dns_%s' % attribute + argument = getattr(parsed_args, destination) + no_argument = getattr(parsed_args, no_destination) + if argument: + resource[destination] = argument + if no_argument: + resource[destination] = "" diff --git a/neutronclient/neutron/v2_0/floatingip.py b/neutronclient/neutron/v2_0/floatingip.py index 7e634e9da..e361a293a 100644 --- a/neutronclient/neutron/v2_0/floatingip.py +++ b/neutronclient/neutron/v2_0/floatingip.py @@ -20,6 +20,7 @@ import argparse from neutronclient._i18n import _ from neutronclient.neutron import v2_0 as neutronV20 +from neutronclient.neutron.v2_0 import dns class ListFloatingIP(neutronV20.ListCommand): @@ -68,6 +69,8 @@ class CreateFloatingIP(neutronV20.CreateCommand): '--subnet', dest='subnet_id', help=_('Subnet ID on which you want to create the floating IP.')) + dns.add_dns_argument_create(parser, self.resource, 'domain') + dns.add_dns_argument_create(parser, self.resource, 'name') def args2body(self, parsed_args): _network_id = neutronV20.find_resourceid_by_name_or_id( @@ -77,6 +80,8 @@ class CreateFloatingIP(neutronV20.CreateCommand): ['port_id', 'tenant_id', 'fixed_ip_address', 'floating_ip_address', 'subnet_id']) + dns.args2body_dns_create(parsed_args, body, 'domain') + dns.args2body_dns_create(parsed_args, body, 'name') return {self.resource: body} diff --git a/neutronclient/neutron/v2_0/network.py b/neutronclient/neutron/v2_0/network.py index e5ac3bd7b..2fb26d327 100644 --- a/neutronclient/neutron/v2_0/network.py +++ b/neutronclient/neutron/v2_0/network.py @@ -21,6 +21,7 @@ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.neutron.v2_0 import availability_zone +from neutronclient.neutron.v2_0 import dns from neutronclient.neutron.v2_0.qos import policy as qos_policy @@ -165,6 +166,7 @@ class CreateNetwork(neutronV20.CreateCommand, qos_policy.CreateQosPolicyMixin): self.add_arguments_qos_policy(parser) availability_zone.add_az_hint_argument(parser, self.resource) + dns.add_dns_argument_create(parser, self.resource, 'domain') def args2body(self, parsed_args): body = {'name': parsed_args.name, @@ -178,6 +180,7 @@ class CreateNetwork(neutronV20.CreateCommand, qos_policy.CreateQosPolicyMixin): self.args2body_qos_policy(parsed_args, body) availability_zone.args2body_az_hint(parsed_args, body) + dns.args2body_dns_create(parsed_args, body, 'domain') return {'network': body} @@ -195,8 +198,10 @@ class UpdateNetwork(neutronV20.UpdateCommand, qos_policy.UpdateQosPolicyMixin): def add_known_arguments(self, parser): self.add_arguments_qos_policy(parser) + dns.add_dns_argument_update(parser, self.resource, 'domain') def args2body(self, parsed_args): body = {} self.args2body_qos_policy(parsed_args, body) + dns.args2body_dns_update(parsed_args, body, 'domain') return {'network': body} diff --git a/neutronclient/neutron/v2_0/port.py b/neutronclient/neutron/v2_0/port.py index 0e27cd227..29426ee58 100644 --- a/neutronclient/neutron/v2_0/port.py +++ b/neutronclient/neutron/v2_0/port.py @@ -22,6 +22,7 @@ from neutronclient._i18n import _ from neutronclient.common import exceptions from neutronclient.common import utils from neutronclient.neutron import v2_0 as neutronV20 +from neutronclient.neutron.v2_0 import dns from neutronclient.neutron.v2_0.qos import policy as qos_policy @@ -263,6 +264,7 @@ class CreatePort(neutronV20.CreateCommand, UpdatePortSecGroupMixin, parser.add_argument( 'network_id', metavar='NETWORK', help=_('Network ID or name this port belongs to.')) + dns.add_dns_argument_create(parser, self.resource, 'name') def args2body(self, parsed_args): client = self.get_client() @@ -283,6 +285,7 @@ class CreatePort(neutronV20.CreateCommand, UpdatePortSecGroupMixin, self.args2body_extradhcpopt(parsed_args, body) self.args2body_qos_policy(parsed_args, body) self.args2body_allowedaddresspairs(parsed_args, body) + dns.args2body_dns_create(parsed_args, body, 'name') return {'port': body} @@ -314,6 +317,7 @@ class UpdatePort(neutronV20.UpdateCommand, UpdatePortSecGroupMixin, self.add_arguments_extradhcpopt(parser) self.add_arguments_qos_policy(parser) self.add_arguments_allowedaddresspairs(parser) + dns.add_dns_argument_update(parser, self.resource, 'name') def args2body(self, parsed_args): body = {} @@ -326,5 +330,6 @@ class UpdatePort(neutronV20.UpdateCommand, UpdatePortSecGroupMixin, self.args2body_extradhcpopt(parsed_args, body) self.args2body_qos_policy(parsed_args, body) self.args2body_allowedaddresspairs(parsed_args, body) + dns.args2body_dns_update(parsed_args, body, 'name') return {'port': body} diff --git a/neutronclient/tests/unit/test_cli20_floatingips.py b/neutronclient/tests/unit/test_cli20_floatingips.py index d500af811..cca3706ce 100644 --- a/neutronclient/tests/unit/test_cli20_floatingips.py +++ b/neutronclient/tests/unit/test_cli20_floatingips.py @@ -117,6 +117,21 @@ class CLITestV20FloatingIpsJSON(test_cli20.CLITestV20Base): self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) + def test_create_floatingip_with_dns_name_and_dns_domain(self): + # Create floatingip: fip1 with dns name and dns domain. + resource = 'floatingip' + cmd = fip.CreateFloatingIP(test_cli20.MyApp(sys.stdout), None) + name = 'fip1' + myid = 'myid' + dns_name_name = 'my-floatingip' + dns_domain_name = 'my-domain.org.' + args = [name, '--dns-name', dns_name_name, '--dns-domain', + dns_domain_name] + position_names = ['floating_network_id', 'dns_name', 'dns_domain'] + position_values = [name, dns_name_name, dns_domain_name] + self._test_create_resource(resource, cmd, name, myid, args, + position_names, position_values) + def test_list_floatingips(self): # list floatingips: -D. resources = 'floatingips' diff --git a/neutronclient/tests/unit/test_cli20_network.py b/neutronclient/tests/unit/test_cli20_network.py index 0465b88dd..dc8fd72ae 100644 --- a/neutronclient/tests/unit/test_cli20_network.py +++ b/neutronclient/tests/unit/test_cli20_network.py @@ -163,6 +163,19 @@ class CLITestV20NetworkJSON(test_cli20.CLITestV20Base): self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) + def test_create_network_with_dns_domain(self): + # Create net: --dns-domain my-domain.org. + resource = 'network' + cmd = network.CreateNetwork(test_cli20.MyApp(sys.stdout), None) + name = 'myname' + myid = 'myid' + dns_domain_name = 'my-domain.org.' + args = [name, '--dns-domain', dns_domain_name] + position_names = ['name', 'dns_domain'] + position_values = [name, dns_domain_name] + self._test_create_resource(resource, cmd, name, myid, args, + position_names, position_values) + def test_list_nets_empty_with_column(self): resources = "networks" cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) @@ -528,6 +541,22 @@ class CLITestV20NetworkJSON(test_cli20.CLITestV20Base): ['myid', '--no-qos-policy'], {'qos_policy_id': None, }) + def test_update_network_with_dns_domain(self): + # Update net: myid --dns-domain my-domain.org. + resource = 'network' + cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) + self._test_update_resource(resource, cmd, 'myid', + ['myid', '--dns-domain', 'my-domain.org.'], + {'dns_domain': 'my-domain.org.', }) + + def test_update_network_with_no_dns_domain(self): + # Update net: myid --no-dns-domain + resource = 'network' + cmd = network.UpdateNetwork(test_cli20.MyApp(sys.stdout), None) + self._test_update_resource(resource, cmd, 'myid', + ['myid', '--no-dns-domain'], + {'dns_domain': "", }) + def test_show_network(self): # Show net: --fields id --fields name myid. resource = 'network' diff --git a/neutronclient/tests/unit/test_cli20_port.py b/neutronclient/tests/unit/test_cli20_port.py index 4b6d617f7..8f502ebae 100644 --- a/neutronclient/tests/unit/test_cli20_port.py +++ b/neutronclient/tests/unit/test_cli20_port.py @@ -338,6 +338,20 @@ class CLITestV20PortJSON(test_cli20.CLITestV20Base): self._test_create_resource(resource, cmd, name, myid, args, position_names, position_values) + def test_create_port_with_dns_name(self): + # Create port: --dns-name my-port. + resource = 'port' + cmd = port.CreatePort(test_cli20.MyApp(sys.stdout), None) + name = 'myname' + myid = 'myid' + netid = 'netid' + dns_name_name = 'my-port' + args = [netid, '--dns-name', dns_name_name] + position_names = ['network_id', 'dns_name'] + position_values = [netid, dns_name_name] + self._test_create_resource(resource, cmd, name, myid, args, + position_names, position_values) + def test_create_port_with_allowed_address_pair_ipaddr(self): # Create port: # --allowed-address-pair ip_address=addr0 @@ -648,6 +662,22 @@ class CLITestV20PortJSON(test_cli20.CLITestV20Base): ['myid', '--no-qos-policy'], {'qos_policy_id': None, }) + def test_update_port_with_dns_name(self): + # Update port: myid --dns-name my-port. + resource = 'port' + cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) + self._test_update_resource(resource, cmd, 'myid', + ['myid', '--dns-name', 'my-port'], + {'dns_name': 'my-port', }) + + def test_update_port_with_no_dns_name(self): + # Update port: myid --no-dns-name + resource = 'port' + cmd = port.UpdatePort(test_cli20.MyApp(sys.stdout), None) + self._test_update_resource(resource, cmd, 'myid', + ['myid', '--no-dns-name'], + {'dns_name': "", }) + def test_delete_extra_dhcp_opts_from_port(self): resource = 'port' myid = 'myid'