From c8edaa87ef193acd1413b601044e82c27357678e Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Mon, 2 Jan 2017 15:48:07 +0200 Subject: [PATCH] Support ip-pool update Support replacing / deleting values from an existing ip-pool Change-Id: I918474a9db144bbf22a0df39edb076dedcd327cb --- vmware_nsxlib/tests/unit/v3/test_constants.py | 1 - vmware_nsxlib/tests/unit/v3/test_resources.py | 57 +++++++++++++++++-- vmware_nsxlib/v3/nsx_constants.py | 3 + vmware_nsxlib/v3/resources.py | 54 +++++++++++++----- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/vmware_nsxlib/tests/unit/v3/test_constants.py b/vmware_nsxlib/tests/unit/v3/test_constants.py index 50495ffb..40e7139a 100644 --- a/vmware_nsxlib/tests/unit/v3/test_constants.py +++ b/vmware_nsxlib/tests/unit/v3/test_constants.py @@ -167,7 +167,6 @@ FAKE_IP_POOL = { "id": FAKE_IP_POOL_UUID, "display_name": "IPPool-IPV6-1", "description": "IPPool-IPV6-1 Description", - "resource_type": "IpPool", "subnets": [{ "dns_nameservers": [ "2002:a70:cbfa:1:1:1:1:1" diff --git a/vmware_nsxlib/tests/unit/v3/test_resources.py b/vmware_nsxlib/tests/unit/v3/test_resources.py index 7e513024..b673112a 100644 --- a/vmware_nsxlib/tests/unit/v3/test_resources.py +++ b/vmware_nsxlib/tests/unit/v3/test_resources.py @@ -561,7 +561,7 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): cidr = '2.2.2.0/24' description = 'desc' dns_nameserver = '7.7.7.7' - pool.create(cidr, ranges=ranges, + pool.create(cidr, allocation_ranges=ranges, display_name=display_name, gateway_ip=gateway_ip, description=description, @@ -589,7 +589,7 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): ranges = [{'start': '2.2.2.0', 'end': '2.2.2.255'}, {'start': '3.2.2.0', 'end': '3.2.2.255'}] cidr = '2.2.2.0/24' - pool.create(cidr, ranges=ranges) + pool.create(cidr, allocation_ranges=ranges) data = { 'subnets': [{ @@ -607,7 +607,7 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): pool = self._mocked_pool() cidr = '2.2.2.0/30' gateway_ip = '2.2.2.1' - pool.create(cidr, ranges=None, gateway_ip=gateway_ip) + pool.create(cidr, allocation_ranges=None, gateway_ip=gateway_ip) exp_ranges = [{'start': '2.2.2.0', 'end': '2.2.2.0'}, {'start': '2.2.2.2', 'end': '2.2.2.3'}] @@ -627,7 +627,7 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): def test_create_ip_pool_no_ranges_no_gateway(self): pool = self._mocked_pool() cidr = '2.2.2.0/30' - pool.create(cidr, ranges=None) + pool.create(cidr, allocation_ranges=None) exp_ranges = [{'start': '2.2.2.0', 'end': '2.2.2.3'}] data = { @@ -650,7 +650,7 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): cidr = None try: - pool.create(cidr, ranges=ranges, + pool.create(cidr, allocation_ranges=ranges, gateway_ip=gateway_ip) except exceptions.InvalidInput: # This call should fail @@ -658,6 +658,53 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase): else: self.fail("shouldn't happen") + def test_update_ip_pool_name(self): + fake_ip_pool = test_constants.FAKE_IP_POOL.copy() + resp_resources = fake_ip_pool + pool = self._mocked_pool( + session_response=mocks.MockRequestsResponse( + 200, jsonutils.dumps(resp_resources))) + + uuid = fake_ip_pool['id'] + new_name = 'new_name' + pool.update(uuid, display_name=new_name) + fake_ip_pool['display_name'] = new_name + test_client.assert_json_call( + 'put', pool, + 'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid, + data=jsonutils.dumps(fake_ip_pool, sort_keys=True)) + + def test_update_ip_pool_gateway(self): + fake_ip_pool = test_constants.FAKE_IP_POOL.copy() + resp_resources = fake_ip_pool + pool = self._mocked_pool( + session_response=mocks.MockRequestsResponse( + 200, jsonutils.dumps(resp_resources))) + + uuid = fake_ip_pool['id'] + new_gateway = '1.0.0.1' + pool.update(uuid, gateway_ip=new_gateway) + fake_ip_pool["subnets"][0]['gateway_ip'] = new_gateway + test_client.assert_json_call( + 'put', pool, + 'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid, + data=jsonutils.dumps(fake_ip_pool, sort_keys=True)) + + def test_update_ip_pool_delete_gateway(self): + fake_ip_pool = test_constants.FAKE_IP_POOL.copy() + resp_resources = fake_ip_pool + pool = self._mocked_pool( + session_response=mocks.MockRequestsResponse( + 200, jsonutils.dumps(resp_resources))) + + uuid = fake_ip_pool['id'] + pool.update(uuid, gateway_ip=None) + del fake_ip_pool["subnets"][0]['gateway_ip'] + test_client.assert_json_call( + 'put', pool, + 'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid, + data=jsonutils.dumps(fake_ip_pool, sort_keys=True)) + def test_get_ip_pool(self): """Test getting a router port by router id""" fake_ip_pool = test_constants.FAKE_IP_POOL.copy() diff --git a/vmware_nsxlib/v3/nsx_constants.py b/vmware_nsxlib/v3/nsx_constants.py index 5340b423..13e23e8c 100644 --- a/vmware_nsxlib/v3/nsx_constants.py +++ b/vmware_nsxlib/v3/nsx_constants.py @@ -107,3 +107,6 @@ ERR_CODE_OBJECT_NOT_FOUND = 202 ERR_CODE_IPAM_POOL_EXHAUSTED = 5109 ERR_CODE_IPAM_SPECIFIC_IP = 5123 ERR_CODE_IPAM_IP_NOT_IN_POOL = 5110 +ERR_CODE_IPAM_RANGE_MODIFY = 5602 +ERR_CODE_IPAM_RANGE_DELETE = 5015 +ERR_CODE_IPAM_RANGE_SHRUNK = 5016 diff --git a/vmware_nsxlib/v3/resources.py b/vmware_nsxlib/v3/resources.py index 9d117841..7ca8774a 100644 --- a/vmware_nsxlib/v3/resources.py +++ b/vmware_nsxlib/v3/resources.py @@ -601,16 +601,16 @@ class IpPool(AbstractRESTResource): return [{"start": str(r[0]), "end": str(r[-1])} for r in ip_set.iter_ipranges()] - def create(self, cidr, ranges=None, display_name=None, description=None, - gateway_ip=None, dns_nameservers=None): + def create(self, cidr, allocation_ranges=None, display_name=None, + description=None, gateway_ip=None, dns_nameservers=None): """Create an IpPool. Arguments: cidr: (required) - ranges: (optional) a list of dictionaries, each with 'start' - and 'end' keys, and IP values. - If None: the cidr will be used to create the ranges, - excluding the gateway. + allocation_ranges: (optional) a list of dictionaries, each with + 'start' and 'end' keys, and IP values. + If None: the cidr will be used to create the ranges, + excluding the gateway. display_name: (optional) description: (optional) gateway_ip: (optional) @@ -619,11 +619,11 @@ class IpPool(AbstractRESTResource): if not cidr: raise exceptions.InvalidInput(operation="IP Pool create", arg_name="cidr", arg_val=cidr) - if not ranges: + if not allocation_ranges: # generate ranges from (cidr - gateway) - ranges = self._generate_ranges(cidr, gateway_ip) + allocation_ranges = self._generate_ranges(cidr, gateway_ip) - subnet = {"allocation_ranges": ranges, + subnet = {"allocation_ranges": allocation_ranges, "cidr": cidr} if gateway_ip: subnet["gateway_ip"] = gateway_ip @@ -632,9 +632,9 @@ class IpPool(AbstractRESTResource): body = {"subnets": [subnet]} if description: - body['description'] = description + body["description"] = description if display_name: - body['display_name'] = display_name + body["display_name"] = display_name return self._client.create(body=body) @@ -642,9 +642,35 @@ class IpPool(AbstractRESTResource): """Delete an IPPool by its ID.""" return self._client.delete(pool_id) - def update(self, uuid, *args, **kwargs): - # Not supported yet - pass + def _update_param_in_pool(self, args_dict, key, pool_data): + # update the arg only if it exists in the args dictionary + if key in args_dict: + if args_dict[key]: + pool_data[key] = args_dict[key] + else: + # remove the current value + del pool_data[key] + + def update(self, pool_id, **kwargs): + """Update the given attributes in the current pool configuration.""" + # Get the current pool, and remove irrelevant fields + pool = self.get(pool_id) + for key in ["resource_type", "_create_time", "_create_user" + "_last_modified_user", "_last_modified_time"]: + pool.pop(key, None) + + # update only the attributes in kwargs + self._update_param_in_pool(kwargs, 'display_name', pool) + self._update_param_in_pool(kwargs, 'description', pool) + self._update_param_in_pool(kwargs, 'gateway_ip', + pool["subnets"][0]) + self._update_param_in_pool(kwargs, 'dns_nameservers', + pool["subnets"][0]) + self._update_param_in_pool(kwargs, 'allocation_ranges', + pool["subnets"][0]) + self._update_param_in_pool(kwargs, 'cidr', + pool["subnets"][0]) + return self._client.update(pool_id, pool) def get(self, pool_id): return self._client.get(pool_id)