Update policy resources apis

1. create when missing
For NSX Policy resources, modify "update" method behavior to
create the resource if it does not exist. This will save roundtrips.

2. update the path to use policy/api/vi

3. use POST instead of PUT

4. Update apis do not have to use get before update

5. Add enforcement point thumbprint

Co-Authored-by: Adit Sarfaty <asarfaty@vmware.com>
Change-Id: Ic44308d1df8944dfbcfa2a613ed8e1847eee3715
This commit is contained in:
Anna Khmelnitsky 2017-04-28 18:45:16 -07:00 committed by Adit Sarfaty
parent 373506a8d4
commit cdaad65004
8 changed files with 350 additions and 245 deletions

View File

@ -18,14 +18,14 @@ from vmware_nsxlib.v3 import client
from vmware_nsxlib.v3 import policy_constants
from vmware_nsxlib.v3 import policy_defs as policy
BASE_POLICY_URI = "https://1.2.3.4/api/v1/"
BASE_POLICY_URI = "https://1.2.3.4/policy/api/v1/"
class TestPolicyApi(nsxlib_testcase.NsxClientTestCase):
def setUp(self):
self.client = self.new_mocked_client(client.NSX3Client,
url_prefix='api/v1/')
url_prefix='policy/api/v1/')
self.policy_api = policy.NsxPolicyApi(self.client)
super(TestPolicyApi, self).setUp()
@ -43,8 +43,8 @@ class TestPolicyDomain(TestPolicyApi):
'archaea',
'prokaryotic cells',
'typically characterized by membrane lipids')
self.policy_api.create(domain_def)
self.assert_json_call('PUT', self.client,
self.policy_api.create_or_update(domain_def)
self.assert_json_call('POST', self.client,
'infra/domains/archaea',
data=domain_def.get_obj_dict())
@ -73,8 +73,8 @@ class TestPolicyGroup(TestPolicyApi):
'eukarya',
'cats',
'felis catus')
self.policy_api.create(group_def)
self.assert_json_call('PUT', self.client,
self.policy_api.create_or_update(group_def)
self.assert_json_call('POST', self.client,
'infra/domains/eukarya/groups/cats',
data=group_def.get_obj_dict())
@ -89,7 +89,7 @@ class TestPolicyGroup(TestPolicyApi):
self.policy_api.create_with_parent(domain_def, group_def)
data = domain_def.get_obj_dict()
data['groups'] = [group_def.get_obj_dict()]
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domains/eukarya',
data=data)
@ -110,14 +110,12 @@ class TestPolicyGroup(TestPolicyApi):
expected_group = {'id': 'dogs',
'display_name': None,
'description': None,
'expression': [expected_condition],
'_revision': 0}
'expression': [expected_condition]}
expected_data = {'id': 'eukarya',
'display_name': None,
'description': None,
'groups': [expected_group],
'_revision': 0}
self.assert_json_call('PUT', self.client,
'groups': [expected_group]}
self.assert_json_call('POST', self.client,
'infra/domains/eukarya',
data=expected_data)
@ -134,7 +132,7 @@ class TestPolicyGroup(TestPolicyApi):
self.policy_api.create_with_parent(domain_def, group_def)
data = domain_def.get_obj_dict()
data['groups'] = [group_def.get_obj_dict()]
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domains/eukarya',
data=data)
@ -149,8 +147,8 @@ class TestPolicyService(TestPolicyApi):
def test_create(self):
service_def = policy.ServiceDef('roomservice')
self.policy_api.create(service_def)
self.assert_json_call('PUT', self.client,
self.policy_api.create_or_update(service_def)
self.assert_json_call('POST', self.client,
'infra/services/roomservice',
data=service_def.get_obj_dict())
@ -167,14 +165,12 @@ class TestPolicyService(TestPolicyApi):
'display_name': 'room http',
'description': None,
'l4_protocol': 'TCP',
'destination_ports': [80, 8080],
'_revision': 0}
'destination_ports': [80, 8080]}
expected_data = {'id': 'roomservice',
'display_name': None,
'description': None,
'service_entries': [expected_entry],
'_revision': 0}
self.assert_json_call('PUT', self.client,
'service_entries': [expected_entry]}
self.assert_json_call('POST', self.client,
'infra/services/roomservice',
data=expected_data)
@ -183,8 +179,8 @@ class TestPolicyCommunicationProfile(TestPolicyApi):
def test_create(self):
profile_def = policy.CommunicationProfileDef('rental')
self.policy_api.create(profile_def)
self.assert_json_call('PUT', self.client,
self.policy_api.create_or_update(profile_def)
self.assert_json_call('POST', self.client,
'infra/communication-profiles/rental',
data=profile_def.get_obj_dict())
@ -201,14 +197,12 @@ class TestPolicyCommunicationProfile(TestPolicyApi):
'display_name': None,
'description': 'includes roomservice',
'services': ["roomservice"],
'action': 'ALLOW',
'_revision': 0}
'action': 'ALLOW'}
expected_data = {'id': 'rental',
'display_name': None,
'description': None,
'communication_profile_entries': [expected_entry],
'_revision': 0}
self.assert_json_call('PUT', self.client,
'communication_profile_entries': [expected_entry]}
self.assert_json_call('POST', self.client,
'infra/communication-profiles/rental',
data=expected_data)
@ -233,8 +227,7 @@ class TestPolicyCommunicationMap(TestPolicyApi):
dest_groups=["group3"],
profile_id="profile2")
self.expected_data1 = {'_revision': 0,
'id': 'cm1',
self.expected_data1 = {'id': 'cm1',
'display_name': None,
'description': None,
'sequence_number': 12,
@ -246,8 +239,7 @@ class TestPolicyCommunicationMap(TestPolicyApi):
'communication_profile_path':
'/infra/communication-profiles/profile1'}
self.expected_data2 = {'_revision': 0,
'id': 'cm2',
self.expected_data2 = {'id': 'cm2',
'display_name': None,
'description': None,
'sequence_number': 13,
@ -265,7 +257,7 @@ class TestPolicyCommunicationMap(TestPolicyApi):
self.policy_api.create_with_parent(map_def, self.entry1)
expected_data = map_def.get_obj_dict()
expected_data['communication_entries'] = [self.expected_data1]
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domains/d1/communication-map',
data=expected_data)
@ -277,14 +269,14 @@ class TestPolicyCommunicationMap(TestPolicyApi):
expected_data = map_def.get_obj_dict()
expected_data['communication_entries'] = [self.expected_data1,
self.expected_data2]
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domains/d1/communication-map',
data=expected_data)
def test_update_entry(self):
self.policy_api.create(self.entry1)
self.policy_api.create_or_update(self.entry1)
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domains/d1/communication-map/'
'communication-entries/cm1',
data=self.expected_data1)
@ -305,9 +297,9 @@ class TestPolicyEnforcementPoint(TestPolicyApi):
username='admin',
password='a')
self.policy_api.create(ep_def)
self.policy_api.create_or_update(ep_def)
ep_path = policy.EnforcementPointDef('ep1').get_resource_path()
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
ep_path,
data=ep_def.get_obj_dict())
@ -317,15 +309,14 @@ class TestPolicyDeploymentMap(TestPolicyApi):
def test_create(self):
map_def = policy.DeploymentMapDef('dm1', domain_id='d1', ep_id='ep1')
self.policy_api.create(map_def)
self.policy_api.create_or_update(map_def)
ep_path = policy.EnforcementPointDef('ep1').get_resource_full_path()
expected_data = {'_revision': 0,
'id': 'dm1',
expected_data = {'id': 'dm1',
'display_name': None,
'description': None,
'domain_path': '/infra/domains/d1',
'enforcement_point_paths': [ep_path]}
self.assert_json_call('PUT', self.client,
self.assert_json_call('POST', self.client,
'infra/domaindeploymentmap/dm1',
data=expected_data)

View File

@ -82,11 +82,12 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
name = 'd1'
description = 'desc'
id = '111'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name,
domain_id=id,
description=description,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(name,
domain_id=id,
description=description,
tenant=TEST_TENANT)
expected_def = policy_defs.DomainDef(domain_id=id,
name=name,
description=description,
@ -96,9 +97,10 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
def test_create_without_id(self):
name = 'd1'
description = 'desc'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name, description=description,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(name, description=description,
tenant=TEST_TENANT)
expected_def = policy_defs.DomainDef(domain_id=mock.ANY,
name=name,
description=description,
@ -141,9 +143,8 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
id = '111'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
description=description,
@ -152,7 +153,6 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
tenant=TEST_TENANT)
expected_dict = {'display_name': name,
'description': description}
self.assert_called_with_def(get_call, expected_def)
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)
@ -168,12 +168,13 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
name = 'g1'
description = 'desc'
id = '222'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name,
domain_id,
group_id=id,
description=description,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(name,
domain_id,
group_id=id,
description=description,
tenant=TEST_TENANT)
expected_def = policy_defs.GroupDef(domain_id=domain_id,
group_id=id,
name=name,
@ -186,9 +187,11 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
domain_id = '111'
name = 'g1'
description = 'desc'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name, domain_id, description=description,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(name, domain_id,
description=description,
tenant=TEST_TENANT)
expected_def = policy_defs.GroupDef(domain_id=domain_id,
group_id=mock.ANY,
name=name,
@ -205,8 +208,9 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
cond_op = policy_constants.CONDITION_OP_EQUALS
cond_member_type = policy_constants.CONDITION_MEMBER_NET
cond_key = policy_constants.CONDITION_KEY_TAG
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(
name, domain_id, description=description,
cond_val=cond_val,
cond_op=cond_op,
@ -270,9 +274,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
id = '222'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(domain_id, id,
name=name,
description=description,
@ -282,7 +285,6 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
tenant=TEST_TENANT)
expected_dict = {'display_name': name,
'description': description}
self.assert_called_with_def(get_call, expected_def)
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)
@ -292,7 +294,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
cond_val = '123'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update_condition(domain_id, id,
cond_val=cond_val,
tenant=TEST_TENANT)
@ -319,7 +322,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
'operator': policy_constants.CONDITION_OP_EQUALS}
with mock.patch.object(self.policy_api, "get",
return_value={'expression': [old_cond]}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update_condition(domain_id, id,
cond_val=None,
tenant=TEST_TENANT)
@ -345,9 +349,11 @@ class TestPolicyService(NsxPolicyLibTestCase):
dest_ports = [81, 82]
with mock.patch.object(self.policy_api,
"create_with_parent") as api_call:
self.resourceApi.create(name, description=description,
protocol=protocol, dest_ports=dest_ports,
tenant=TEST_TENANT)
self.resourceApi.create_or_overwrite(name,
description=description,
protocol=protocol,
dest_ports=dest_ports,
tenant=TEST_TENANT)
exp_srv_def = policy_defs.ServiceDef(service_id=mock.ANY,
name=name,
description=description,
@ -400,7 +406,8 @@ class TestPolicyService(NsxPolicyLibTestCase):
description = 'new desc'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
description=description,
@ -424,7 +431,8 @@ class TestPolicyService(NsxPolicyLibTestCase):
with mock.patch.object(
self.policy_api, "get",
return_value={'service_entries': [service_entry]}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
protocol=protocol,
dest_ports=dest_ports,
@ -457,7 +465,8 @@ class TestPolicyService(NsxPolicyLibTestCase):
with mock.patch.object(
self.policy_api, "get",
return_value={'service_entries': [service_entry]}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call,\
mock.patch.object(self.policy_api,
"create_or_update") as update_call,\
mock.patch.object(self.policy_api, "list",
return_value={'results': []}):
self.resourceApi.update(id,
@ -474,7 +483,7 @@ class TestPolicyService(NsxPolicyLibTestCase):
# update will be called for the service and entry (2 calls)
expected_dict = {'display_name': name,
'description': description,
'service_entries': [service_entry]}
'service_entries': []}
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)
@ -505,9 +514,10 @@ class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
action = 'DENY'
with mock.patch.object(self.policy_api,
"create_with_parent") as api_call:
self.resourceApi.create(name, description=description,
services=[service_id], action=action,
tenant=TEST_TENANT)
self.resourceApi.create_or_overwrite(name, description=description,
services=[service_id],
action=action,
tenant=TEST_TENANT)
exp_srv_def = policy_defs.CommunicationProfileDef(
profile_id=mock.ANY,
name=name,
@ -563,7 +573,8 @@ class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
description = 'new desc'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
description=description,
@ -587,7 +598,8 @@ class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
with mock.patch.object(
self.policy_api, "get", return_value=entries_dict) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
services=[service_id],
action=action,
@ -620,7 +632,8 @@ class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
with mock.patch.object(
self.policy_api, "get", return_value=entries_dict) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
description=description,
@ -635,7 +648,7 @@ class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
# update will be called for the service and entry (2 calls)
expected_dict = {'display_name': name,
'description': description,
'communication_profile_entries': [profile_entry]}
'communication_profile_entries': []}
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)
@ -668,15 +681,17 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
seq_num = 7
profile_id = 'c1'
list_return_value = {'results': [{'sequence_number': 1}]}
with mock.patch.object(self.policy_api, "create") as api_call,\
with mock.patch.object(self.policy_api,
"create_or_update") as api_call,\
mock.patch.object(self.policy_api, "list",
return_value=list_return_value):
self.resourceApi.create(name, domain_id, description=description,
sequence_number=seq_num,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
self.resourceApi.create_or_overwrite(name, domain_id,
description=description,
sequence_number=seq_num,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
expected_def = policy_defs.CommunicationMapEntryDef(
domain_id=domain_id,
map_id=mock.ANY,
@ -689,6 +704,36 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_create_first_seqnum(self):
domain_id = '111'
name = 'cm1'
description = 'desc'
source_group = 'g1'
dest_group = 'g2'
profile_id = 'c1'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call, \
mock.patch.object(self.resourceApi, "list", return_value=[]):
self.resourceApi.create_or_overwrite(name, domain_id,
description=description,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
expected_def = policy_defs.CommunicationMapEntryDef(
domain_id=domain_id,
map_id=mock.ANY,
name=name,
description=description,
sequence_number=1,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_create_without_seqnum(self):
domain_id = '111'
name = 'cm1'
@ -698,12 +743,14 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
profile_id = 'c1'
with mock.patch.object(self.policy_api,
"create_with_parent") as api_call, \
mock.patch.object(self.resourceApi, "list", return_value=[]):
self.resourceApi.create(name, domain_id, description=description,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
mock.patch.object(self.resourceApi, "_get_last_seq_num",
return_value=-1):
self.resourceApi.create_or_overwrite(name, domain_id,
description=description,
profile_id=profile_id,
source_groups=[source_group],
dest_groups=[dest_group],
tenant=TEST_TENANT)
expected_map_def = policy_defs.CommunicationMapDef(
domain_id=domain_id,
@ -755,16 +802,18 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
obj = self.resourceApi.get_by_name(domain_id, name,
tenant=TEST_TENANT)
self.assertIsNotNone(obj)
expected_def = policy_defs.CommunicationMapDef(domain_id,
tenant=TEST_TENANT)
expected_def = policy_defs.CommunicationMapEntryDef(
domain_id,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_list(self):
domain_id = '111'
with mock.patch.object(self.policy_api, "list") as api_call:
self.resourceApi.list(domain_id, tenant=TEST_TENANT)
expected_def = policy_defs.CommunicationMapDef(domain_id=domain_id,
tenant=TEST_TENANT)
expected_def = policy_defs.CommunicationMapEntryDef(
domain_id=domain_id,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
def test_update(self):
@ -777,7 +826,8 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
profile_id = 'nc1'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(domain_id, id,
name=name,
description=description,
@ -817,12 +867,15 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
ip_address = '1.1.1.1'
username = 'admin'
password = 'zzz'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name, description=description,
ip_address=ip_address,
username=username,
password=password,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(
name, description=description,
ip_address=ip_address,
username=username,
password=password,
tenant=TEST_TENANT)
expected_def = policy_defs.EnforcementPointDef(
ep_id=mock.ANY,
name=name,
@ -870,9 +923,8 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
name = 'new name'
username = 'admin'
password = 'zzz'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
username=username,
@ -883,7 +935,6 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
expected_dict = {'display_name': name,
'username': username,
'password': password}
self.assert_called_with_def(get_call, expected_def)
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)
@ -899,11 +950,13 @@ class TestPolicyDeploymentMap(NsxPolicyLibTestCase):
description = 'desc'
domain_id = 'domain1'
ep_id = 'ep1'
with mock.patch.object(self.policy_api, "create") as api_call:
self.resourceApi.create(name, description=description,
ep_id=ep_id,
domain_id=domain_id,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
self.resourceApi.create_or_overwrite(name,
description=description,
ep_id=ep_id,
domain_id=domain_id,
tenant=TEST_TENANT)
expected_def = policy_defs.DeploymentMapDef(
map_id=mock.ANY,
name=name,
@ -950,9 +1003,8 @@ class TestPolicyDeploymentMap(NsxPolicyLibTestCase):
name = 'new name'
domain_id = 'domain2'
ep_id = 'ep2'
with mock.patch.object(self.policy_api, "get",
return_value={}) as get_call,\
mock.patch.object(self.policy_api, "update") as update_call:
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
self.resourceApi.update(id,
name=name,
ep_id=ep_id,
@ -966,6 +1018,5 @@ class TestPolicyDeploymentMap(NsxPolicyLibTestCase):
expected_dict = {'display_name': name,
'enforcement_point_paths': [ep_path],
'domain_path': domain_path}
self.assert_called_with_def(get_call, expected_def)
self.assert_called_with_def_and_dict(
update_call, expected_def, expected_dict)

View File

@ -49,7 +49,8 @@ class NsxLibBase(object):
self.client = client.NSX3Client(
self.cluster,
nsx_api_managers=self.nsxlib_config.nsx_api_managers,
max_attempts=self.nsxlib_config.max_attempts)
max_attempts=self.nsxlib_config.max_attempts,
url_path_base=self.client_url_prefix)
self.general_apis = utils.NsxLibApiBase(
self.client, self.nsxlib_config)
@ -63,7 +64,12 @@ class NsxLibBase(object):
def set_config(self, nsxlib_config):
"""Set config user provided and extend it according to application"""
self.nsxlib_config = nsxlib_config
self.nsxlib_config.extend(keepalive_section=self.keepalive_section)
self.nsxlib_config.extend(keepalive_section=self.keepalive_section,
url_base=self.client_url_prefix)
@abc.abstractproperty
def client_url_prefix(self):
pass
@abc.abstractproperty
def keepalive_section(self):
@ -202,6 +208,10 @@ class NsxLib(NsxLibBase):
return False
@property
def client_url_prefix(self):
return client.NSX3Client.NSX_V1_API_PREFIX
class NsxPolicyLib(NsxLibBase):
@ -231,3 +241,7 @@ class NsxPolicyLib(NsxLibBase):
return True
return False
@property
def client_url_prefix(self):
return client.NSX3Client.NSX_POLICY_V1_API_PREFIX

View File

@ -226,13 +226,15 @@ class JSONRESTClient(RESTClient):
class NSX3Client(JSONRESTClient):
_NSX_V1_API_PREFIX = 'api/v1/'
NSX_V1_API_PREFIX = 'api/v1/'
NSX_POLICY_V1_API_PREFIX = 'policy/api/v1/'
def __init__(self, connection, url_prefix=None,
default_headers=None,
nsx_api_managers=None,
max_attempts=utils.DEFAULT_MAX_ATTEMPTS,
client_obj=None):
client_obj=None,
url_path_base=NSX_V1_API_PREFIX):
# If the client obj is defined - copy configuration from it
if client_obj:
@ -242,12 +244,12 @@ class NSX3Client(JSONRESTClient):
self.nsx_api_managers = nsx_api_managers or []
self.max_attempts = max_attempts
url_prefix = url_prefix or NSX3Client._NSX_V1_API_PREFIX
if url_prefix and NSX3Client._NSX_V1_API_PREFIX not in url_prefix:
url_prefix = url_prefix or url_path_base
if url_prefix and url_path_base not in url_prefix:
if url_prefix.startswith('http'):
url_prefix += '/' + NSX3Client._NSX_V1_API_PREFIX
url_prefix += '/' + url_path_base
else:
url_prefix = "%s/%s" % (NSX3Client._NSX_V1_API_PREFIX,
url_prefix = "%s/%s" % (url_path_base,
url_prefix or '')
self.max_attempts = max_attempts

View File

@ -150,7 +150,9 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
return "%s-%s" % (requests.__title__, requests.__version__)
def validate_connection(self, cluster_api, endpoint, conn):
client = nsx_client.NSX3Client(conn, url_prefix=endpoint.provider.url)
client = nsx_client.NSX3Client(
conn, url_prefix=endpoint.provider.url,
url_path_base=cluster_api.nsxlib_config.url_base)
keepalive_section = cluster_api.nsxlib_config.keepalive_section
result = client.get(keepalive_section, silent=True)
# If keeplive section returns a list, it is assumed to be non-empty

View File

@ -118,9 +118,10 @@ class NsxLibConfig(object):
'dhcp_profile_uuid is not used by the nsxlib, and will '
'be removed from its configuration in the future.')
def extend(self, keepalive_section):
def extend(self, keepalive_section, url_base=None):
"""Called by library code to initialize application-specific data"""
self.keepalive_section = keepalive_section
self.url_base = url_base
def _attribute_by_index(self, scalar_or_list, index):
if isinstance(scalar_or_list, list):

View File

@ -36,8 +36,7 @@ class ResourceDef(object):
self.body = {}
def get_obj_dict(self):
body = {'_revision': 0,
'display_name': self.name,
body = {'display_name': self.name,
'description': self.description}
if self.id:
body['id'] = self.id
@ -67,9 +66,20 @@ class ResourceDef(object):
def sub_entries_path():
pass
def update_attributes_in_body(self, body, **kwargs):
self.body = body
def _get_body_from_kwargs(self, **kwargs):
if 'body' in kwargs:
body = kwargs['body']
else:
body = {}
return body
def update_attributes_in_body(self, **kwargs):
self.body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
for key, value in six.iteritems(kwargs):
if key == 'body':
continue
if value is not None:
if key == 'name':
self.body['display_name'] = value
@ -164,13 +174,16 @@ class GroupDef(ResourceDef):
for condition in self.conditions]
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
# Fix params that need special conversions
if kwargs.get('conditions') is not None:
body['expression'] = [cond.get_obj_dict()
for cond in kwargs['conditions']]
del kwargs['conditions']
super(GroupDef, self).update_attributes_in_body(body, **kwargs)
super(GroupDef, self).update_attributes_in_body(body=body, **kwargs)
class ServiceDef(ResourceDef):
@ -231,8 +244,12 @@ class L4ServiceEntryDef(ResourceDef):
body['destination_ports'] = self.dest_ports
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
# Fix params that need special conversions
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
if kwargs.get('protocol') is not None:
body['l4_protocol'] = kwargs['protocol'].upper()
del kwargs['protocol']
@ -240,7 +257,7 @@ class L4ServiceEntryDef(ResourceDef):
body['destination_ports'] = kwargs['dest_ports']
del kwargs['dest_ports']
super(L4ServiceEntryDef, self).update_attributes_in_body(
body, **kwargs)
body=body, **kwargs)
class CommunicationProfileDef(ResourceDef):
@ -270,9 +287,9 @@ class CommunicationProfileDef(ResourceDef):
entryDef = CommunicationProfileEntryDef()
return entryDef.get_last_section_dict_key
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
super(CommunicationProfileDef, self).update_attributes_in_body(
body, **kwargs)
**kwargs)
# make sure entries are there
entries_path = self.sub_entries_path()
if entries_path not in self.body:
@ -307,12 +324,15 @@ class CommunicationProfileEntryDef(ResourceDef):
body['action'] = self.action
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
if kwargs.get('action') is not None:
body['action'] = kwargs['action'].upper()
del kwargs['action']
super(CommunicationProfileEntryDef, self).update_attributes_in_body(
body, **kwargs)
body=body, **kwargs)
class CommunicationMapDef(ResourceDef):
@ -380,7 +400,10 @@ class CommunicationMapEntryDef(ResourceDef):
body['communication_profile_path'] = self.profile_path
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
# Fix params that need special conversions
if kwargs.get('profile_id') is not None:
profile_path = self.get_profile_path(kwargs['profile_id'])
@ -400,7 +423,7 @@ class CommunicationMapEntryDef(ResourceDef):
del kwargs['source_groups']
super(CommunicationMapEntryDef, self).update_attributes_in_body(
body, **kwargs)
body=body, **kwargs)
class EnforcementPointDef(ResourceDef):
@ -411,6 +434,7 @@ class EnforcementPointDef(ResourceDef):
ip_address=None,
username=None,
password=None,
thumbprint=None,
ep_type='NSXT',
tenant=policy_constants.POLICY_INFRA_TENANT):
super(EnforcementPointDef, self).__init__()
@ -422,6 +446,7 @@ class EnforcementPointDef(ResourceDef):
self.username = username
self.password = password
self.ip_address = ip_address
self.thumbprint = thumbprint
self.parent_ids = (tenant)
@property
@ -433,8 +458,7 @@ class EnforcementPointDef(ResourceDef):
body = super(EnforcementPointDef, self).get_obj_dict()
body['id'] = self.id
body['connection_info'] = [{'fqdn': 'abc',
'thumbprint':
policy_constants.DEFAULT_THUMBPRINT,
'thumbprint': self.thumbprint,
'username': self.username,
'password': self.password,
'ip_address': self.ip_address,
@ -443,24 +467,21 @@ class EnforcementPointDef(ResourceDef):
body['resource_type'] = 'EnforcementPoint'
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
# Fix params that need special conversions
if body.get('connection_info'):
body['connection_info'][0]['resource_type'] = 'NSXTConnectionInfo'
if kwargs.get('username') is not None:
body['connection_info'][0]['username'] = kwargs['username']
del kwargs['username']
if kwargs.get('password') is not None:
body['connection_info'][0]['password'] = kwargs['password']
del kwargs['password']
if kwargs.get('ip_address') is not None:
body['connection_info'][0]['ip_address'] = kwargs['ip_address']
del kwargs['ip_address']
for attr in ('username', 'password', 'ip_address', 'thumbprint'):
if kwargs.get(attr) is not None:
body['connection_info'][0][attr] = kwargs[attr]
del kwargs[attr]
super(EnforcementPointDef, self).update_attributes_in_body(
body, **kwargs)
body=body, **kwargs)
# Currently assumes one deployment point per id
@ -497,7 +518,10 @@ class DeploymentMapDef(ResourceDef):
body['enforcement_point_paths'] = [self.ep_path]
return body
def update_attributes_in_body(self, body, **kwargs):
def update_attributes_in_body(self, **kwargs):
body = self._get_body_from_kwargs(**kwargs)
if 'body' in kwargs:
del kwargs['body']
# Fix params that need special conversions
if kwargs.get('domain_id') is not None:
domain_id = kwargs.get('domain_id')
@ -514,7 +538,7 @@ class DeploymentMapDef(ResourceDef):
del kwargs['ep_id']
super(DeploymentMapDef, self).update_attributes_in_body(
body, **kwargs)
body=body, **kwargs)
class NsxPolicyApi(object):
@ -522,9 +546,18 @@ class NsxPolicyApi(object):
def __init__(self, client):
self.client = client
def create(self, resource_def):
def create_or_update(self, resource_def):
"""Create or update a policy object.
This api will update an existing object, or create a new one if it
doesn't exist.
The policy API supports POST for update too
"""
path = resource_def.get_resource_path()
return self.client.update(path, resource_def.get_obj_dict())
body = resource_def.body
if not body:
body = resource_def.get_obj_dict()
return self.client.create(path, body)
def create_with_parent(self, parent_def, resource_def):
path = parent_def.get_resource_path()
@ -535,7 +568,7 @@ class NsxPolicyApi(object):
else:
child_dict_key = resource_def.get_last_section_dict_key
body[child_dict_key] = [resource_def.get_obj_dict()]
return self.client.update(path, body)
return self.client.create(path, body)
def delete(self, resource_def):
path = resource_def.get_resource_path()
@ -548,8 +581,3 @@ class NsxPolicyApi(object):
def list(self, resource_def):
path = resource_def.get_section_path()
return self.client.list(path)
def update(self, resource_def):
path = resource_def.get_resource_path()
body = resource_def.body
return self.client.update(path, body)

View File

@ -54,7 +54,7 @@ class NsxPolicyResourceBase(object):
pass
@abc.abstractmethod
def create(self, *args, **kwargs):
def create_or_overwrite(self, *args, **kwargs):
pass
@abc.abstractmethod
@ -78,14 +78,14 @@ class NsxPolicyResourceBase(object):
class NsxPolicyDomainApi(NsxPolicyResourceBase):
"""NSX Policy Domain."""
def create(self, name, domain_id=None, description=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(self, name, domain_id=None, description=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
domain_id = self._init_obj_uuid(domain_id)
domain_def = policy_defs.DomainDef(domain_id=domain_id,
name=name,
description=description,
tenant=tenant)
return self.policy_api.create(domain_def)
return self.policy_api.create_or_update(domain_def)
def delete(self, domain_id, tenant=policy_constants.POLICY_INFRA_TENANT):
domain_def = policy_defs.DomainDef(domain_id, tenant=tenant)
@ -103,24 +103,22 @@ class NsxPolicyDomainApi(NsxPolicyResourceBase):
tenant=policy_constants.POLICY_INFRA_TENANT):
domain_def = policy_defs.DomainDef(domain_id=domain_id,
tenant=tenant)
# Get the current data, and update it with the new values
domain = self.get(domain_id, tenant=tenant)
domain_def.update_attributes_in_body(domain,
name=name,
domain_def.update_attributes_in_body(name=name,
description=description)
# update the backend
return self.policy_api.update(domain_def)
return self.policy_api.create_or_update(domain_def)
class NsxPolicyGroupApi(NsxPolicyResourceBase):
"""NSX Policy Group (under a Domain) with a single condition."""
def create(self, name, domain_id, group_id=None,
description=None,
cond_val=None,
cond_key=policy_constants.CONDITION_KEY_TAG,
cond_op=policy_constants.CONDITION_OP_EQUALS,
cond_member_type=policy_constants.CONDITION_MEMBER_PORT,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(
self, name, domain_id, group_id=None,
description=None,
cond_val=None,
cond_key=policy_constants.CONDITION_KEY_TAG,
cond_op=policy_constants.CONDITION_OP_EQUALS,
cond_member_type=policy_constants.CONDITION_MEMBER_PORT,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Create a group with/without a condition.
Empty condition value will result a group with no condition.
@ -142,7 +140,7 @@ class NsxPolicyGroupApi(NsxPolicyResourceBase):
description=description,
conditions=conditions,
tenant=tenant)
return self.policy_api.create(group_def)
return self.policy_api.create_or_update(group_def)
def delete(self, domain_id, group_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
@ -180,12 +178,10 @@ class NsxPolicyGroupApi(NsxPolicyResourceBase):
group_def = policy_defs.GroupDef(domain_id=domain_id,
group_id=group_id,
tenant=tenant)
# Get the current data, and update it with the new values
group = self.get(domain_id, group_id, tenant=tenant)
group_def.update_attributes_in_body(group, name=name,
group_def.update_attributes_in_body(name=name,
description=description)
# update the backend
return self.policy_api.update(group_def)
return self.policy_api.create_or_update(group_def)
def update_condition(
self, domain_id, group_id,
@ -212,10 +208,11 @@ class NsxPolicyGroupApi(NsxPolicyResourceBase):
else:
conditions = []
# Get the current data, and update it with the new values
# We need to do that here because of the conditions data
group = self.get(domain_id, group_id, tenant=tenant)
group_def.update_attributes_in_body(group, conditions=conditions)
group_def.update_attributes_in_body(body=group, conditions=conditions)
# update the backend
return self.policy_api.update(group_def)
return self.policy_api.create_or_update(group_def)
class NsxPolicyL4ServiceApi(NsxPolicyResourceBase):
@ -225,9 +222,9 @@ class NsxPolicyL4ServiceApi(NsxPolicyResourceBase):
and multiple service entries per service.
At this point this is not supported here.
"""
def create(self, name, service_id=None, description=None,
protocol=policy_constants.TCP, dest_ports=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(self, name, service_id=None, description=None,
protocol=policy_constants.TCP, dest_ports=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
service_id = self._init_obj_uuid(service_id)
service_def = policy_defs.ServiceDef(service_id=service_id,
name=name,
@ -266,16 +263,17 @@ class NsxPolicyL4ServiceApi(NsxPolicyResourceBase):
name=None, description=None,
protocol=None, dest_ports=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
# TODO(asarfaty): This action fails on backend
entry_id = srv_entry['id']
entry_def = policy_defs.L4ServiceEntryDef(service_id=service_id,
service_entry_id=entry_id,
tenant=tenant)
entry_def.update_attributes_in_body(srv_entry, name=name,
entry_def.update_attributes_in_body(body=srv_entry, name=name,
description=description,
protocol=protocol,
dest_ports=dest_ports)
self.policy_api.update(entry_def)
self.policy_api.create_or_update(entry_def)
def update(self, service_id, name=None, description=None,
protocol=None, dest_ports=None,
@ -288,11 +286,11 @@ class NsxPolicyL4ServiceApi(NsxPolicyResourceBase):
# update the service itself
service_def = policy_defs.ServiceDef(service_id=service_id,
tenant=tenant)
service_def.update_attributes_in_body(service, name=name,
service_def.update_attributes_in_body(name=name,
description=description)
# update the backend
updated_service = self.policy_api.update(service_def)
updated_service = self.policy_api.create_or_update(service_def)
else:
updated_service = service
@ -320,9 +318,10 @@ class NsxPolicyCommunicationProfileApi(NsxPolicyResourceBase):
profile.
At this point this is not supported here.
"""
def create(self, name, profile_id=None, description=None,
services=None, action=policy_constants.ACTION_ALLOW,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(self, name, profile_id=None, description=None,
services=None,
action=policy_constants.ACTION_ALLOW,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Create a Communication profile with a single entry.
Services should be a list of service ids
@ -371,12 +370,13 @@ class NsxPolicyCommunicationProfileApi(NsxPolicyResourceBase):
profile_id=profile_id,
profile_entry_id=entry_id,
tenant=tenant)
entry_def.update_attributes_in_body(profile_entry, name=name,
entry_def.update_attributes_in_body(body=profile_entry,
name=name,
description=description,
services=services,
action=action)
self.policy_api.update(entry_def)
self.policy_api.create_or_update(entry_def)
def update(self, profile_id, name=None, description=None,
services=None, action=None,
@ -388,11 +388,11 @@ class NsxPolicyCommunicationProfileApi(NsxPolicyResourceBase):
# update the profile itself
profile_def = policy_defs.CommunicationProfileDef(
profile_id=profile_id, tenant=tenant)
profile_def.update_attributes_in_body(profile, name=name,
profile_def.update_attributes_in_body(name=name,
description=description)
# update the backend
updated_profile = self.policy_api.update(profile_def)
updated_profile = self.policy_api.create_or_update(profile_def)
else:
updated_profile = profile
@ -419,22 +419,28 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
def _get_last_seq_num(self, domain_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
# get the current entries, and choose the next unused sequence number
communication_maps = self.list(domain_id, tenant=tenant)
if not len(communication_maps):
try:
com_entries = self.list(domain_id, tenant=tenant)
except exceptions.ResourceNotFound:
return -1
if not com_entries:
return 0
seq_nums = [int(cm['sequence_number']) for cm in communication_maps]
seq_nums = [int(cm['sequence_number']) for cm in com_entries]
seq_nums.sort()
return seq_nums[-1]
def create(self, name, domain_id, map_id=None,
description=None, sequence_number=None, profile_id=None,
source_groups=None, dest_groups=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Create a CommunicationtMap.
def create_or_overwrite(self, name, domain_id, map_id=None,
description=None, sequence_number=None,
profile_id=None,
source_groups=None, dest_groups=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Create CommunicationMapEntry.
source_groups/dest_groups should be a list of group ids belonging
to the domain.
NOTE: In multi-connection environment, it is recommended to execute
this call under lock to prevent race condition where two entries
end up with same sequence number.
"""
# Validate and convert inputs
map_id = self._init_obj_uuid(map_id)
@ -447,7 +453,10 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
# get the next available sequence number
last_sequence = self._get_last_seq_num(domain_id, tenant=tenant)
if not sequence_number:
sequence_number = last_sequence + 1
if last_sequence < 0:
sequence_number = 1
else:
sequence_number = last_sequence + 1
entry_def = policy_defs.CommunicationMapEntryDef(
domain_id=domain_id,
@ -460,12 +469,14 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
profile_id=profile_id,
tenant=tenant)
if last_sequence == 0:
if last_sequence < 0:
# if communication map is absent, we need to create it
map_def = policy_defs.CommunicationMapDef(domain_id, tenant)
return self.policy_api.create_with_parent(map_def, entry_def)
map_result = self.policy_api.create_with_parent(map_def, entry_def)
# return the created entry
return map_result['communication_entries'][0]
return self.policy_api.create(entry_def)
return self.policy_api.create_or_update(entry_def)
def delete(self, domain_id, map_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
@ -485,14 +496,14 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
def get_by_name(self, domain_id, name,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Return first communication map matched by name of this domain"""
"""Return first communication map entry matched by name"""
return super(NsxPolicyCommunicationMapApi, self).get_by_name(
name, domain_id, tenant=tenant)
def list(self, domain_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""List all the map entries of a specific domain."""
map_def = policy_defs.CommunicationMapDef(
map_def = policy_defs.CommunicationMapEntryDef(
domain_id=domain_id,
tenant=tenant)
return self.policy_api.list(map_def)['results']
@ -505,10 +516,18 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
domain_id=domain_id,
map_id=map_id,
tenant=tenant)
# Get the current data, and update it with the new values
comm_map = self.get(domain_id, map_id, tenant=tenant)
try:
comm_map = self.get(domain_id, map_id, tenant=tenant)
except exceptions.ResourceNotFound:
return self.create_or_overwrite(name, domain_id, map_id,
description, sequence_number,
profile_id, source_groups,
dest_groups, tenant)
map_def.update_attributes_in_body(
comm_map,
body=comm_map,
name=name,
description=description,
sequence_number=sequence_number,
@ -517,16 +536,16 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
dest_groups=dest_groups)
# update the backend
return self.policy_api.update(map_def)
return self.policy_api.create_or_update(map_def)
class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
"""NSX Policy Enforcement Point."""
def create(self, name, ep_id=None, description=None,
ip_address=None, username=None,
password=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(self, name, ep_id=None, description=None,
ip_address=None, username=None,
password=None, thumbprint=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
if not ip_address or not username or password is None:
err_msg = (_("Cannot create an enforcement point without "
"ip_address, username and password"))
@ -539,8 +558,9 @@ class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
ip_address=ip_address,
username=username,
password=password,
thumbprint=thumbprint,
tenant=tenant)
return self.policy_api.create(ep_def)
return self.policy_api.create_or_update(ep_def)
def delete(self, ep_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
@ -559,7 +579,8 @@ class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
return self.policy_api.list(ep_def)['results']
def update(self, ep_id, name=None, description=None,
ip_address=None, username=None, password=None,
ip_address=None, username=None,
password=None, thumbprint=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
"""Update the enforcement point.
@ -572,24 +593,22 @@ class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
raise exceptions.ManagerError(details=err_msg)
ep_def = policy_defs.EnforcementPointDef(ep_id=ep_id, tenant=tenant)
# Get the current data, and update it with the new values
ep = self.get(ep_id, tenant=tenant)
ep_def.update_attributes_in_body(ep,
name=name,
ep_def.update_attributes_in_body(name=name,
description=description,
ip_address=ip_address,
username=username,
password=password)
password=password,
thumbprint=thumbprint)
# update the backend
return self.policy_api.update(ep_def)
return self.policy_api.create_or_update(ep_def)
class NsxPolicyDeploymentMapApi(NsxPolicyResourceBase):
"""NSX Policy Deployment Map."""
def create(self, name, map_id=None, description=None,
ep_id=None, domain_id=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
def create_or_overwrite(self, name, map_id=None, description=None,
ep_id=None, domain_id=None,
tenant=policy_constants.POLICY_INFRA_TENANT):
map_id = self._init_obj_uuid(map_id)
map_def = policy_defs.DeploymentMapDef(
map_id=map_id,
@ -598,7 +617,7 @@ class NsxPolicyDeploymentMapApi(NsxPolicyResourceBase):
ep_id=ep_id,
domain_id=domain_id,
tenant=tenant)
return self.policy_api.create(map_def)
return self.policy_api.create_or_update(map_def)
def delete(self, map_id,
tenant=policy_constants.POLICY_INFRA_TENANT):
@ -621,12 +640,9 @@ class NsxPolicyDeploymentMapApi(NsxPolicyResourceBase):
tenant=policy_constants.POLICY_INFRA_TENANT):
map_def = policy_defs.DeploymentMapDef(
map_id=map_id, tenant=tenant)
# Get the current data, and update it with the new values
map_obj = self.get(map_id, tenant=tenant)
map_def.update_attributes_in_body(map_obj,
name=name,
map_def.update_attributes_in_body(name=name,
description=description,
ep_id=ep_id,
domain_id=domain_id)
# update the backend
return self.policy_api.update(map_def)
return self.policy_api.create_or_update(map_def)