Add support for removing subnets from a policy segment

Removing the subnets of a segment should be done via PUT and not PATCH
as the NSX backend does nto support it.

Change-Id: Ib0ab3baacc65437aa1d822a133bdec2ebf566bd5
This commit is contained in:
Adit Sarfaty 2018-12-19 09:59:02 +02:00
parent be6be25219
commit f5bafe0ff4
3 changed files with 103 additions and 3 deletions

View File

@ -2130,6 +2130,84 @@ class TestPolicyTier0(NsxPolicyLibTestCase):
tier1_id, tenant=TEST_TENANT)
class TestPolicySegment(NsxPolicyLibTestCase):
def setUp(self, *args, **kwargs):
super(TestPolicySegment, self).setUp()
self.resourceApi = self.policy_lib.segment
def test_create(self):
name = 'test'
description = 'desc'
tier1_id = '111'
subnets = [policy_defs.Subnet(gateway_address="2.2.2.0/24")]
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(
name, description=description,
tier1_id=tier1_id,
subnets=subnets,
tenant=TEST_TENANT)
expected_def = policy_defs.SegmentDef(
segment_id=mock.ANY,
name=name,
description=description,
tier1_id=tier1_id,
subnets=subnets,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_delete(self):
segment_id = '111'
with mock.patch.object(self.policy_api, "delete") as api_call:
self.resourceApi.delete(segment_id, tenant=TEST_TENANT)
expected_def = policy_defs.SegmentDef(segment_id=segment_id,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_get(self):
segment_id = '111'
with mock.patch.object(self.policy_api, "get") as api_call:
self.resourceApi.get(segment_id, tenant=TEST_TENANT)
expected_def = policy_defs.SegmentDef(segment_id=segment_id,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_list(self):
with mock.patch.object(self.policy_api, "list") as api_call:
self.resourceApi.list(tenant=TEST_TENANT)
expected_def = policy_defs.SegmentDef(tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_update(self):
segment_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(segment_id,
name=name,
tenant=TEST_TENANT)
expected_def = policy_defs.SegmentDef(segment_id=segment_id,
name=name,
tenant=TEST_TENANT)
self.assert_called_with_def(update_call, expected_def)
def test_remove_connectivity_and_subnets(self):
segment_id = '111'
with mock.patch.object(self.policy_api, "get",
return_value={'id': segment_id}) as api_get,\
mock.patch.object(self.policy_api.client, "update") as api_put:
self.resourceApi.remove_connectivity_and_subnets(
segment_id, tenant=TEST_TENANT)
api_get.assert_called_once()
api_put.assert_called_once_with(
'%s/segments/%s' % (TEST_TENANT, segment_id),
{'id': segment_id, 'connectivity_path': None, 'subnets': None})
class TestPolicySegmentProfileBase(NsxPolicyLibTestCase):
def setUp(self, resource_api_name='segment_security_profile',

View File

@ -498,8 +498,13 @@ class BaseSegmentDef(ResourceDef):
def get_obj_dict(self):
body = super(BaseSegmentDef, self).get_obj_dict()
if self.has_attr('subnets'):
body['subnets'] = [subnet.get_obj_dict()
for subnet in self.get_attr('subnets')]
# Note(asarfaty): removing subnets through PATCH api is not
# supported
if self.get_attr('subnets'):
subnets = [subnet.get_obj_dict()
for subnet in self.get_attr('subnets')]
self._set_attr_if_specified(body, 'subnets',
value=subnets)
self._set_attrs_if_specified(body, ['domain_name', 'vlan_ids'])
return body
@ -543,7 +548,7 @@ class SegmentDef(BaseSegmentDef):
def get_obj_dict(self):
body = super(SegmentDef, self).get_obj_dict()
if self.has_attr('tier1_id'):
path = None
path = ""
if self.get_attr('tier1_id'):
tier1 = Tier1Def(tier1_id=self.get_attr('tier1_id'),
tenant=self.get_tenant())

View File

@ -1193,6 +1193,23 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
tags=tags,
tenant=tenant)
def remove_connectivity_and_subnets(
self, segment_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Disconnect a segment from a router and remove its subnets.
PATCH does not support this action so PUT is used for this
"""
# Get the current segment and update it
segment = self.get(segment_id)
segment['subnets'] = None
segment['connectivity_path'] = None
segment_def = self.entry_def(segment_id=segment_id, tenant=tenant)
path = segment_def.get_resource_path()
self.policy_api.client.update(path, segment)
def get_realized_state(self, segment_id, entity_type=None,
tenant=policy_constants.POLICY_INFRA_TENANT,
realization_info=None):