Merge "NSX Policy: patch security rules with ChildResourceReference" into stable/victoria
This commit is contained in:
commit
760ed08121
|
@ -500,6 +500,84 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi):
|
|||
def test_updating_security_policy_and_dfw_rules_no_child_rules(self):
|
||||
return self._test_updating_security_policy_and_dfw_rules(False)
|
||||
|
||||
@mock.patch('vmware_nsxlib.v3.policy.core_defs.NsxPolicyApi.get')
|
||||
def test_updating_security_policy_patch_rules(self, mock_get_api):
|
||||
dfw_rule1 = {'id': 'rule_id1', 'action': 'ALLOW',
|
||||
'display_name': 'rule1', 'description': None,
|
||||
'direction': 'IN_OUT', 'ip_protocol': 'IPV4_IPV6',
|
||||
'logged': False,
|
||||
'destination_groups': ['destination_url'],
|
||||
'source_groups': ['src_url'], 'resource_type': 'Rule',
|
||||
'scope': None, 'sequence_number': None, 'tag': None,
|
||||
'services': ['ANY']}
|
||||
dfw_rule2 = {'id': 'rule_id2', 'action': 'DROP',
|
||||
'display_name': 'rule2', 'description': None,
|
||||
'direction': 'IN_OUT', 'ip_protocol': 'IPV4_IPV6',
|
||||
'logged': False,
|
||||
'destination_groups': ['destination_url'],
|
||||
'source_groups': ['src_url'], 'resource_type': 'Rule',
|
||||
'scope': None, 'sequence_number': None, 'tag': None,
|
||||
'services': ['ANY']}
|
||||
security_policy = {'id': 'security_policy_id1',
|
||||
'display_name': 'security_policy',
|
||||
'category': 'Application',
|
||||
'resource_type': 'SecurityPolicy'}
|
||||
domain = {'resource_type': 'Domain', 'id': 'domain1'}
|
||||
domain_id = domain['id']
|
||||
map_id = security_policy['id']
|
||||
dfw_rule_entries = [self.policy_lib.comm_map.build_entry(
|
||||
name=rule['display_name'],
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
entry_id=rule['id'],
|
||||
source_groups=rule['source_groups'],
|
||||
dest_groups=rule['destination_groups'],
|
||||
ip_protocol=rule['ip_protocol'],
|
||||
action=rule['action'],
|
||||
direction=rule['direction']
|
||||
) for rule in [dfw_rule1, dfw_rule2]]
|
||||
|
||||
def get_group_path(group_id, domain_id):
|
||||
return '/infra/domains/' + domain_id + '/groups/' + group_id
|
||||
|
||||
for dfw_rule in [dfw_rule1, dfw_rule2]:
|
||||
dfw_rule['destination_groups'] = [get_group_path(group_id,
|
||||
domain_id)
|
||||
for group_id in
|
||||
dfw_rule['destination_groups']]
|
||||
dfw_rule['source_groups'] = [get_group_path(group_id, domain_id)
|
||||
for group_id in
|
||||
dfw_rule['source_groups']]
|
||||
|
||||
security_policy_values = copy.deepcopy(security_policy)
|
||||
security_policy_values.update({'rules':
|
||||
copy.deepcopy([dfw_rule1, dfw_rule2])})
|
||||
mock_get_api.return_value = security_policy_values
|
||||
|
||||
with trans.NsxPolicyTransaction():
|
||||
self.policy_lib.comm_map.patch_entries(
|
||||
domain_id=domain_id,
|
||||
map_id=map_id,
|
||||
entries=dfw_rule_entries,
|
||||
)
|
||||
|
||||
child_security_policies = [{
|
||||
'resource_type': 'ChildResourceReference',
|
||||
'target_type': 'SecurityPolicy',
|
||||
'id': security_policy['id'],
|
||||
}]
|
||||
child_rules = [{'resource_type': 'ChildRule', 'Rule': dfw_rule1},
|
||||
{'resource_type': 'ChildRule', 'Rule': dfw_rule2}]
|
||||
child_security_policies[0].update({'children': child_rules})
|
||||
domain.update({'children': child_security_policies})
|
||||
child_domains = [{
|
||||
'resource_type': 'ChildDomain',
|
||||
'Domain': domain
|
||||
}]
|
||||
expected_body = {'resource_type': 'Infra',
|
||||
'children': child_domains}
|
||||
self.assert_infra_patch_call(expected_body)
|
||||
|
||||
@mock.patch('vmware_nsxlib.v3.policy.core_defs.NsxPolicyApi.get')
|
||||
def test_updating_security_policy_with_no_entries_set(self, mock_get_api):
|
||||
dfw_rule1 = {'id': 'rule_id1', 'action': 'ALLOW',
|
||||
|
|
|
@ -4011,6 +4011,35 @@ class NsxPolicySecurityPolicyBaseApi(NsxPolicyResourceBase):
|
|||
|
||||
_update()
|
||||
|
||||
def patch_entries(self, domain_id, map_id, entries,
|
||||
tenant=constants.POLICY_INFRA_TENANT):
|
||||
# Specify that we want to use a childresourcerefence
|
||||
map_def = self._init_parent_def(
|
||||
domain_id=domain_id, map_id=map_id, tenant=tenant,
|
||||
child_resource_ref=True)
|
||||
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.policy_api.client.max_attempts)
|
||||
def _update():
|
||||
transaction = trans.NsxPolicyTransaction.get_current()
|
||||
if not transaction:
|
||||
err_msg = ("patch_entries can only be used within "
|
||||
"H-API transactions")
|
||||
raise exceptions.ManagerException(
|
||||
details=err_msg)
|
||||
patch_entries = []
|
||||
for entry in entries:
|
||||
rule = entry.get_obj_dict()
|
||||
LOG.debug("#### ADDING ENTRY: %s", entry)
|
||||
patch_entries.append(
|
||||
self.entry_def.adapt_from_rule_dict(
|
||||
rule, domain_id, map_id))
|
||||
|
||||
self._create_or_store(map_def, patch_entries)
|
||||
|
||||
_update()
|
||||
|
||||
def update_entries_logged(self, domain_id, map_id, logged,
|
||||
tenant=constants.POLICY_INFRA_TENANT):
|
||||
"""Update all communication map entries logged flags"""
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
import threading
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsxlib._i18n import _
|
||||
|
||||
from vmware_nsxlib.v3 import exceptions
|
||||
|
@ -25,6 +27,9 @@ from vmware_nsxlib.v3.policy import core_defs
|
|||
from vmware_nsxlib.v3 import utils
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class NsxPolicyTransactionException(exceptions.NsxLibException):
|
||||
message = _("Policy Transaction Error: %(msg)s")
|
||||
|
||||
|
@ -100,11 +105,19 @@ class NsxPolicyTransaction(object):
|
|||
|
||||
self.defs = sorted_defs
|
||||
|
||||
def _build_wrapper_dict(self, resource_class, node, delete=False):
|
||||
wrapper_dict = {'resource_type': 'Child%s' % resource_class,
|
||||
resource_class: node}
|
||||
def _build_wrapper_dict(self, resource_class, node, delete=False,
|
||||
child_resource_ref=False):
|
||||
if child_resource_ref:
|
||||
wrapper_dict = {'resource_type': 'ChildResourceReference',
|
||||
'target_type': resource_class,
|
||||
'id': node['id'],
|
||||
'children': []}
|
||||
else:
|
||||
wrapper_dict = {'resource_type': 'Child%s' % resource_class,
|
||||
resource_class: node}
|
||||
if delete:
|
||||
wrapper_dict.update({'marked_for_delete': True})
|
||||
LOG.debug("### WRAPPER DICT:%s", wrapper_dict)
|
||||
return wrapper_dict
|
||||
|
||||
def _find_parent_in_dict(self, d, resource_def, level=1):
|
||||
|
@ -124,21 +137,26 @@ class NsxPolicyTransaction(object):
|
|||
node = {'resource_type': resource_type,
|
||||
'id': parent_id,
|
||||
'children': []}
|
||||
LOG.debug("#### UNEXPECTED: %s", resource_type)
|
||||
return self._build_wrapper_dict(resource_class, node), node
|
||||
|
||||
# iterate over all objects in d, and look for resource type
|
||||
for child in d:
|
||||
parent = None
|
||||
if (child.get('target_type') == resource_type and
|
||||
child['resource_type'] == 'ChildResourceReference'):
|
||||
parent = child
|
||||
if resource_type in child and child[resource_type]:
|
||||
parent = child[resource_type]
|
||||
# If resource type matches, check for id
|
||||
if parent['id'] == parent_id:
|
||||
if is_leaf:
|
||||
return parent
|
||||
if 'children' not in parent:
|
||||
parent['children'] = []
|
||||
# If resource type matches, check for id
|
||||
if parent and parent['id'] == parent_id:
|
||||
if is_leaf:
|
||||
return parent
|
||||
if 'children' not in parent:
|
||||
parent['children'] = []
|
||||
|
||||
return self._find_parent_in_dict(
|
||||
parent['children'], resource_def, level + 1)
|
||||
return self._find_parent_in_dict(
|
||||
parent['children'], resource_def, level + 1)
|
||||
|
||||
# Parent not found - create a node for missing parent
|
||||
wrapper, node = create_missing_node()
|
||||
|
@ -162,6 +180,7 @@ class NsxPolicyTransaction(object):
|
|||
url = top_def.get_resource_path()
|
||||
body = {'resource_type': top_def.resource_type(),
|
||||
'children': []}
|
||||
|
||||
# iterate over defs (except top level def)
|
||||
for resource_def in self.defs[1:]:
|
||||
parent_dict = None
|
||||
|
@ -185,10 +204,18 @@ class NsxPolicyTransaction(object):
|
|||
child_def = resource_def.mandatory_child_def
|
||||
child_dict_key = child_def.get_last_section_dict_key
|
||||
node[child_dict_key] = [child_def.get_obj_dict()]
|
||||
parent_dict['children'].append(
|
||||
self._build_wrapper_dict(resource_class,
|
||||
node,
|
||||
resource_def.get_delete()))
|
||||
child_resource_ref = (
|
||||
resource_def.has_attr('child_resource_ref') and
|
||||
resource_def.get_attr('child_resource_ref'))
|
||||
LOG.debug("#### BEFORE WRAP CALL")
|
||||
LOG.debug("#### NODE XXX: %s", node)
|
||||
LOG.debug("#### CHILD REF:%s", child_resource_ref)
|
||||
meh = self._build_wrapper_dict(resource_class,
|
||||
node,
|
||||
resource_def.get_delete(),
|
||||
child_resource_ref)
|
||||
parent_dict['children'].append(meh)
|
||||
|
||||
if body:
|
||||
headers = {'nsx-enable-partial-patch': 'true'}
|
||||
|
||||
|
|
Loading…
Reference in New Issue