Refactor policy code to match the new NSX
The NSX policy manager changed the supported apis: - Use PATCH instead of POST - Remove the Communication profiles - Add ID to communication maps, and allow multiple maps Change-Id: I8cb2dd21892fd9e0878653f5667187fef76a3315
This commit is contained in:
parent
c25f33e163
commit
31f2095cc1
@ -44,7 +44,7 @@ class TestPolicyDomain(TestPolicyApi):
|
||||
'prokaryotic cells',
|
||||
'typically characterized by membrane lipids')
|
||||
self.policy_api.create_or_update(domain_def)
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/archaea',
|
||||
data=domain_def.get_obj_dict())
|
||||
|
||||
@ -74,7 +74,7 @@ class TestPolicyGroup(TestPolicyApi):
|
||||
'cats',
|
||||
'felis catus')
|
||||
self.policy_api.create_or_update(group_def)
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', 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('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/eukarya',
|
||||
data=data)
|
||||
|
||||
@ -115,7 +115,7 @@ class TestPolicyGroup(TestPolicyApi):
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'groups': [expected_group]}
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/eukarya',
|
||||
data=expected_data)
|
||||
|
||||
@ -132,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('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/eukarya',
|
||||
data=data)
|
||||
|
||||
@ -148,7 +148,7 @@ class TestPolicyService(TestPolicyApi):
|
||||
def test_create(self):
|
||||
service_def = policy.ServiceDef('roomservice')
|
||||
self.policy_api.create_or_update(service_def)
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/services/roomservice',
|
||||
data=service_def.get_obj_dict())
|
||||
|
||||
@ -170,7 +170,7 @@ class TestPolicyService(TestPolicyApi):
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'service_entries': [expected_entry]}
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/services/roomservice',
|
||||
data=expected_data)
|
||||
|
||||
@ -190,123 +190,95 @@ class TestPolicyService(TestPolicyApi):
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'service_entries': [expected_entry]}
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/services/icmpservice',
|
||||
data=expected_data)
|
||||
|
||||
|
||||
class TestPolicyCommunicationProfile(TestPolicyApi):
|
||||
|
||||
def test_create(self):
|
||||
profile_def = policy.CommunicationProfileDef('rental')
|
||||
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())
|
||||
|
||||
def test_create_with_parent(self):
|
||||
profile_def = policy.CommunicationProfileDef('rental')
|
||||
entry_def = policy.CommunicationProfileEntryDef(
|
||||
'rental',
|
||||
'room1',
|
||||
description='includes roomservice',
|
||||
services=["roomservice"])
|
||||
|
||||
self.policy_api.create_with_parent(profile_def, entry_def)
|
||||
expected_entry = {'id': 'room1',
|
||||
'display_name': None,
|
||||
'description': 'includes roomservice',
|
||||
'services': ["roomservice"],
|
||||
'action': 'ALLOW'}
|
||||
expected_data = {'id': 'rental',
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'communication_profile_entries': [expected_entry]}
|
||||
self.assert_json_call('POST', self.client,
|
||||
'infra/communication-profiles/rental',
|
||||
data=expected_data)
|
||||
|
||||
|
||||
class TestPolicyCommunicationMap(TestPolicyApi):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPolicyCommunicationMap, self).setUp()
|
||||
self.entry1 = policy.CommunicationMapEntryDef(
|
||||
'd1', 'cm1',
|
||||
'd1', 'cm1', 'en1',
|
||||
sequence_number=12,
|
||||
source_groups=["group1",
|
||||
"group2"],
|
||||
dest_groups=["group1"],
|
||||
profile_id="profile1")
|
||||
service_id="service1")
|
||||
|
||||
self.entry2 = policy.CommunicationMapEntryDef(
|
||||
'd1', 'cm2',
|
||||
'd1', 'cm2', 'en2',
|
||||
sequence_number=13,
|
||||
source_groups=["group1",
|
||||
"group2"],
|
||||
dest_groups=["group3"],
|
||||
profile_id="profile2")
|
||||
service_id="service2")
|
||||
|
||||
self.expected_data1 = {'id': 'cm1',
|
||||
self.expected_data1 = {'id': 'en1',
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'sequence_number': 12,
|
||||
'action': 'ALLOW',
|
||||
'scope': ['ANY'],
|
||||
'source_groups':
|
||||
['/infra/domains/d1/groups/group1',
|
||||
'/infra/domains/d1/groups/group2'],
|
||||
'destination_groups':
|
||||
['/infra/domains/d1/groups/group1'],
|
||||
'communication_profile_path':
|
||||
'/infra/communication-profiles/profile1'}
|
||||
'services':
|
||||
['/infra/services/service1']}
|
||||
|
||||
self.expected_data2 = {'id': 'cm2',
|
||||
self.expected_data2 = {'id': 'en2',
|
||||
'display_name': None,
|
||||
'description': None,
|
||||
'sequence_number': 13,
|
||||
'action': 'ALLOW',
|
||||
'scope': ['ANY'],
|
||||
'source_groups':
|
||||
['/infra/domains/d1/groups/group1',
|
||||
'/infra/domains/d1/groups/group2'],
|
||||
'destination_groups':
|
||||
['/infra/domains/d1/groups/group3'],
|
||||
'communication_profile_path':
|
||||
'/infra/communication-profiles/profile2'}
|
||||
'services':
|
||||
['/infra/services/service2']}
|
||||
|
||||
def test_create_with_one_entry(self):
|
||||
map_def = policy.CommunicationMapDef('d1')
|
||||
map_def = policy.CommunicationMapDef(domain_id='d1', map_id='cm1')
|
||||
|
||||
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('POST', self.client,
|
||||
'infra/domains/d1/communication-map',
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/d1/communication-maps/cm1',
|
||||
data=expected_data)
|
||||
|
||||
def test_create_with_two_entries(self):
|
||||
map_def = policy.CommunicationMapDef('d1')
|
||||
map_def = policy.CommunicationMapDef(domain_id='d1', map_id='cm1')
|
||||
|
||||
self.policy_api.create_with_parent(map_def,
|
||||
[self.entry1, self.entry2])
|
||||
expected_data = map_def.get_obj_dict()
|
||||
expected_data['communication_entries'] = [self.expected_data1,
|
||||
self.expected_data2]
|
||||
self.assert_json_call('POST', self.client,
|
||||
'infra/domains/d1/communication-map',
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/d1/communication-maps/cm1',
|
||||
data=expected_data)
|
||||
|
||||
def test_update_entry(self):
|
||||
self.policy_api.create_or_update(self.entry1)
|
||||
|
||||
self.assert_json_call('POST', self.client,
|
||||
'infra/domains/d1/communication-map/'
|
||||
'communication-entries/cm1',
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/d1/communication-maps/cm1/'
|
||||
'communication-entries/en1',
|
||||
data=self.expected_data1)
|
||||
|
||||
def test_delete_entry(self):
|
||||
self.policy_api.delete(self.entry2)
|
||||
|
||||
self.assert_json_call('DELETE', self.client,
|
||||
'infra/domains/d1/communication-map/'
|
||||
'communication-entries/cm2')
|
||||
'infra/domains/d1/communication-maps/cm2/'
|
||||
'communication-entries/en2')
|
||||
|
||||
|
||||
class TestPolicyEnforcementPoint(TestPolicyApi):
|
||||
@ -319,7 +291,7 @@ class TestPolicyEnforcementPoint(TestPolicyApi):
|
||||
|
||||
self.policy_api.create_or_update(ep_def)
|
||||
ep_path = policy.EnforcementPointDef('ep1').get_resource_path()
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
ep_path,
|
||||
data=ep_def.get_obj_dict())
|
||||
|
||||
@ -336,6 +308,6 @@ class TestPolicyDeploymentMap(TestPolicyApi):
|
||||
'description': None,
|
||||
'enforcement_point_path': ep_path}
|
||||
|
||||
self.assert_json_call('POST', self.client,
|
||||
self.assert_json_call('PATCH', self.client,
|
||||
'infra/domains/d1/domain-deployment-maps/dm1',
|
||||
data=expected_data)
|
||||
|
@ -418,7 +418,7 @@ class TestPolicyService(NsxPolicyLibTestCase):
|
||||
|
||||
def test_update(self):
|
||||
id = '111'
|
||||
name = 'new name'
|
||||
name = 'newName'
|
||||
description = 'new desc'
|
||||
with mock.patch.object(self.policy_api, "get",
|
||||
return_value={}) as get_call,\
|
||||
@ -431,47 +431,14 @@ class TestPolicyService(NsxPolicyLibTestCase):
|
||||
expected_def = policy_defs.ServiceDef(service_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'service_entries': []}
|
||||
'description': description}
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
def test_update_entry(self):
|
||||
id = '111'
|
||||
protocol = 'udp'
|
||||
dest_ports = [555]
|
||||
service_entry_id = '222'
|
||||
service_entry = {'id': service_entry_id}
|
||||
|
||||
with mock.patch.object(
|
||||
self.policy_api, "get",
|
||||
return_value={'service_entries': [service_entry]}) as get_call,\
|
||||
mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(id,
|
||||
protocol=protocol,
|
||||
dest_ports=dest_ports,
|
||||
tenant=TEST_TENANT)
|
||||
# get will be called for the entire service
|
||||
expected_def = policy_defs.ServiceDef(service_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service entry only
|
||||
expected_entry_def = policy_defs.L4ServiceEntryDef(
|
||||
service_id=id,
|
||||
service_entry_id=service_entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': service_entry_id,
|
||||
'l4_protocol': protocol.upper(),
|
||||
'destination_ports': dest_ports}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict)
|
||||
|
||||
def test_update_all(self):
|
||||
id = '111'
|
||||
name = 'new name'
|
||||
name = 'newName'
|
||||
description = 'new desc'
|
||||
protocol = 'udp'
|
||||
dest_ports = [555]
|
||||
@ -496,26 +463,17 @@ class TestPolicyService(NsxPolicyLibTestCase):
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service and entry (2 calls)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'service_entries': []}
|
||||
'service_entries': [{
|
||||
'id': service_entry_id,
|
||||
'display_name': name,
|
||||
'description': description,
|
||||
'l4_protocol': protocol.upper(),
|
||||
'destination_ports': dest_ports}]}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
expected_entry_def = policy_defs.L4ServiceEntryDef(
|
||||
service_id=id,
|
||||
service_entry_id=service_entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': service_entry_id,
|
||||
'display_name': name,
|
||||
'description': description,
|
||||
'l4_protocol': protocol.upper(),
|
||||
'destination_ports': dest_ports}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict,
|
||||
call_num=1)
|
||||
|
||||
|
||||
class TestPolicyIcmpService(NsxPolicyLibTestCase):
|
||||
|
||||
@ -582,7 +540,7 @@ class TestPolicyIcmpService(NsxPolicyLibTestCase):
|
||||
|
||||
def test_update(self):
|
||||
id = '111'
|
||||
name = 'new name'
|
||||
name = 'new_name'
|
||||
description = 'new desc'
|
||||
with mock.patch.object(self.policy_api, "get",
|
||||
return_value={}) as get_call,\
|
||||
@ -595,44 +553,14 @@ class TestPolicyIcmpService(NsxPolicyLibTestCase):
|
||||
expected_def = policy_defs.ServiceDef(service_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'service_entries': []}
|
||||
'description': description}
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
def test_update_entry(self):
|
||||
id = '111'
|
||||
icmp_code = 12
|
||||
service_entry_id = '222'
|
||||
service_entry = {'id': service_entry_id}
|
||||
|
||||
with mock.patch.object(
|
||||
self.policy_api, "get",
|
||||
return_value={'service_entries': [service_entry]}) as get_call,\
|
||||
mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(id,
|
||||
icmp_code=icmp_code,
|
||||
tenant=TEST_TENANT)
|
||||
# get will be called for the entire service
|
||||
expected_def = policy_defs.ServiceDef(service_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service entry only
|
||||
expected_entry_def = policy_defs.IcmpServiceEntryDef(
|
||||
service_id=id,
|
||||
service_entry_id=service_entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': service_entry_id,
|
||||
'icmp_code': icmp_code}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict)
|
||||
|
||||
def test_update_all(self):
|
||||
id = '111'
|
||||
name = 'new name'
|
||||
name = 'newName'
|
||||
description = 'new desc'
|
||||
version = 6
|
||||
icmp_type = 3
|
||||
@ -659,194 +587,18 @@ class TestPolicyIcmpService(NsxPolicyLibTestCase):
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service and entry (2 calls)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'service_entries': []}
|
||||
'service_entries': [{
|
||||
'id': service_entry_id,
|
||||
'display_name': name,
|
||||
'description': description,
|
||||
'protocol': 'ICMPv6',
|
||||
'icmp_type': icmp_type,
|
||||
'icmp_code': icmp_code}]}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
expected_entry_def = policy_defs.IcmpServiceEntryDef(
|
||||
service_id=id,
|
||||
service_entry_id=service_entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': service_entry_id,
|
||||
'display_name': name,
|
||||
'description': description,
|
||||
'protocol': 'ICMPv6',
|
||||
'icmp_type': icmp_type,
|
||||
'icmp_code': icmp_code}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict,
|
||||
call_num=1)
|
||||
|
||||
|
||||
class TestPolicyCommunicationProfile(NsxPolicyLibTestCase):
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
super(TestPolicyCommunicationProfile, self).setUp()
|
||||
self.resourceApi = self.policy_lib.comm_profile
|
||||
|
||||
def test_create(self):
|
||||
name = 'c1'
|
||||
description = 'desc'
|
||||
service_id = '333'
|
||||
action = 'DENY'
|
||||
with mock.patch.object(self.policy_api,
|
||||
"create_with_parent") as api_call:
|
||||
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,
|
||||
description=description,
|
||||
tenant=TEST_TENANT)
|
||||
exp_entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=mock.ANY,
|
||||
name=name,
|
||||
description=description,
|
||||
services=[service_id],
|
||||
action=action,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_defs(
|
||||
api_call, [exp_srv_def, exp_entry_def])
|
||||
|
||||
def test_delete(self):
|
||||
id = '111'
|
||||
with mock.patch.object(self.policy_api, "delete") as api_call,\
|
||||
mock.patch.object(self.policy_api, "get") as get_call:
|
||||
self.resourceApi.delete(id, tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=id, tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
def test_get(self):
|
||||
id = '111'
|
||||
with mock.patch.object(self.policy_api, "get") as api_call:
|
||||
self.resourceApi.get(id, tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=id, tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
def test_get_by_name(self):
|
||||
name = 'c1'
|
||||
with mock.patch.object(
|
||||
self.policy_api, "list",
|
||||
return_value={'results': [{'display_name': name}]}) as api_call:
|
||||
obj = self.resourceApi.get_by_name(name, tenant=TEST_TENANT)
|
||||
self.assertIsNotNone(obj)
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
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.CommunicationProfileDef(
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
def test_update(self):
|
||||
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,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(id,
|
||||
name=name,
|
||||
description=description,
|
||||
tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=id, tenant=TEST_TENANT)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'communication_profile_entries': []}
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
def test_update_entry(self):
|
||||
id = '111'
|
||||
service_id = '333'
|
||||
action = 'deny'
|
||||
entry_id = '222'
|
||||
profile_entry = {'id': entry_id}
|
||||
entries_dict = {'communication_profile_entries': [profile_entry]}
|
||||
|
||||
with mock.patch.object(
|
||||
self.policy_api, "get", return_value=entries_dict) as get_call,\
|
||||
mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(id,
|
||||
services=[service_id],
|
||||
action=action,
|
||||
tenant=TEST_TENANT)
|
||||
# get will be called for the entire service
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=id, tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service entry only
|
||||
expected_entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=id,
|
||||
profile_entry_id=entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': entry_id,
|
||||
'action': action.upper(),
|
||||
'services': [service_id]}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict)
|
||||
|
||||
def test_update_all(self):
|
||||
id = '111'
|
||||
name = 'new name'
|
||||
description = 'new desc'
|
||||
service_id = '333'
|
||||
action = 'deny'
|
||||
entry_id = '222'
|
||||
profile_entry = {'id': entry_id}
|
||||
entries_dict = {'communication_profile_entries': [profile_entry]}
|
||||
|
||||
with mock.patch.object(
|
||||
self.policy_api, "get", return_value=entries_dict) as get_call,\
|
||||
mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(id,
|
||||
name=name,
|
||||
description=description,
|
||||
services=[service_id],
|
||||
action=action,
|
||||
tenant=TEST_TENANT)
|
||||
# get will be called for the entire service
|
||||
expected_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=id, tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
|
||||
# update will be called for the service and entry (2 calls)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'communication_profile_entries': []}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
expected_entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=id,
|
||||
profile_entry_id=entry_id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_entry_dict = {'id': entry_id,
|
||||
'display_name': name,
|
||||
'description': description,
|
||||
'action': action.upper(),
|
||||
'services': [service_id]}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_entry_def, expected_entry_dict,
|
||||
call_num=1)
|
||||
|
||||
|
||||
class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
|
||||
@ -854,67 +606,96 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
super(TestPolicyCommunicationMap, self).setUp()
|
||||
self.resourceApi = self.policy_lib.comm_map
|
||||
|
||||
def test_create(self):
|
||||
def test_create_another(self):
|
||||
domain_id = '111'
|
||||
map_id = '222'
|
||||
name = 'cm1'
|
||||
description = 'desc'
|
||||
source_group = 'g1'
|
||||
dest_group = 'g2'
|
||||
seq_num = 7
|
||||
profile_id = 'c1'
|
||||
list_return_value = {'results': [{'sequence_number': 1}]}
|
||||
service_id = 'c1'
|
||||
get_return_value = {'communication_entries': [{'sequence_number': 1}]}
|
||||
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):
|
||||
mock.patch.object(self.policy_api, "get",
|
||||
return_value=get_return_value):
|
||||
self.resourceApi.create_or_overwrite(name, domain_id,
|
||||
map_id=map_id,
|
||||
description=description,
|
||||
sequence_number=seq_num,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=mock.ANY,
|
||||
map_id=map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=seq_num,
|
||||
profile_id=profile_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
category=policy_constants.CATEGORY_DEFAULT,
|
||||
precedence=0,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
entry_id=map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=seq_num,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def, call_num=1)
|
||||
|
||||
def test_create_first_seqnum(self):
|
||||
domain_id = '111'
|
||||
map_id = '222'
|
||||
name = 'cm1'
|
||||
description = 'desc'
|
||||
source_group = 'g1'
|
||||
dest_group = 'g2'
|
||||
profile_id = 'c1'
|
||||
service_id = 'c1'
|
||||
category = 'Emergency'
|
||||
get_return_value = {'communication_entries': []}
|
||||
with mock.patch.object(self.policy_api,
|
||||
"create_or_update") as api_call, \
|
||||
mock.patch.object(self.resourceApi, "list", return_value=[]):
|
||||
mock.patch.object(self.resourceApi, "get",
|
||||
return_value=get_return_value):
|
||||
self.resourceApi.create_or_overwrite(name, domain_id,
|
||||
map_id=map_id,
|
||||
description=description,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
category=category,
|
||||
tenant=TEST_TENANT)
|
||||
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
category=category,
|
||||
precedence=0,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id,
|
||||
map_id=mock.ANY,
|
||||
map_id=map_id,
|
||||
entry_id=map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=1,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
self.assert_called_with_def(api_call, expected_def, call_num=1)
|
||||
|
||||
def test_create_without_seqnum(self):
|
||||
domain_id = '111'
|
||||
@ -922,29 +703,33 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
description = 'desc'
|
||||
source_group = 'g1'
|
||||
dest_group = 'g2'
|
||||
profile_id = 'c1'
|
||||
service_id = 'c1'
|
||||
with mock.patch.object(self.policy_api,
|
||||
"create_with_parent") as api_call, \
|
||||
mock.patch.object(self.resourceApi, "_get_last_seq_num",
|
||||
return_value=-1):
|
||||
"create_with_parent") as api_call:
|
||||
self.resourceApi.create_or_overwrite(name, domain_id,
|
||||
description=description,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
|
||||
expected_map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=mock.ANY,
|
||||
name=name,
|
||||
description=description,
|
||||
category=policy_constants.CATEGORY_DEFAULT,
|
||||
precedence=0,
|
||||
tenant=TEST_TENANT)
|
||||
|
||||
expected_entry_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id,
|
||||
map_id=mock.ANY,
|
||||
entry_id=mock.ANY,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=1,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
@ -958,7 +743,7 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
id = '222'
|
||||
with mock.patch.object(self.policy_api, "delete") as api_call:
|
||||
self.resourceApi.delete(domain_id, id, tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
@ -969,7 +754,7 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
id = '222'
|
||||
with mock.patch.object(self.policy_api, "get") as api_call:
|
||||
self.resourceApi.get(domain_id, id, tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
@ -984,8 +769,8 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
obj = self.resourceApi.get_by_name(domain_id, name,
|
||||
tenant=TEST_TENANT)
|
||||
self.assertIsNotNone(obj)
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id,
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
@ -993,61 +778,53 @@ class TestPolicyCommunicationMap(NsxPolicyLibTestCase):
|
||||
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.CommunicationMapEntryDef(
|
||||
expected_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
|
||||
def test_update(self):
|
||||
domain_id = '111'
|
||||
id = '222'
|
||||
map_id = '222'
|
||||
name = 'new name'
|
||||
description = 'new desc'
|
||||
source_group = 'ng1'
|
||||
dest_group = 'ng2'
|
||||
profile_id = 'nc1'
|
||||
service_id = 'nc1'
|
||||
with mock.patch.object(self.policy_api, "get",
|
||||
return_value={}) as get_call,\
|
||||
mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
self.resourceApi.update(domain_id, id,
|
||||
self.resourceApi.update(domain_id, map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
source_groups=[source_group],
|
||||
dest_groups=[dest_group],
|
||||
tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.CommunicationMapEntryDef(
|
||||
expected_map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=id,
|
||||
map_id=map_id,
|
||||
tenant=TEST_TENANT)
|
||||
sgroup_path = "/%s/domains/%s/groups/%s" % (
|
||||
TEST_TENANT, domain_id, source_group)
|
||||
dgroup_path = "/%s/domains/%s/groups/%s" % (
|
||||
TEST_TENANT, domain_id, dest_group)
|
||||
profile_path = "/%s/communication-profiles/%s" % (
|
||||
TEST_TENANT, profile_id)
|
||||
expected_dict = {'display_name': name,
|
||||
'description': description,
|
||||
'communication_profile_path': profile_path,
|
||||
'source_groups': [sgroup_path],
|
||||
'destination_groups': [dgroup_path]}
|
||||
self.assert_called_with_def(get_call, expected_def)
|
||||
expected_map_dict = {'display_name': name,
|
||||
'description': description}
|
||||
self.assert_called_with_def(get_call, expected_map_def)
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
update_call, expected_map_def, expected_map_dict)
|
||||
|
||||
def test_get_realized(self):
|
||||
domain_id = 'd1'
|
||||
map_id = '111'
|
||||
ep_id = 'ef1'
|
||||
result = {'state': policy_constants.STATE_REALIZED}
|
||||
with mock.patch.object(
|
||||
self.policy_api, "get_by_path",
|
||||
return_value=result) as api_get:
|
||||
state = self.resourceApi.get_realized_state(
|
||||
domain_id, ep_id, tenant=TEST_TENANT)
|
||||
domain_id, map_id, ep_id, tenant=TEST_TENANT)
|
||||
self.assertEqual(policy_constants.STATE_REALIZED, state)
|
||||
expected_path = policy_defs.REALIZED_STATE_COMM_MAP % (
|
||||
TEST_TENANT, ep_id, domain_id)
|
||||
TEST_TENANT, ep_id, domain_id, map_id)
|
||||
api_get.assert_called_once_with(expected_path)
|
||||
|
||||
|
||||
@ -1063,11 +840,13 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
|
||||
ip_address = '1.1.1.1'
|
||||
username = 'admin'
|
||||
password = 'zzz'
|
||||
thumbprint = 'abc'
|
||||
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,
|
||||
thumbprint=thumbprint,
|
||||
username=username,
|
||||
password=password,
|
||||
tenant=TEST_TENANT)
|
||||
@ -1078,6 +857,7 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
|
||||
description=description,
|
||||
ip_address=ip_address,
|
||||
username=username,
|
||||
thumbprint=thumbprint,
|
||||
password=password,
|
||||
tenant=TEST_TENANT)
|
||||
self.assert_called_with_def(api_call, expected_def)
|
||||
@ -1119,18 +899,29 @@ class TestPolicyEnforcementPoint(NsxPolicyLibTestCase):
|
||||
name = 'new name'
|
||||
username = 'admin'
|
||||
password = 'zzz'
|
||||
ip_address = '1.1.1.1'
|
||||
thumbprint = 'abc'
|
||||
with mock.patch.object(self.policy_api,
|
||||
"create_or_update") as update_call:
|
||||
"create_or_update") as update_call,\
|
||||
mock.patch.object(self.policy_api, "get", return_value={'id': id}):
|
||||
self.resourceApi.update(id,
|
||||
name=name,
|
||||
username=username,
|
||||
password=password,
|
||||
ip_address=ip_address,
|
||||
thumbprint=thumbprint,
|
||||
tenant=TEST_TENANT)
|
||||
expected_def = policy_defs.EnforcementPointDef(ep_id=id,
|
||||
tenant=TEST_TENANT)
|
||||
expected_dict = {'display_name': name,
|
||||
'username': username,
|
||||
'password': password}
|
||||
expected_dict = {'id': id,
|
||||
'display_name': name,
|
||||
'resource_type': 'EnforcementPoint',
|
||||
'connection_info': {
|
||||
'username': username,
|
||||
'password': password,
|
||||
'thumbprint': thumbprint,
|
||||
'enforcement_point_address': ip_address,
|
||||
'resource_type': 'NSXTConnectionInfo'}}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
||||
@ -1235,7 +1026,7 @@ class TestPolicyDeploymentMap(NsxPolicyLibTestCase):
|
||||
ep_path = ("/%s/deployment-zones/default/"
|
||||
"enforcement-points/%s" % (TEST_TENANT, ep_id))
|
||||
expected_dict = {'display_name': name,
|
||||
'enforcement_point_paths': [ep_path],
|
||||
'domain_path': domain_path}
|
||||
'enforcement_point_path': ep_path,
|
||||
'parent_path': domain_path}
|
||||
self.assert_called_with_def_and_dict(
|
||||
update_call, expected_def, expected_dict)
|
||||
|
@ -352,8 +352,6 @@ class NsxPolicyLib(NsxLibBase):
|
||||
self.service = policy_resources.NsxPolicyL4ServiceApi(self.policy_api)
|
||||
self.icmp_service = policy_resources.NsxPolicyIcmpServiceApi(
|
||||
self.policy_api)
|
||||
self.comm_profile = policy_resources.NsxPolicyCommunicationProfileApi(
|
||||
self.policy_api)
|
||||
self.comm_map = policy_resources.NsxPolicyCommunicationMapApi(
|
||||
self.policy_api)
|
||||
self.enforcement_point = policy_resources.NsxPolicyEnforcementPointApi(
|
||||
|
@ -34,3 +34,9 @@ DEFAULT_THUMBPRINT = 'abc'
|
||||
|
||||
STATE_REALIZED = 'REALIZED'
|
||||
STATE_UNREALIZED = 'UNREALIZED'
|
||||
|
||||
CATEGORY_EMERGENCY = 'Emergency'
|
||||
CATEGORY_INFRASTRUCTURE = 'Infrastructure'
|
||||
CATEGORY_ENVIRONMENTAL = 'Environmental'
|
||||
CATEGORY_APPLICATION = 'Application'
|
||||
CATEGORY_DEFAULT = 'Default'
|
||||
|
@ -22,12 +22,12 @@ from vmware_nsxlib.v3 import policy_constants
|
||||
|
||||
TENANTS_PATH_PATTERN = "%s/"
|
||||
DOMAINS_PATH_PATTERN = TENANTS_PATH_PATTERN + "domains/"
|
||||
COMM_PROF_PATH_PATTERN = TENANTS_PATH_PATTERN + "communication-profiles/"
|
||||
SERVICES_PATH_PATTERN = TENANTS_PATH_PATTERN + "services/"
|
||||
REALIZED_STATE_EF = (TENANTS_PATH_PATTERN +
|
||||
"realized-state/enforcement-points/%s/")
|
||||
REALIZED_STATE_GROUP = REALIZED_STATE_EF + "groups/nsgroups/%s-%s"
|
||||
REALIZED_STATE_COMM_MAP = REALIZED_STATE_EF + "firewalls/firewall-sections/%s"
|
||||
REALIZED_STATE_COMM_MAP = (REALIZED_STATE_EF +
|
||||
"firewalls/firewall-sections/%s.%s")
|
||||
REALIZED_STATE_SERVICE = REALIZED_STATE_EF + "services/nsservices/services:%s"
|
||||
|
||||
|
||||
@ -324,124 +324,77 @@ class IcmpServiceEntryDef(ServiceEntryDef):
|
||||
body=body, **kwargs)
|
||||
|
||||
|
||||
class CommunicationProfileDef(ResourceDef):
|
||||
def __init__(self,
|
||||
profile_id=None,
|
||||
name=None,
|
||||
description=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
super(CommunicationProfileDef, self).__init__()
|
||||
self.tenant = tenant
|
||||
self.id = profile_id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.parent_ids = (tenant)
|
||||
|
||||
@property
|
||||
def path_pattern(self):
|
||||
return COMM_PROF_PATH_PATTERN
|
||||
|
||||
def get_obj_dict(self):
|
||||
body = super(CommunicationProfileDef, self).get_obj_dict()
|
||||
body['communication_profile_entries'] = []
|
||||
return body
|
||||
|
||||
@staticmethod
|
||||
def sub_entries_path():
|
||||
entryDef = CommunicationProfileEntryDef()
|
||||
return entryDef.get_last_section_dict_key
|
||||
|
||||
def update_attributes_in_body(self, **kwargs):
|
||||
super(CommunicationProfileDef, self).update_attributes_in_body(
|
||||
**kwargs)
|
||||
# make sure entries are there
|
||||
entries_path = self.sub_entries_path()
|
||||
if entries_path not in self.body:
|
||||
self.body[entries_path] = []
|
||||
|
||||
|
||||
class CommunicationProfileEntryDef(ResourceDef):
|
||||
def __init__(self,
|
||||
profile_id=None,
|
||||
profile_entry_id=None,
|
||||
name=None,
|
||||
description=None,
|
||||
services=None,
|
||||
action=policy_constants.ACTION_ALLOW,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
super(CommunicationProfileEntryDef, self).__init__()
|
||||
self.tenant = tenant
|
||||
self.id = profile_entry_id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.services = services
|
||||
self.action = action.upper()
|
||||
self.parent_ids = (tenant, profile_id)
|
||||
|
||||
@property
|
||||
def path_pattern(self):
|
||||
return COMM_PROF_PATH_PATTERN + "%s/communication-profile-entries/"
|
||||
|
||||
def get_obj_dict(self):
|
||||
body = super(CommunicationProfileEntryDef, self).get_obj_dict()
|
||||
body['services'] = self.services
|
||||
body['action'] = self.action
|
||||
return body
|
||||
|
||||
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=body, **kwargs)
|
||||
|
||||
|
||||
class CommunicationMapDef(ResourceDef):
|
||||
def __init__(self,
|
||||
map_id=None,
|
||||
domain_id=None,
|
||||
category=policy_constants.CATEGORY_DEFAULT,
|
||||
name=None,
|
||||
precedence=0,
|
||||
description=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
super(CommunicationMapDef, self).__init__()
|
||||
self.id = map_id
|
||||
self.category = category
|
||||
self.precedence = precedence
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.tenant = tenant
|
||||
self.domain_id = domain_id
|
||||
self.parent_ids = (tenant, domain_id)
|
||||
|
||||
@property
|
||||
def path_pattern(self):
|
||||
return (DOMAINS_PATH_PATTERN + "%s/communication-map/")
|
||||
return (DOMAINS_PATH_PATTERN + "%s/communication-maps/")
|
||||
|
||||
def get_realized_state_path(self, ep_id):
|
||||
return REALIZED_STATE_COMM_MAP % (self.tenant, ep_id, self.domain_id)
|
||||
return REALIZED_STATE_COMM_MAP % (self.tenant, ep_id, self.domain_id,
|
||||
self.id)
|
||||
|
||||
def get_obj_dict(self):
|
||||
body = super(CommunicationMapDef, self).get_obj_dict()
|
||||
if self.category:
|
||||
body['category'] = self.category
|
||||
if self.precedence:
|
||||
body['precedence'] = self.precedence
|
||||
return body
|
||||
|
||||
@staticmethod
|
||||
def sub_entries_path():
|
||||
return CommunicationMapEntryDef().get_last_section_dict_key
|
||||
|
||||
|
||||
class CommunicationMapEntryDef(ResourceDef):
|
||||
def __init__(self,
|
||||
domain_id=None,
|
||||
map_id=None,
|
||||
entry_id=None,
|
||||
sequence_number=None,
|
||||
source_groups=None,
|
||||
dest_groups=None,
|
||||
profile_id=None,
|
||||
service_id=None,
|
||||
action=policy_constants.ACTION_ALLOW,
|
||||
scope="ANY",
|
||||
name=None,
|
||||
description=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
super(CommunicationMapEntryDef, self).__init__()
|
||||
self.tenant = tenant
|
||||
self.domain_id = domain_id
|
||||
self.id = map_id
|
||||
self.map_id = map_id,
|
||||
self.id = entry_id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.sequence_number = sequence_number
|
||||
|
||||
self.action = action
|
||||
self.scope = scope
|
||||
self.source_groups = self.get_groups_path(domain_id, source_groups)
|
||||
self.dest_groups = self.get_groups_path(domain_id, dest_groups)
|
||||
self.profile_path = self.get_profile_path(
|
||||
profile_id) if profile_id else None
|
||||
self.parent_ids = (tenant, domain_id)
|
||||
self.service_path = self.get_service_path(
|
||||
service_id) if service_id else None
|
||||
self.parent_ids = (tenant, domain_id, map_id)
|
||||
|
||||
# convert groups and communication profile to full path
|
||||
# convert groups and services to full path
|
||||
def get_groups_path(self, domain_id, group_ids):
|
||||
if not group_ids:
|
||||
return [policy_constants.ANY_GROUP]
|
||||
@ -450,22 +403,24 @@ class CommunicationMapEntryDef(ResourceDef):
|
||||
tenant=self.tenant).get_resource_full_path()
|
||||
for group_id in group_ids]
|
||||
|
||||
def get_profile_path(self, profile_id):
|
||||
return CommunicationProfileDef(
|
||||
profile_id,
|
||||
def get_service_path(self, service_id):
|
||||
return ServiceDef(
|
||||
service_id,
|
||||
tenant=self.tenant).get_resource_full_path()
|
||||
|
||||
@property
|
||||
def path_pattern(self):
|
||||
return (DOMAINS_PATH_PATTERN +
|
||||
"%s/communication-map/communication-entries/")
|
||||
"%s/communication-maps/%s/communication-entries/")
|
||||
|
||||
def get_obj_dict(self):
|
||||
body = super(CommunicationMapEntryDef, self).get_obj_dict()
|
||||
body['source_groups'] = self.source_groups
|
||||
body['destination_groups'] = self.dest_groups
|
||||
body['sequence_number'] = self.sequence_number
|
||||
body['communication_profile_path'] = self.profile_path
|
||||
body['services'] = [self.service_path]
|
||||
body['scope'] = [self.scope]
|
||||
body['action'] = self.action
|
||||
return body
|
||||
|
||||
def update_attributes_in_body(self, **kwargs):
|
||||
@ -473,10 +428,10 @@ class CommunicationMapEntryDef(ResourceDef):
|
||||
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'])
|
||||
body['communication_profile_path'] = profile_path
|
||||
del kwargs['profile_id']
|
||||
if kwargs.get('service_id') is not None:
|
||||
service_path = self.get_service_path(kwargs['service_id'])
|
||||
body['services'] = [service_path]
|
||||
del kwargs['service_id']
|
||||
|
||||
if kwargs.get('dest_groups') is not None:
|
||||
groups = self.get_groups_path(
|
||||
@ -490,6 +445,10 @@ class CommunicationMapEntryDef(ResourceDef):
|
||||
body['source_groups'] = groups
|
||||
del kwargs['source_groups']
|
||||
|
||||
if kwargs.get('scope') is not None:
|
||||
body['scope'] = [kwargs['scope']]
|
||||
del kwargs['scope']
|
||||
|
||||
super(CommunicationMapEntryDef, self).update_attributes_in_body(
|
||||
body=body, **kwargs)
|
||||
|
||||
@ -538,13 +497,18 @@ class EnforcementPointDef(ResourceDef):
|
||||
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 not body.get('connection_info'):
|
||||
body['connection_info'] = {}
|
||||
body['connection_info']['resource_type'] = 'NSXTConnectionInfo'
|
||||
body['resource_type'] = 'EnforcementPoint'
|
||||
|
||||
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]
|
||||
for attr in ('username', 'password', 'ip_address', 'thumbprint'):
|
||||
if kwargs.get(attr) is not None:
|
||||
body_attr = attr
|
||||
if attr == 'ip_address':
|
||||
body_attr = 'enforcement_point_address'
|
||||
body['connection_info'][body_attr] = kwargs[attr]
|
||||
del kwargs[attr]
|
||||
|
||||
super(EnforcementPointDef, self).update_attributes_in_body(
|
||||
body=body, **kwargs)
|
||||
@ -592,14 +556,14 @@ class DeploymentMapDef(ResourceDef):
|
||||
domain_id = kwargs.get('domain_id')
|
||||
domain_path = DomainDef(
|
||||
domain_id, tenant=self.tenant).get_resource_full_path()
|
||||
body['domain_path'] = domain_path
|
||||
body['parent_path'] = domain_path
|
||||
del kwargs['domain_id']
|
||||
|
||||
if kwargs.get('ep_id') is not None:
|
||||
ep_id = kwargs.get('ep_id')
|
||||
ep_path = EnforcementPointDef(
|
||||
ep_id, tenant=self.tenant).get_resource_full_path()
|
||||
body['enforcement_point_paths'] = [ep_path]
|
||||
body['enforcement_point_path'] = ep_path
|
||||
del kwargs['ep_id']
|
||||
|
||||
super(DeploymentMapDef, self).update_attributes_in_body(
|
||||
@ -616,13 +580,14 @@ class NsxPolicyApi(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
|
||||
The policy API supports PATCH for create/update operations
|
||||
"""
|
||||
path = resource_def.get_resource_path()
|
||||
body = resource_def.body
|
||||
if not body:
|
||||
body = resource_def.get_obj_dict()
|
||||
return self.client.create(path, body)
|
||||
self.client.patch(path, body)
|
||||
return self.client.get(path)
|
||||
|
||||
def create_with_parent(self, parent_def, resource_def):
|
||||
path = parent_def.get_resource_path()
|
||||
@ -633,7 +598,8 @@ 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.create(path, body)
|
||||
self.client.patch(path, body)
|
||||
return self.client.get(path)
|
||||
|
||||
def delete(self, resource_def):
|
||||
path = resource_def.get_resource_path()
|
||||
|
@ -27,9 +27,6 @@ from vmware_nsxlib.v3 import policy_defs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# TODO(asarfaty): support retries?
|
||||
# TODO(asarfaty): In future versions PATCH may be supported for update
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class NsxPolicyResourceBase(object):
|
||||
@ -68,6 +65,10 @@ class NsxPolicyResourceBase(object):
|
||||
obj_uuid = str(uuid.uuid4())
|
||||
return obj_uuid
|
||||
|
||||
def _canonize_name(self, name):
|
||||
# remove spaces and slashes from objects names
|
||||
return name.replace(' ', '_').replace('/', '_')
|
||||
|
||||
def get_by_name(self, name, *args, **kwargs):
|
||||
# Return first match by name
|
||||
resources_list = self.list(*args, **kwargs)
|
||||
@ -271,6 +272,47 @@ class NsxPolicyServiceBase(NsxPolicyResourceBase):
|
||||
path = service_def.get_realized_state_path(ep_id)
|
||||
return self._get_realized_state(path)
|
||||
|
||||
# TODO(asarfaty) currently service update doesn't work
|
||||
def update(self, service_id, name=None, description=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT,
|
||||
**kwargs):
|
||||
# service name cannot contain spaces or slashes
|
||||
if name:
|
||||
name = self._canonize_name(name)
|
||||
|
||||
# Get the current data of service & its' service entry
|
||||
service = self.get(service_id, tenant=tenant)
|
||||
# update the relevant data service itself:
|
||||
# TODO(asarfaty): currently updating the service itself doesn't work
|
||||
if name is not None:
|
||||
service['display_name'] = name
|
||||
if description is not None:
|
||||
service['description'] = description
|
||||
|
||||
if (service.get('service_entries') and
|
||||
len(service['service_entries']) == 1):
|
||||
# update the service entry body
|
||||
self._update_service_entry(
|
||||
service_id, service['service_entries'][0],
|
||||
name=name, description=description, **kwargs)
|
||||
else:
|
||||
LOG.error("Cannot update service %s - expected 1 service "
|
||||
"entry", service_id)
|
||||
|
||||
# update the backend
|
||||
service_def = policy_defs.ServiceDef(service_id=service_id,
|
||||
tenant=tenant)
|
||||
service_def.body = service
|
||||
self.policy_api.create_or_update(service_def)
|
||||
# return the updated service
|
||||
return self.get(service_id, tenant=tenant)
|
||||
|
||||
def get_by_name(self, name, *args, **kwargs):
|
||||
# service name cannot contain spaces or slashes
|
||||
name = self._canonize_name(name)
|
||||
return super(NsxPolicyServiceBase, self).get_by_name(
|
||||
name, *args, **kwargs)
|
||||
|
||||
@property
|
||||
def entry_def(self):
|
||||
pass
|
||||
@ -290,6 +332,8 @@ class NsxPolicyL4ServiceApi(NsxPolicyServiceBase):
|
||||
protocol=policy_constants.TCP, dest_ports=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
service_id = self._init_obj_uuid(service_id)
|
||||
# service name cannot contain spaces or slashes
|
||||
name = self._canonize_name(name)
|
||||
service_def = policy_defs.ServiceDef(service_id=service_id,
|
||||
name=name,
|
||||
description=description,
|
||||
@ -320,43 +364,6 @@ class NsxPolicyL4ServiceApi(NsxPolicyServiceBase):
|
||||
protocol=protocol,
|
||||
dest_ports=dest_ports)
|
||||
|
||||
self.policy_api.create_or_update(entry_def)
|
||||
|
||||
def update(self, service_id, name=None, description=None,
|
||||
protocol=None, dest_ports=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
# Get the current data of service & its' service entry
|
||||
service = self.get(service_id, tenant=tenant)
|
||||
|
||||
# update the service itself:
|
||||
if name is not None or description is not None:
|
||||
# update the service itself
|
||||
service_def = policy_defs.ServiceDef(service_id=service_id,
|
||||
tenant=tenant)
|
||||
service_def.update_attributes_in_body(name=name,
|
||||
description=description)
|
||||
|
||||
# update the backend
|
||||
updated_service = self.policy_api.create_or_update(service_def)
|
||||
else:
|
||||
updated_service = service
|
||||
|
||||
# update the service entry if it exists
|
||||
service_entry = policy_defs.ServiceDef.get_single_entry(service)
|
||||
if not service_entry:
|
||||
LOG.error("Cannot update service %s - expected 1 service "
|
||||
"entry", service_id)
|
||||
return updated_service
|
||||
|
||||
self._update_service_entry(
|
||||
service_id, service_entry,
|
||||
name=name, description=description,
|
||||
protocol=protocol, dest_ports=dest_ports,
|
||||
tenant=tenant)
|
||||
|
||||
# re-read the service from the backend to return the current data
|
||||
return self.get(service_id, tenant=tenant)
|
||||
|
||||
|
||||
class NsxPolicyIcmpServiceApi(NsxPolicyServiceBase):
|
||||
"""NSX Policy Service with a single ICMP service entry.
|
||||
@ -372,6 +379,8 @@ class NsxPolicyIcmpServiceApi(NsxPolicyServiceBase):
|
||||
version=4, icmp_type=None, icmp_code=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
service_id = self._init_obj_uuid(service_id)
|
||||
# service name cannot contain spaces or slashes
|
||||
name = self._canonize_name(name)
|
||||
service_def = policy_defs.ServiceDef(service_id=service_id,
|
||||
name=name,
|
||||
description=description,
|
||||
@ -404,164 +413,16 @@ class NsxPolicyIcmpServiceApi(NsxPolicyServiceBase):
|
||||
icmp_type=icmp_type,
|
||||
icmp_code=icmp_code)
|
||||
|
||||
self.policy_api.create_or_update(entry_def)
|
||||
|
||||
def update(self, service_id, name=None, description=None,
|
||||
version=None, icmp_type=None, icmp_code=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
# Get the current data of service & its' service entry
|
||||
service = self.get(service_id, tenant=tenant)
|
||||
|
||||
# update the service itself:
|
||||
if name is not None or description is not None:
|
||||
# update the service itself
|
||||
service_def = policy_defs.ServiceDef(service_id=service_id,
|
||||
tenant=tenant)
|
||||
service_def.update_attributes_in_body(name=name,
|
||||
description=description)
|
||||
|
||||
# update the backend
|
||||
updated_service = self.policy_api.create_or_update(service_def)
|
||||
else:
|
||||
updated_service = service
|
||||
|
||||
# update the service entry if it exists
|
||||
service_entry = policy_defs.ServiceDef.get_single_entry(service)
|
||||
if not service_entry:
|
||||
LOG.error("Cannot update service %s - expected 1 service "
|
||||
"entry", service_id)
|
||||
return updated_service
|
||||
|
||||
self._update_service_entry(
|
||||
service_id, service_entry,
|
||||
name=name, description=description,
|
||||
version=version, icmp_type=icmp_type, icmp_code=icmp_code,
|
||||
tenant=tenant)
|
||||
|
||||
# re-read the service from the backend to return the current data
|
||||
return self.get(service_id, tenant=tenant)
|
||||
|
||||
|
||||
class NsxPolicyCommunicationProfileApi(NsxPolicyResourceBase):
|
||||
"""NSX Policy Communication profile (with a single entry).
|
||||
|
||||
Note the nsx-policy backend supports multiple entries per communication
|
||||
profile.
|
||||
At this point this is not supported here.
|
||||
"""
|
||||
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
|
||||
"""
|
||||
profile_id = self._init_obj_uuid(profile_id)
|
||||
profile_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=profile_id,
|
||||
name=name,
|
||||
description=description,
|
||||
tenant=tenant)
|
||||
# NOTE(asarfaty) We set the profile entry display name (which is also
|
||||
# used as the id) to be the same as the profile name. In case we
|
||||
# support multiple entries, we need the name to be unique.
|
||||
entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=profile_id,
|
||||
name=name,
|
||||
description=description,
|
||||
services=services,
|
||||
action=action,
|
||||
tenant=tenant)
|
||||
|
||||
return self.policy_api.create_with_parent(profile_def, entry_def)
|
||||
|
||||
def delete(self, profile_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
"""Delete the Communication profile with all the entries"""
|
||||
# first delete the entries, or else the profile deletion will fail
|
||||
profile_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=profile_id, tenant=tenant)
|
||||
prof = self.policy_api.get(profile_def)
|
||||
if 'communication_profile_entries' in prof:
|
||||
for entry in prof['communication_profile_entries']:
|
||||
entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=profile_id,
|
||||
profile_entry_id=entry['id'],
|
||||
tenant=tenant)
|
||||
self.policy_api.delete(entry_def)
|
||||
self.policy_api.delete(profile_def)
|
||||
|
||||
def get(self, profile_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
profile_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=profile_id, tenant=tenant)
|
||||
return self.policy_api.get(profile_def)
|
||||
|
||||
def list(self, tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
profile_def = policy_defs.CommunicationProfileDef(tenant=tenant)
|
||||
return self.policy_api.list(profile_def)['results']
|
||||
|
||||
def _update_profile_entry(self, profile_id, profile_entry,
|
||||
name=None, description=None,
|
||||
services=None, action=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
entry_id = profile_entry['id']
|
||||
entry_def = policy_defs.CommunicationProfileEntryDef(
|
||||
profile_id=profile_id,
|
||||
profile_entry_id=entry_id,
|
||||
tenant=tenant)
|
||||
entry_def.update_attributes_in_body(body=profile_entry,
|
||||
name=name,
|
||||
description=description,
|
||||
services=services,
|
||||
action=action)
|
||||
|
||||
self.policy_api.create_or_update(entry_def)
|
||||
|
||||
def update(self, profile_id, name=None, description=None,
|
||||
services=None, action=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
# Get the current data of the profile & its' entry
|
||||
profile = self.get(profile_id, tenant=tenant)
|
||||
|
||||
if name is not None or description is not None:
|
||||
# update the profile itself
|
||||
profile_def = policy_defs.CommunicationProfileDef(
|
||||
profile_id=profile_id, tenant=tenant)
|
||||
profile_def.update_attributes_in_body(name=name,
|
||||
description=description)
|
||||
|
||||
# update the backend
|
||||
updated_profile = self.policy_api.create_or_update(profile_def)
|
||||
else:
|
||||
updated_profile = profile
|
||||
|
||||
# update the profile entry if it exists
|
||||
profile_entry = policy_defs.CommunicationProfileDef.get_single_entry(
|
||||
profile)
|
||||
if not profile_entry:
|
||||
LOG.error("Cannot update communication profile %s - expected 1 "
|
||||
"profile entry", profile_id)
|
||||
return updated_profile
|
||||
|
||||
self._update_profile_entry(
|
||||
profile_id, profile_entry,
|
||||
name=name, description=description,
|
||||
services=services, action=action,
|
||||
tenant=tenant)
|
||||
|
||||
# re-read the profile from the backend to return the current data
|
||||
return self.get(profile_id, tenant=tenant)
|
||||
|
||||
|
||||
class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
||||
"""NSX Policy CommunicationMap (Under a Domain)."""
|
||||
def _get_last_seq_num(self, domain_id,
|
||||
def _get_last_seq_num(self, domain_id, map_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
# get the current entries, and choose the next unused sequence number
|
||||
# between the entries under the same communication map
|
||||
try:
|
||||
com_entries = self.list(domain_id, tenant=tenant)
|
||||
com_map = self.get(domain_id, map_id, tenant=tenant)
|
||||
com_entries = com_map.get('communication_entries')
|
||||
except exceptions.ResourceNotFound:
|
||||
return -1
|
||||
if not com_entries:
|
||||
@ -571,11 +432,13 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
||||
return seq_nums[-1]
|
||||
|
||||
def create_or_overwrite(self, name, domain_id, map_id=None,
|
||||
description=None, sequence_number=None,
|
||||
profile_id=None,
|
||||
description=None, precedence=0,
|
||||
category=policy_constants.CATEGORY_DEFAULT,
|
||||
sequence_number=None, service_id=None,
|
||||
action=policy_constants.ACTION_ALLOW,
|
||||
source_groups=None, dest_groups=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
"""Create CommunicationMapEntry.
|
||||
"""Create CommunicationMap & Entry.
|
||||
|
||||
source_groups/dest_groups should be a list of group ids belonging
|
||||
to the domain.
|
||||
@ -584,44 +447,56 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
||||
end up with same sequence number.
|
||||
"""
|
||||
# Validate and convert inputs
|
||||
map_id = self._init_obj_uuid(map_id)
|
||||
if not profile_id:
|
||||
# profile-id must be provided
|
||||
if not service_id:
|
||||
# service-id must be provided
|
||||
err_msg = (_("Cannot create a communication map %(name)s without "
|
||||
"communication profile id") % {'name': name})
|
||||
"service id") % {'name': name})
|
||||
raise exceptions.ManagerError(details=err_msg)
|
||||
if map_id:
|
||||
# get the next available sequence number
|
||||
last_sequence = self._get_last_seq_num(domain_id, map_id,
|
||||
tenant=tenant)
|
||||
else:
|
||||
map_id = self._init_obj_uuid(map_id)
|
||||
last_sequence = -1
|
||||
|
||||
# get the next available sequence number
|
||||
last_sequence = self._get_last_seq_num(domain_id, tenant=tenant)
|
||||
if not sequence_number:
|
||||
if last_sequence < 0:
|
||||
sequence_number = 1
|
||||
else:
|
||||
sequence_number = last_sequence + 1
|
||||
|
||||
# Build the communication entry. Since we currently support only one
|
||||
# it will have the same id as its parent
|
||||
entry_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
entry_id=map_id,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=sequence_number,
|
||||
source_groups=source_groups,
|
||||
dest_groups=dest_groups,
|
||||
profile_id=profile_id,
|
||||
service_id=service_id,
|
||||
action=action,
|
||||
tenant=tenant)
|
||||
|
||||
map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id, map_id=map_id,
|
||||
tenant=tenant, name=name, description=description,
|
||||
precedence=precedence, category=category)
|
||||
if last_sequence < 0:
|
||||
# if communication map is absent, we need to create it
|
||||
map_def = policy_defs.CommunicationMapDef(domain_id, tenant)
|
||||
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_with_parent(map_def, entry_def)
|
||||
|
||||
return self.policy_api.create_or_update(entry_def)
|
||||
# TODO(asarfaty) combine both calls together
|
||||
self.policy_api.create_or_update(map_def)
|
||||
self.policy_api.create_or_update(entry_def)
|
||||
return self.get(domain_id, map_id, tenant=tenant)
|
||||
|
||||
def delete(self, domain_id, map_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
map_def = policy_defs.CommunicationMapEntryDef(
|
||||
map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
tenant=tenant)
|
||||
@ -629,7 +504,7 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
||||
|
||||
def get(self, domain_id, map_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
map_def = policy_defs.CommunicationMapEntryDef(
|
||||
map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
tenant=tenant)
|
||||
@ -644,44 +519,60 @@ class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
||||
def list(self, domain_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
"""List all the map entries of a specific domain."""
|
||||
map_def = policy_defs.CommunicationMapEntryDef(
|
||||
map_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id,
|
||||
tenant=tenant)
|
||||
return self.policy_api.list(map_def)['results']
|
||||
|
||||
def update(self, domain_id, map_id, name=None, description=None,
|
||||
sequence_number=None, profile_id=None,
|
||||
source_groups=None, dest_groups=None,
|
||||
sequence_number=None, service_id=None, action=None,
|
||||
source_groups=None, dest_groups=None, precedence=None,
|
||||
category=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
map_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
tenant=tenant)
|
||||
# Get the current data of communication map & its' entry
|
||||
comm_map = self.get(domain_id, map_id, tenant=tenant)
|
||||
# update the communication map itself:
|
||||
comm_def = policy_defs.CommunicationMapDef(
|
||||
domain_id=domain_id, map_id=map_id, tenant=tenant)
|
||||
if name is not None:
|
||||
comm_map['display_name'] = name
|
||||
if description is not None:
|
||||
comm_map['description'] = description
|
||||
if category is not None:
|
||||
comm_map['category'] = category
|
||||
if precedence is not None:
|
||||
comm_map['precedence'] = precedence
|
||||
|
||||
# Get the current data, and update it with the new values
|
||||
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)
|
||||
if (comm_map.get('communication_entries') and
|
||||
len(comm_map['communication_entries']) == 1):
|
||||
# update the entry body
|
||||
comm_entry = comm_map['communication_entries'][0]
|
||||
entry_id = comm_entry['id']
|
||||
entry_def = policy_defs.CommunicationMapEntryDef(
|
||||
domain_id=domain_id, map_id=map_id, entry_id=entry_id,
|
||||
tenant=tenant)
|
||||
entry_def.update_attributes_in_body(
|
||||
body=comm_entry, name=name,
|
||||
description=description,
|
||||
service_id=service_id,
|
||||
source_groups=source_groups,
|
||||
dest_groups=dest_groups,
|
||||
sequence_number=sequence_number,
|
||||
action=action)
|
||||
else:
|
||||
LOG.error("Cannot update communication map %s - expected 1 entry",
|
||||
map_id)
|
||||
|
||||
map_def.update_attributes_in_body(
|
||||
body=comm_map,
|
||||
name=name,
|
||||
description=description,
|
||||
sequence_number=sequence_number,
|
||||
profile_id=profile_id,
|
||||
source_groups=source_groups,
|
||||
dest_groups=dest_groups)
|
||||
comm_def.body = comm_map
|
||||
self.policy_api.create_or_update(comm_def)
|
||||
|
||||
# update the backend
|
||||
return self.policy_api.create_or_update(map_def)
|
||||
# re-read the map from the backend to return the current data
|
||||
return self.get(domain_id, map_id, tenant=tenant)
|
||||
|
||||
def get_realized_state(self, domain_id, ep_id,
|
||||
def get_realized_state(self, domain_id, map_id, ep_id,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
map_def = policy_defs.CommunicationMapDef(domain_id, tenant)
|
||||
map_def = policy_defs.CommunicationMapDef(map_id, domain_id,
|
||||
tenant=tenant)
|
||||
path = map_def.get_realized_state_path(ep_id)
|
||||
return self._get_realized_state(path)
|
||||
|
||||
@ -734,13 +625,15 @@ class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
|
||||
username & password must be defined
|
||||
"""
|
||||
if not username or password is None:
|
||||
# profile-id must be provided
|
||||
# username/password must be provided
|
||||
err_msg = (_("Cannot update an enforcement point without "
|
||||
"username and password"))
|
||||
raise exceptions.ManagerError(details=err_msg)
|
||||
|
||||
# Get the original body because ip & thumbprint are mandatory
|
||||
body = self.get(ep_id)
|
||||
ep_def = policy_defs.EnforcementPointDef(ep_id=ep_id, tenant=tenant)
|
||||
ep_def.update_attributes_in_body(name=name,
|
||||
ep_def.update_attributes_in_body(body=body,
|
||||
name=name,
|
||||
description=description,
|
||||
ip_address=ip_address,
|
||||
username=username,
|
||||
@ -807,7 +700,7 @@ class NsxPolicyDeploymentMapApi(NsxPolicyResourceBase):
|
||||
ep_id=None, domain_id=None,
|
||||
tenant=policy_constants.POLICY_INFRA_TENANT):
|
||||
map_def = policy_defs.DeploymentMapDef(
|
||||
map_id=map_id, tenant=tenant)
|
||||
map_id=map_id, domain_id=domain_id, tenant=tenant)
|
||||
map_def.update_attributes_in_body(name=name,
|
||||
description=description,
|
||||
ep_id=ep_id,
|
||||
|
Loading…
x
Reference in New Issue
Block a user