diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py b/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py index 01031eb6..acf3c951 100644 --- a/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py +++ b/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py @@ -39,7 +39,7 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): def assert_infra_patch_call(self, body): self.assert_json_call('PATCH', self.client, 'infra', - data=body) + data=body, headers=mock.ANY) def test_domains_only(self): diff --git a/vmware_nsxlib/v3/policy/core_defs.py b/vmware_nsxlib/v3/policy/core_defs.py index 0ad9f147..1846e7ee 100644 --- a/vmware_nsxlib/v3/policy/core_defs.py +++ b/vmware_nsxlib/v3/policy/core_defs.py @@ -474,6 +474,9 @@ class Tier0LocaleServiceDef(RouterLocaleServiceDef): def path_ids(self): return ('tenant', 'tier0_id', 'service_id') + def path_defs(self): + return (TenantDef, Tier0Def) + class Tier1LocaleServiceDef(RouterLocaleServiceDef): @@ -826,9 +829,11 @@ class PortAddressBinding(object): self.vlan_id = vlan_id def get_obj_dict(self): - return {'ip_address': self.ip_address, - 'mac_address': self.mac_address, - 'vlan_id': self.vlan_id} + data = {'ip_address': self.ip_address, + 'mac_address': self.mac_address} + if self.vlan_id is not None: + data['vlan_id'] = self.vlan_id + return data class SegmentPortDef(ResourceDef): diff --git a/vmware_nsxlib/v3/policy/core_resources.py b/vmware_nsxlib/v3/policy/core_resources.py index 5145086b..61ae5368 100644 --- a/vmware_nsxlib/v3/policy/core_resources.py +++ b/vmware_nsxlib/v3/policy/core_resources.py @@ -1122,7 +1122,7 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase): tier1_id=tier1_id, service_id=self._locale_service_id(tier1_id), tenant=tenant) - self.policy_api.create_or_update(t1service_def) + self._create_or_store(t1service_def) def delete_locale_service(self, tier1_id, tenant=constants.POLICY_INFRA_TENANT): @@ -3078,6 +3078,10 @@ class NsxPolicySecurityPolicyBaseApi(NsxPolicyResourceBase): self._create_or_store(entry_def) return entry_id + def create_entry_from_def(self, entry_def): + """Create CommunicationMap Entry from a predefined entry def""" + self._create_or_store(entry_def) + def delete(self, domain_id, map_id, tenant=constants.POLICY_INFRA_TENANT): map_def = self._init_parent_def( diff --git a/vmware_nsxlib/v3/policy/transaction.py b/vmware_nsxlib/v3/policy/transaction.py index 29adff78..0599d189 100644 --- a/vmware_nsxlib/v3/policy/transaction.py +++ b/vmware_nsxlib/v3/policy/transaction.py @@ -102,12 +102,13 @@ class NsxPolicyTransaction(object): def _find_parent_in_dict(self, d, resource_def, level=1): - if len(resource_def.path_defs()) <= level: + res_path_defs = resource_def.path_defs() + if not res_path_defs or len(res_path_defs) <= level: return parent_type = resource_def.path_defs()[level] - is_leaf = (level + 1 == len(resource_def.path_defs())) + is_leaf = (level + 1 == len(res_path_defs)) resource_type = parent_type.resource_type() resource_class = parent_type.resource_class() parent_id = resource_def.get_attr(resource_def.path_ids[level]) @@ -144,8 +145,8 @@ class NsxPolicyTransaction(object): def apply_defs(self): # TODO(annak): find longest common URL, for now always # applying on tenant level - - if not self.defs: + if not self.defs or not self.client: + # Empty transaction return self._sort_defs() @@ -178,11 +179,11 @@ class NsxPolicyTransaction(object): 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, - resource_def.get_obj_dict())) + self._build_wrapper_dict(resource_class, node)) if body: - self.client.patch(url, body) + headers = {'nsx-enable-partial-patch': 'true'} + self.client.patch(url, body, headers=headers) @staticmethod def get_current():