Add command to unset information from Subnets
This patch introduces the ``subnet unset`` command to clear the host-routes, allocation-pools and dns-nameservers from subnets. Implements: blueprint network-property-unset Change-Id: I31324a2423f6d2315eed27445dfdcfe863e0b550
This commit is contained in:
parent
21ac9230e8
commit
45b026d7c8
@ -235,3 +235,41 @@ Display subnet details
|
|||||||
.. describe:: <subnet>
|
.. describe:: <subnet>
|
||||||
|
|
||||||
Subnet to display (name or ID)
|
Subnet to display (name or ID)
|
||||||
|
|
||||||
|
subnet unset
|
||||||
|
------------
|
||||||
|
|
||||||
|
Unset subnet properties
|
||||||
|
|
||||||
|
.. program:: subnet unset
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
os subnet unset
|
||||||
|
[--allocation-pool start=<ip-address>,end=<ip-address> [...]]
|
||||||
|
[--dns-nameserver <dns-nameserver> [...]]
|
||||||
|
[--host-route destination=<subnet>,gateway=<ip-address> [...]]
|
||||||
|
<subnet>
|
||||||
|
|
||||||
|
.. option:: --dns-nameserver <dns-nameserver>
|
||||||
|
|
||||||
|
DNS server to be removed from this subnet
|
||||||
|
(repeat option to unset multiple DNS servers)
|
||||||
|
|
||||||
|
.. option:: --allocation-pool start=<ip-address>,end=<ip-address>
|
||||||
|
|
||||||
|
Allocation pool to be removed from this subnet e.g.:
|
||||||
|
``start=192.168.199.2,end=192.168.199.254``
|
||||||
|
(repeat option to unset multiple Allocation pools)
|
||||||
|
|
||||||
|
.. option:: --host-route destination=<subnet>,gateway=<ip-address>
|
||||||
|
|
||||||
|
Route to be removed from 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
|
||||||
|
(repeat option to unset multiple host routes)
|
||||||
|
|
||||||
|
.. _subnet_unset-subnet:
|
||||||
|
.. describe:: <subnet>
|
||||||
|
|
||||||
|
subnet to modify (name or ID)
|
||||||
|
@ -28,6 +28,11 @@ from openstackclient.identity import common as identity_common
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _update_arguments(obj_list, parsed_args_list):
|
||||||
|
for item in parsed_args_list:
|
||||||
|
obj_list.remove(item)
|
||||||
|
|
||||||
|
|
||||||
def _format_allocation_pools(data):
|
def _format_allocation_pools(data):
|
||||||
pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
|
pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
|
||||||
for pool in data]
|
for pool in data]
|
||||||
@ -433,3 +438,81 @@ class ShowSubnet(command.ShowOne):
|
|||||||
columns = _get_columns(obj)
|
columns = _get_columns(obj)
|
||||||
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
data = utils.get_item_properties(obj, columns, formatters=_formatters)
|
||||||
return (columns, data)
|
return (columns, data)
|
||||||
|
|
||||||
|
|
||||||
|
class UnsetSubnet(command.Command):
|
||||||
|
"""Unset subnet properties"""
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(UnsetSubnet, self).get_parser(prog_name)
|
||||||
|
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 to be removed from this subnet '
|
||||||
|
'e.g.: start=192.168.199.2,end=192.168.199.254 '
|
||||||
|
'(repeat option to unset multiple Allocation pools)')
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--dns-nameserver',
|
||||||
|
metavar='<dns-nameserver>',
|
||||||
|
action='append',
|
||||||
|
dest='dns_nameservers',
|
||||||
|
help=_('DNS server to be removed from this subnet '
|
||||||
|
'(repeat option to set multiple DNS servers)')
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--host-route',
|
||||||
|
metavar='destination=<subnet>,gateway=<ip-address>',
|
||||||
|
dest='host_routes',
|
||||||
|
action=parseractions.MultiKeyValueAction,
|
||||||
|
required_keys=['destination', 'gateway'],
|
||||||
|
help=_('Route to be removed from 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 '
|
||||||
|
'(repeat option to unset multiple host routes)')
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'subnet',
|
||||||
|
metavar="<subnet>",
|
||||||
|
help=_("Subnet to modify (name or ID)")
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
client = self.app.client_manager.network
|
||||||
|
obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
|
||||||
|
tmp_obj = copy.deepcopy(obj)
|
||||||
|
attrs = {}
|
||||||
|
if parsed_args.dns_nameservers:
|
||||||
|
try:
|
||||||
|
_update_arguments(tmp_obj.dns_nameservers,
|
||||||
|
parsed_args.dns_nameservers)
|
||||||
|
except ValueError as error:
|
||||||
|
msg = (_("%s not in dns-nameservers") % str(error))
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
attrs['dns_nameservers'] = tmp_obj.dns_nameservers
|
||||||
|
if parsed_args.host_routes:
|
||||||
|
try:
|
||||||
|
_update_arguments(
|
||||||
|
tmp_obj.host_routes,
|
||||||
|
convert_entries_to_nexthop(parsed_args.host_routes))
|
||||||
|
except ValueError as error:
|
||||||
|
msg = (_("Subnet does not have %s in host-routes") %
|
||||||
|
str(error))
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
attrs['host_routes'] = tmp_obj.host_routes
|
||||||
|
if parsed_args.allocation_pools:
|
||||||
|
try:
|
||||||
|
_update_arguments(tmp_obj.allocation_pools,
|
||||||
|
parsed_args.allocation_pools)
|
||||||
|
except ValueError as error:
|
||||||
|
msg = (_("Subnet does not have %s in allocation-pools") %
|
||||||
|
str(error))
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
attrs['allocation_pools'] = tmp_obj.allocation_pools
|
||||||
|
if attrs:
|
||||||
|
client.update_subnet(obj, **attrs)
|
||||||
|
@ -767,3 +767,109 @@ class TestShowSubnet(TestSubnet):
|
|||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
|
class TestUnsetSubnet(TestSubnet):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestUnsetSubnet, self).setUp()
|
||||||
|
self._testsubnet = network_fakes.FakeSubnet.create_one_subnet(
|
||||||
|
{'dns_nameservers': ['8.8.8.8',
|
||||||
|
'8.8.8.4'],
|
||||||
|
'host_routes': [{'destination': '10.20.20.0/24',
|
||||||
|
'nexthop': '10.20.20.1'},
|
||||||
|
{'destination': '10.30.30.30/24',
|
||||||
|
'nexthop': '10.30.30.1'}],
|
||||||
|
'allocation_pools': [{'start': '8.8.8.100',
|
||||||
|
'end': '8.8.8.150'},
|
||||||
|
{'start': '8.8.8.160',
|
||||||
|
'end': '8.8.8.170'}], })
|
||||||
|
self.network.find_subnet = mock.Mock(return_value=self._testsubnet)
|
||||||
|
self.network.update_subnet = mock.Mock(return_value=None)
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = subnet_v2.UnsetSubnet(self.app, self.namespace)
|
||||||
|
|
||||||
|
def test_unset_subnet_params(self):
|
||||||
|
arglist = [
|
||||||
|
'--dns-nameserver', '8.8.8.8',
|
||||||
|
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
|
||||||
|
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
|
||||||
|
self._testsubnet.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('dns_nameservers', ['8.8.8.8']),
|
||||||
|
('host_routes', [{
|
||||||
|
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
|
||||||
|
('allocation_pools', [{
|
||||||
|
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
'dns_nameservers': ['8.8.8.4'],
|
||||||
|
'host_routes': [{
|
||||||
|
"destination": "10.20.20.0/24", "nexthop": "10.20.20.1"}],
|
||||||
|
'allocation_pools': [{'start': '8.8.8.160', 'end': '8.8.8.170'}],
|
||||||
|
}
|
||||||
|
self.network.update_subnet.assert_called_once_with(
|
||||||
|
self._testsubnet, **attrs)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_unset_subnet_wrong_host_routes(self):
|
||||||
|
arglist = [
|
||||||
|
'--dns-nameserver', '8.8.8.8',
|
||||||
|
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.2',
|
||||||
|
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
|
||||||
|
self._testsubnet.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('dns_nameservers', ['8.8.8.8']),
|
||||||
|
('host_routes', [{
|
||||||
|
"destination": "10.30.30.30/24", "gateway": "10.30.30.2"}]),
|
||||||
|
('allocation_pools', [{
|
||||||
|
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertRaises(exceptions.CommandError,
|
||||||
|
self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
|
def test_unset_subnet_wrong_allocation_pool(self):
|
||||||
|
arglist = [
|
||||||
|
'--dns-nameserver', '8.8.8.8',
|
||||||
|
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
|
||||||
|
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.156',
|
||||||
|
self._testsubnet.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('dns_nameservers', ['8.8.8.8']),
|
||||||
|
('host_routes', [{
|
||||||
|
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
|
||||||
|
('allocation_pools', [{
|
||||||
|
'start': '8.8.8.100', 'end': '8.8.8.156'}]),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertRaises(exceptions.CommandError,
|
||||||
|
self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
|
def test_unset_subnet_wrong_dns_nameservers(self):
|
||||||
|
arglist = [
|
||||||
|
'--dns-nameserver', '8.8.8.1',
|
||||||
|
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
|
||||||
|
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
|
||||||
|
self._testsubnet.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('dns_nameservers', ['8.8.8.1']),
|
||||||
|
('host_routes', [{
|
||||||
|
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
|
||||||
|
('allocation_pools', [{
|
||||||
|
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
self.assertRaises(exceptions.CommandError,
|
||||||
|
self.cmd.take_action, parsed_args)
|
||||||
|
6
releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml
Normal file
6
releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add a new command ``subnet unset`` to clear the information
|
||||||
|
of allocation-pools, host-routes or DNS servers from the subnet.
|
||||||
|
[ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
|
@ -382,6 +382,7 @@ openstack.network.v2 =
|
|||||||
subnet_list = openstackclient.network.v2.subnet:ListSubnet
|
subnet_list = openstackclient.network.v2.subnet:ListSubnet
|
||||||
subnet_set = openstackclient.network.v2.subnet:SetSubnet
|
subnet_set = openstackclient.network.v2.subnet:SetSubnet
|
||||||
subnet_show = openstackclient.network.v2.subnet:ShowSubnet
|
subnet_show = openstackclient.network.v2.subnet:ShowSubnet
|
||||||
|
subnet_unset = openstackclient.network.v2.subnet:UnsetSubnet
|
||||||
|
|
||||||
subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool
|
subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool
|
||||||
subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool
|
subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool
|
||||||
|
Loading…
Reference in New Issue
Block a user