summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-03-25 15:47:15 +0000
committerGerrit Code Review <review@openstack.org>2016-03-25 15:47:15 +0000
commitef1faf77925f70eb9feeb7bb416f4c9257a16bee (patch)
tree463def1234aebf70b56270139c4c4710f031d9d8 /openstackclient
parent860dbc132d512c6df16d29875bb6388d10d9fab8 (diff)
parent2b95e363d325c686db229a9da1d9a3a7677e8294 (diff)
downloadpython-openstackclient-ef1faf77925f70eb9feeb7bb416f4c9257a16bee.tar.gz
Merge "Subnet: Add "subnet set" command using SDK"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/network/v2/subnet.py215
-rw-r--r--openstackclient/tests/network/v2/test_subnet.py74
2 files changed, 209 insertions, 80 deletions
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index 794c787f..da4f6536 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -17,6 +17,7 @@ import copy
from json.encoder import JSONEncoder
from openstackclient.common import command
+from openstackclient.common import exceptions
from openstackclient.common import parseractions
from openstackclient.common import utils
from openstackclient.identity import common as identity_common
@@ -42,6 +43,39 @@ _formatters = {
}
+def _get_common_parse_arguments(parser):
+ parser.add_argument(
+ '--allocation-pool',
+ metavar='start=<ip-address>,end=<ip-address>',
+ dest='allocation_pools',
+ action=parseractions.MultiKeyValueAction,
+ required_keys=['start', 'end'],
+ help='Allocation pool IP addresses for this subnet '
+ 'e.g.: start=192.168.199.2,end=192.168.199.254 '
+ '(This option can be repeated)',
+ )
+ parser.add_argument(
+ '--dns-nameserver',
+ metavar='<dns-nameserver>',
+ action='append',
+ dest='dns_nameservers',
+ help='DNS name server for this subnet '
+ '(This option can be repeated)',
+ )
+ parser.add_argument(
+ '--host-route',
+ metavar='destination=<subnet>,gateway=<ip-address>',
+ dest='host_routes',
+ action=parseractions.MultiKeyValueAction,
+ required_keys=['destination', 'gateway'],
+ help='Additional route for this subnet '
+ 'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
+ 'destination: destination subnet (in CIDR notation) '
+ 'gateway: nexthop IP address '
+ '(This option can be repeated)',
+ )
+
+
def _get_columns(item):
columns = list(item.keys())
if 'tenant_id' in columns:
@@ -70,57 +104,66 @@ def convert_entries_to_gateway(entries):
return changed_entries
-def _get_attrs(client_manager, parsed_args):
+def _get_attrs(client_manager, parsed_args, is_create=True):
attrs = {}
- if parsed_args.name is not None:
+ if 'name' in parsed_args and parsed_args.name is not None:
attrs['name'] = str(parsed_args.name)
- if 'project' in parsed_args and parsed_args.project is not None:
- identity_client = client_manager.identity
- project_id = identity_common.find_project(
- identity_client,
- parsed_args.project,
- parsed_args.project_domain,
- ).id
- attrs['tenant_id'] = project_id
-
- client = client_manager.network
- attrs['network_id'] = client.find_network(parsed_args.network,
- ignore_missing=False).id
-
- if parsed_args.subnet_pool is not None:
- subnet_pool = client.find_subnet_pool(parsed_args.subnet_pool,
- ignore_missing=False)
- attrs['subnetpool_id'] = subnet_pool.id
-
- if parsed_args.use_default_subnet_pool:
- attrs['use_default_subnetpool'] = True
- if parsed_args.gateway.lower() != 'auto':
- if parsed_args.gateway.lower() == 'none':
- attrs['gateway_ip'] = None
- else:
- attrs['gateway_ip'] = parsed_args.gateway
- if parsed_args.prefix_length is not None:
- attrs['prefixlen'] = parsed_args.prefix_length
- if parsed_args.subnet_range is not None:
- attrs['cidr'] = parsed_args.subnet_range
- if parsed_args.ip_version is not None:
- attrs['ip_version'] = parsed_args.ip_version
- if parsed_args.ipv6_ra_mode is not None:
- attrs['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
- if parsed_args.ipv6_address_mode is not None:
- attrs['ipv6_address_mode'] = parsed_args.ipv6_address_mode
- if parsed_args.allocation_pools is not None:
+ if is_create:
+ if 'project' in parsed_args and parsed_args.project is not None:
+ identity_client = client_manager.identity
+ project_id = identity_common.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ attrs['tenant_id'] = project_id
+ client = client_manager.network
+ attrs['network_id'] = client.find_network(parsed_args.network,
+ ignore_missing=False).id
+ if parsed_args.subnet_pool is not None:
+ subnet_pool = client.find_subnet_pool(parsed_args.subnet_pool,
+ ignore_missing=False)
+ attrs['subnetpool_id'] = subnet_pool.id
+ if parsed_args.use_default_subnet_pool:
+ attrs['use_default_subnetpool'] = True
+ if parsed_args.prefix_length is not None:
+ attrs['prefixlen'] = parsed_args.prefix_length
+ if parsed_args.subnet_range is not None:
+ attrs['cidr'] = parsed_args.subnet_range
+ if parsed_args.ip_version is not None:
+ attrs['ip_version'] = parsed_args.ip_version
+ if parsed_args.ipv6_ra_mode is not None:
+ attrs['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
+ if parsed_args.ipv6_address_mode is not None:
+ attrs['ipv6_address_mode'] = parsed_args.ipv6_address_mode
+
+ if 'gateway' in parsed_args and parsed_args.gateway is not None:
+ gateway = parsed_args.gateway.lower()
+
+ if not is_create and gateway == 'auto':
+ raise exceptions.CommandError("Auto option is not available"
+ " for Subnet Set. Valid options are"
+ " <ip-address> or none")
+ elif gateway != 'auto':
+ if gateway == 'none':
+ attrs['gateway_ip'] = None
+ else:
+ attrs['gateway_ip'] = gateway
+ if ('allocation_pools' in parsed_args and
+ parsed_args.allocation_pools is not None):
attrs['allocation_pools'] = parsed_args.allocation_pools
- if parsed_args.enable_dhcp is not None:
- attrs['enable_dhcp'] = parsed_args.enable_dhcp
- if parsed_args.dns_nameservers is not None:
+ if parsed_args.dhcp:
+ attrs['enable_dhcp'] = True
+ elif parsed_args.no_dhcp:
+ attrs['enable_dhcp'] = False
+ if ('dns_nameservers' in parsed_args and
+ parsed_args.dns_nameservers is not None):
attrs['dns_nameservers'] = parsed_args.dns_nameservers
- if parsed_args.host_routes is not None:
+ if 'host_routes' in parsed_args and parsed_args.host_routes is not None:
# Change 'gateway' entry to 'nexthop' to match the API
attrs['host_routes'] = convert_entries_to_nexthop(
parsed_args.host_routes)
-
return attrs
@@ -163,39 +206,19 @@ class CreateSubnet(command.ShowOne):
'(required if --subnet-pool is not specified, '
'optional otherwise)',
)
- parser.add_argument(
- '--allocation-pool',
- metavar='start=<ip-address>,end=<ip-address>',
- dest='allocation_pools',
- action=parseractions.MultiKeyValueAction,
- required_keys=['start', 'end'],
- help='Allocation pool IP addresses for this subnet '
- 'e.g.: start=192.168.199.2,end=192.168.199.254 '
- '(This option can be repeated)',
- )
dhcp_enable_group = parser.add_mutually_exclusive_group()
dhcp_enable_group.add_argument(
'--dhcp',
- dest='enable_dhcp',
action='store_true',
default=True,
help='Enable DHCP (default)',
)
dhcp_enable_group.add_argument(
'--no-dhcp',
- dest='enable_dhcp',
- action='store_false',
+ action='store_true',
help='Disable DHCP',
)
parser.add_argument(
- '--dns-nameserver',
- metavar='<dns-nameserver>',
- action='append',
- dest='dns_nameservers',
- help='DNS name server for this subnet '
- '(This option can be repeated)',
- )
- parser.add_argument(
'--gateway',
metavar='<gateway>',
default='auto',
@@ -208,18 +231,6 @@ class CreateSubnet(command.ShowOne):
"(default is 'auto')",
)
parser.add_argument(
- '--host-route',
- metavar='destination=<subnet>,gateway=<ip-address>',
- dest='host_routes',
- action=parseractions.MultiKeyValueAction,
- required_keys=['destination', 'gateway'],
- help='Additional route for this subnet '
- 'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
- 'destination: destination subnet (in CIDR notation) '
- 'gateway: nexthop IP address '
- '(This option can be repeated)',
- )
- parser.add_argument(
'--ip-version',
type=int,
default=4,
@@ -246,7 +257,7 @@ class CreateSubnet(command.ShowOne):
metavar='<network>',
help='Network this subnet belongs to (name or ID)',
)
-
+ _get_common_parse_arguments(parser)
return parser
def take_action(self, parsed_args):
@@ -309,6 +320,56 @@ class ListSubnet(command.Lister):
) for s in data))
+class SetSubnet(command.Command):
+ """Set subnet properties"""
+
+ def get_parser(self, prog_name):
+ parser = super(SetSubnet, self).get_parser(prog_name)
+ parser.add_argument(
+ 'subnet',
+ metavar="<subnet>",
+ help=("Subnet to modify (name or ID)")
+ )
+ parser.add_argument(
+ '--name',
+ metavar='<name>',
+ help='Updated name of the subnet',
+ )
+ dhcp_enable_group = parser.add_mutually_exclusive_group()
+ dhcp_enable_group.add_argument(
+ '--dhcp',
+ action='store_true',
+ default=None,
+ help='Enable DHCP',
+ )
+ dhcp_enable_group.add_argument(
+ '--no-dhcp',
+ action='store_true',
+ help='Disable DHCP',
+ )
+ parser.add_argument(
+ '--gateway',
+ metavar='<gateway>',
+ help="Specify a gateway for the subnet. The options are: "
+ " <ip-address>: Specific IP address to use as the gateway "
+ " 'none': This subnet will not use a gateway "
+ "e.g.: --gateway 192.168.9.1, --gateway none"
+ )
+ _get_common_parse_arguments(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
+ attrs = _get_attrs(self.app.client_manager, parsed_args,
+ is_create=False)
+ if not attrs:
+ msg = "Nothing specified to be set"
+ raise exceptions.CommandError(msg)
+ client.update_subnet(obj, **attrs)
+ return
+
+
class ShowSubnet(command.ShowOne):
"""Show subnet details"""
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
index de17c789..2535bbe6 100644
--- a/openstackclient/tests/network/v2/test_subnet.py
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -14,6 +14,7 @@
import copy
import mock
+from openstackclient.common import exceptions
from openstackclient.common import utils
from openstackclient.network.v2 import subnet as subnet_v2
from openstackclient.tests import fakes
@@ -203,9 +204,9 @@ class TestCreateSubnet(TestSubnet):
self.network.find_network = mock.Mock(return_value=self._network)
arglist = [
- self._subnet.name,
"--subnet-range", self._subnet.cidr,
"--network", self._subnet.network_id,
+ self._subnet.name,
]
verifylist = [
('name', self._subnet.name),
@@ -266,7 +267,7 @@ class TestCreateSubnet(TestSubnet):
('ip_version', self._subnet_from_pool.ip_version),
('gateway', self._subnet_from_pool.gateway_ip),
('dns_nameservers', self._subnet_from_pool.dns_nameservers),
- ('enable_dhcp', self._subnet_from_pool.enable_dhcp),
+ ('dhcp', self._subnet_from_pool.enable_dhcp),
('host_routes', subnet_v2.convert_entries_to_gateway(
self._subnet_from_pool.host_routes)),
('subnet_pool', self._subnet_from_pool.subnetpool_id),
@@ -332,7 +333,7 @@ class TestCreateSubnet(TestSubnet):
('ipv6_address_mode', self._subnet_ipv6.ipv6_address_mode),
('gateway', self._subnet_ipv6.gateway_ip),
('dns_nameservers', self._subnet_ipv6.dns_nameservers),
- ('enable_dhcp', self._subnet_ipv6.enable_dhcp),
+ ('dhcp', self._subnet_ipv6.enable_dhcp),
('host_routes', subnet_v2.convert_entries_to_gateway(
self._subnet_ipv6.host_routes)),
('allocation_pools', self._subnet_ipv6.allocation_pools),
@@ -469,6 +470,73 @@ class TestListSubnet(TestSubnet):
self.assertEqual(self.data_long, list(data))
+class TestSetSubnet(TestSubnet):
+
+ _subnet = network_fakes.FakeSubnet.create_one_subnet()
+
+ def setUp(self):
+ super(TestSetSubnet, self).setUp()
+ self.network.update_subnet = mock.Mock(return_value=None)
+ self.network.find_subnet = mock.Mock(return_value=self._subnet)
+ self.cmd = subnet_v2.SetSubnet(self.app, self.namespace)
+
+ def test_set_this(self):
+ arglist = [
+ "--name", "new_subnet",
+ "--dhcp",
+ "--gateway", self._subnet.gateway_ip,
+ self._subnet.name,
+ ]
+ verifylist = [
+ ('name', "new_subnet"),
+ ('dhcp', True),
+ ('gateway', self._subnet.gateway_ip),
+ ('subnet', self._subnet.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ attrs = {
+ 'enable_dhcp': True,
+ 'gateway_ip': self._subnet.gateway_ip,
+ 'name': "new_subnet",
+ }
+ self.network.update_subnet.assert_called_with(self._subnet, **attrs)
+ self.assertIsNone(result)
+
+ def test_set_that(self):
+ arglist = [
+ "--name", "new_subnet",
+ "--no-dhcp",
+ "--gateway", "none",
+ self._subnet.name,
+ ]
+ verifylist = [
+ ('name', "new_subnet"),
+ ('no_dhcp', True),
+ ('gateway', "none"),
+ ('subnet', self._subnet.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ attrs = {
+ 'enable_dhcp': False,
+ 'gateway_ip': None,
+ 'name': "new_subnet",
+ }
+ self.network.update_subnet.assert_called_with(self._subnet, **attrs)
+ self.assertIsNone(result)
+
+ def test_set_nothing(self):
+ arglist = [self._subnet.name, ]
+ verifylist = [('subnet', self._subnet.name)]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+
class TestShowSubnet(TestSubnet):
# The subnets to be shown
_subnet = network_fakes.FakeSubnet.create_one_subnet()