Skip to content

Commit 45b026d

Browse files
author
reedip
committed
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
1 parent 21ac923 commit 45b026d

5 files changed

Lines changed: 234 additions & 0 deletions

File tree

doc/source/command-objects/subnet.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,41 @@ Display subnet details
235235
.. describe:: <subnet>
236236
237237
Subnet to display (name or ID)
238+
239+
subnet unset
240+
------------
241+
242+
Unset subnet properties
243+
244+
.. program:: subnet unset
245+
.. code:: bash
246+
247+
os subnet unset
248+
[--allocation-pool start=<ip-address>,end=<ip-address> [...]]
249+
[--dns-nameserver <dns-nameserver> [...]]
250+
[--host-route destination=<subnet>,gateway=<ip-address> [...]]
251+
<subnet>
252+
253+
.. option:: --dns-nameserver <dns-nameserver>
254+
255+
DNS server to be removed from this subnet
256+
(repeat option to unset multiple DNS servers)
257+
258+
.. option:: --allocation-pool start=<ip-address>,end=<ip-address>
259+
260+
Allocation pool to be removed from this subnet e.g.:
261+
``start=192.168.199.2,end=192.168.199.254``
262+
(repeat option to unset multiple Allocation pools)
263+
264+
.. option:: --host-route destination=<subnet>,gateway=<ip-address>
265+
266+
Route to be removed from this subnet e.g.:
267+
``destination=10.10.0.0/16,gateway=192.168.71.254``
268+
destination: destination subnet (in CIDR notation)
269+
gateway: nexthop IP address
270+
(repeat option to unset multiple host routes)
271+
272+
.. _subnet_unset-subnet:
273+
.. describe:: <subnet>
274+
275+
subnet to modify (name or ID)

openstackclient/network/v2/subnet.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
LOG = logging.getLogger(__name__)
2929

3030

31+
def _update_arguments(obj_list, parsed_args_list):
32+
for item in parsed_args_list:
33+
obj_list.remove(item)
34+
35+
3136
def _format_allocation_pools(data):
3237
pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
3338
for pool in data]
@@ -433,3 +438,81 @@ def take_action(self, parsed_args):
433438
columns = _get_columns(obj)
434439
data = utils.get_item_properties(obj, columns, formatters=_formatters)
435440
return (columns, data)
441+
442+
443+
class UnsetSubnet(command.Command):
444+
"""Unset subnet properties"""
445+
446+
def get_parser(self, prog_name):
447+
parser = super(UnsetSubnet, self).get_parser(prog_name)
448+
parser.add_argument(
449+
'--allocation-pool',
450+
metavar='start=<ip-address>,end=<ip-address>',
451+
dest='allocation_pools',
452+
action=parseractions.MultiKeyValueAction,
453+
required_keys=['start', 'end'],
454+
help=_('Allocation pool to be removed from this subnet '
455+
'e.g.: start=192.168.199.2,end=192.168.199.254 '
456+
'(repeat option to unset multiple Allocation pools)')
457+
)
458+
parser.add_argument(
459+
'--dns-nameserver',
460+
metavar='<dns-nameserver>',
461+
action='append',
462+
dest='dns_nameservers',
463+
help=_('DNS server to be removed from this subnet '
464+
'(repeat option to set multiple DNS servers)')
465+
)
466+
parser.add_argument(
467+
'--host-route',
468+
metavar='destination=<subnet>,gateway=<ip-address>',
469+
dest='host_routes',
470+
action=parseractions.MultiKeyValueAction,
471+
required_keys=['destination', 'gateway'],
472+
help=_('Route to be removed from this subnet '
473+
'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
474+
'destination: destination subnet (in CIDR notation) '
475+
'gateway: nexthop IP address '
476+
'(repeat option to unset multiple host routes)')
477+
)
478+
parser.add_argument(
479+
'subnet',
480+
metavar="<subnet>",
481+
help=_("Subnet to modify (name or ID)")
482+
)
483+
return parser
484+
485+
def take_action(self, parsed_args):
486+
client = self.app.client_manager.network
487+
obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
488+
tmp_obj = copy.deepcopy(obj)
489+
attrs = {}
490+
if parsed_args.dns_nameservers:
491+
try:
492+
_update_arguments(tmp_obj.dns_nameservers,
493+
parsed_args.dns_nameservers)
494+
except ValueError as error:
495+
msg = (_("%s not in dns-nameservers") % str(error))
496+
raise exceptions.CommandError(msg)
497+
attrs['dns_nameservers'] = tmp_obj.dns_nameservers
498+
if parsed_args.host_routes:
499+
try:
500+
_update_arguments(
501+
tmp_obj.host_routes,
502+
convert_entries_to_nexthop(parsed_args.host_routes))
503+
except ValueError as error:
504+
msg = (_("Subnet does not have %s in host-routes") %
505+
str(error))
506+
raise exceptions.CommandError(msg)
507+
attrs['host_routes'] = tmp_obj.host_routes
508+
if parsed_args.allocation_pools:
509+
try:
510+
_update_arguments(tmp_obj.allocation_pools,
511+
parsed_args.allocation_pools)
512+
except ValueError as error:
513+
msg = (_("Subnet does not have %s in allocation-pools") %
514+
str(error))
515+
raise exceptions.CommandError(msg)
516+
attrs['allocation_pools'] = tmp_obj.allocation_pools
517+
if attrs:
518+
client.update_subnet(obj, **attrs)

openstackclient/tests/network/v2/test_subnet.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,3 +767,109 @@ def test_show_all_options(self):
767767

768768
self.assertEqual(self.columns, columns)
769769
self.assertEqual(self.data, data)
770+
771+
772+
class TestUnsetSubnet(TestSubnet):
773+
774+
def setUp(self):
775+
super(TestUnsetSubnet, self).setUp()
776+
self._testsubnet = network_fakes.FakeSubnet.create_one_subnet(
777+
{'dns_nameservers': ['8.8.8.8',
778+
'8.8.8.4'],
779+
'host_routes': [{'destination': '10.20.20.0/24',
780+
'nexthop': '10.20.20.1'},
781+
{'destination': '10.30.30.30/24',
782+
'nexthop': '10.30.30.1'}],
783+
'allocation_pools': [{'start': '8.8.8.100',
784+
'end': '8.8.8.150'},
785+
{'start': '8.8.8.160',
786+
'end': '8.8.8.170'}], })
787+
self.network.find_subnet = mock.Mock(return_value=self._testsubnet)
788+
self.network.update_subnet = mock.Mock(return_value=None)
789+
# Get the command object to test
790+
self.cmd = subnet_v2.UnsetSubnet(self.app, self.namespace)
791+
792+
def test_unset_subnet_params(self):
793+
arglist = [
794+
'--dns-nameserver', '8.8.8.8',
795+
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
796+
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
797+
self._testsubnet.name,
798+
]
799+
verifylist = [
800+
('dns_nameservers', ['8.8.8.8']),
801+
('host_routes', [{
802+
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
803+
('allocation_pools', [{
804+
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
805+
]
806+
807+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
808+
result = self.cmd.take_action(parsed_args)
809+
810+
attrs = {
811+
'dns_nameservers': ['8.8.8.4'],
812+
'host_routes': [{
813+
"destination": "10.20.20.0/24", "nexthop": "10.20.20.1"}],
814+
'allocation_pools': [{'start': '8.8.8.160', 'end': '8.8.8.170'}],
815+
}
816+
self.network.update_subnet.assert_called_once_with(
817+
self._testsubnet, **attrs)
818+
self.assertIsNone(result)
819+
820+
def test_unset_subnet_wrong_host_routes(self):
821+
arglist = [
822+
'--dns-nameserver', '8.8.8.8',
823+
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.2',
824+
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
825+
self._testsubnet.name,
826+
]
827+
verifylist = [
828+
('dns_nameservers', ['8.8.8.8']),
829+
('host_routes', [{
830+
"destination": "10.30.30.30/24", "gateway": "10.30.30.2"}]),
831+
('allocation_pools', [{
832+
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
833+
]
834+
835+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
836+
self.assertRaises(exceptions.CommandError,
837+
self.cmd.take_action, parsed_args)
838+
839+
def test_unset_subnet_wrong_allocation_pool(self):
840+
arglist = [
841+
'--dns-nameserver', '8.8.8.8',
842+
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
843+
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.156',
844+
self._testsubnet.name,
845+
]
846+
verifylist = [
847+
('dns_nameservers', ['8.8.8.8']),
848+
('host_routes', [{
849+
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
850+
('allocation_pools', [{
851+
'start': '8.8.8.100', 'end': '8.8.8.156'}]),
852+
]
853+
854+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
855+
self.assertRaises(exceptions.CommandError,
856+
self.cmd.take_action, parsed_args)
857+
858+
def test_unset_subnet_wrong_dns_nameservers(self):
859+
arglist = [
860+
'--dns-nameserver', '8.8.8.1',
861+
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
862+
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
863+
self._testsubnet.name,
864+
]
865+
verifylist = [
866+
('dns_nameservers', ['8.8.8.1']),
867+
('host_routes', [{
868+
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
869+
('allocation_pools', [{
870+
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
871+
]
872+
873+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
874+
self.assertRaises(exceptions.CommandError,
875+
self.cmd.take_action, parsed_args)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Add a new command ``subnet unset`` to clear the information
5+
of allocation-pools, host-routes or DNS servers from the subnet.
6+
[ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ openstack.network.v2 =
382382
subnet_list = openstackclient.network.v2.subnet:ListSubnet
383383
subnet_set = openstackclient.network.v2.subnet:SetSubnet
384384
subnet_show = openstackclient.network.v2.subnet:ShowSubnet
385+
subnet_unset = openstackclient.network.v2.subnet:UnsetSubnet
385386

386387
subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool
387388
subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool

0 commit comments

Comments
 (0)