From b3f79b5af5031a7f973eed4cad7fbba44a6a12ba Mon Sep 17 00:00:00 2001 From: Yun-Tang Hsu Date: Mon, 5 Aug 2024 13:14:25 -0700 Subject: [PATCH] Support HAPI for lb-pool and lb-virtual-server In this patch, we support HAPI for lb-pool and lb-virtual-server whose tenant is org-root We also fix a bug in func _build_wrapper_dict where the children array of wrapper_dict and the children array of node should be the same one. Change-Id: Iaaf392f7e6904605e8ddd84d6691c92fc845dda6 Signed-off-by: Yun-Tang Hsu Signed-off-by: Yun-Tang Hsu --- .../tests/unit/v3/policy/test_lb_resources.py | 86 +++++++++++++++++++ .../tests/unit/v3/policy/test_transaction.py | 80 +++++++++++------ vmware_nsxlib/v3/policy/constants.py | 1 + vmware_nsxlib/v3/policy/core_defs.py | 82 ++++++++++++++++++ vmware_nsxlib/v3/policy/core_resources.py | 17 ++++ vmware_nsxlib/v3/policy/lb_defs.py | 37 +++++++- vmware_nsxlib/v3/policy/lb_resources.py | 29 ++++++- vmware_nsxlib/v3/policy/transaction.py | 14 +-- 8 files changed, 309 insertions(+), 37 deletions(-) diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py b/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py index 9916c2aa..76ac7e41 100644 --- a/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py +++ b/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py @@ -23,7 +23,11 @@ from vmware_nsxlib.v3 import exceptions as nsxlib_exc from vmware_nsxlib.v3 import nsx_constants from vmware_nsxlib.v3.policy import constants from vmware_nsxlib.v3.policy import lb_defs +from vmware_nsxlib.v3.policy.lb_defs import VPC_LB_POOL_PATH_HAPI_PATTERN from vmware_nsxlib.v3.policy.lb_defs import VPC_LB_SERVICES_PATH_PATTERN +from vmware_nsxlib.v3.policy.lb_defs import \ + VPC_LB_VIRTUAL_SERVERS_HAPI_PATH_PATTERN +from vmware_nsxlib.v3.policy import transaction as trans TEST_TENANT = 'test' TEST_VPC_TENANT = 'orgs/default/projects/proj-2/vpcs/vpc-1234' @@ -1306,6 +1310,47 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase): self.assertEqual(body['lb_service_path'], lb_service_path) + def test_create_delete_with_vpc_tenant_hapi(self): + name = 'd1' + obj_id = '111' + + with trans.NsxPolicyTransaction() as t: + self.resourceApi.create_or_overwrite( + name=name, + virtual_server_id=obj_id, + tenant=TEST_VPC_TENANT) + + expected_def = lb_defs.LBVirtualServerDef( + nsx_version=self.policy_lib.get_version(), + virtual_server_id=obj_id, name=name, + tenant=constants.POLICY_ORG_ROOT_TENANT, + ) + actual_def = t.defs[1] + self._compare_def(expected_def, actual_def) + self.assertEqual(actual_def.get_attr('org_id'), 'default') + self.assertEqual(actual_def.get_attr('project_id'), 'proj-2') + self.assertEqual(actual_def.get_attr('vpc_id'), 'vpc-1234') + self.assertEqual(actual_def.path_pattern, + VPC_LB_VIRTUAL_SERVERS_HAPI_PATH_PATTERN) + + with trans.NsxPolicyTransaction() as t: + self.resourceApi.delete( + virtual_server_id=obj_id, + tenant=TEST_VPC_TENANT) + + expected_def = lb_defs.LBVirtualServerDef( + nsx_version=self.policy_lib.get_version(), + virtual_server_id=obj_id, + tenant=constants.POLICY_ORG_ROOT_TENANT, + ) + actual_def = t.defs[1] + self._compare_def(expected_def, actual_def) + self.assertEqual(actual_def.get_attr('org_id'), 'default') + self.assertEqual(actual_def.get_attr('project_id'), 'proj-2') + self.assertEqual(actual_def.get_attr('vpc_id'), 'vpc-1234') + self.assertEqual(actual_def.path_pattern, + VPC_LB_VIRTUAL_SERVERS_HAPI_PATH_PATTERN) + def test_delete(self): obj_id = '111' with mock.patch.object(self.policy_api, "delete") as api_call: @@ -1796,6 +1841,47 @@ class TestPolicyLBPoolApi(test_resources.NsxPolicyLibTestCase): self.assert_called_with_def(api_call, expected_def) self.assertIsNotNone(result) + def test_create_delete_with_vpc_tenant_hapi(self): + name = 'd1' + obj_id = '111' + + with trans.NsxPolicyTransaction() as t: + self.resourceApi.create_or_overwrite( + name=name, + lb_pool_id=obj_id, + tenant=TEST_VPC_TENANT) + + expected_def = lb_defs.LBPoolDef( + nsx_version=self.policy_lib.get_version(), + lb_pool_id=obj_id, name=name, + tenant=constants.POLICY_ORG_ROOT_TENANT, + ) + actual_def = t.defs[1] + self._compare_def(expected_def, actual_def) + self.assertEqual(actual_def.get_attr('org_id'), 'default') + self.assertEqual(actual_def.get_attr('project_id'), 'proj-2') + self.assertEqual(actual_def.get_attr('vpc_id'), 'vpc-1234') + self.assertEqual(actual_def.path_pattern, + VPC_LB_POOL_PATH_HAPI_PATTERN) + + with trans.NsxPolicyTransaction() as t: + self.resourceApi.delete( + lb_pool_id=obj_id, + tenant=TEST_VPC_TENANT) + + expected_def = lb_defs.LBPoolDef( + nsx_version=self.policy_lib.get_version(), + lb_pool_id=obj_id, + tenant=constants.POLICY_ORG_ROOT_TENANT, + ) + actual_def = t.defs[1] + self._compare_def(expected_def, actual_def) + self.assertEqual(actual_def.get_attr('org_id'), 'default') + self.assertEqual(actual_def.get_attr('project_id'), 'proj-2') + self.assertEqual(actual_def.get_attr('vpc_id'), 'vpc-1234') + self.assertEqual(actual_def.path_pattern, + VPC_LB_POOL_PATH_HAPI_PATTERN) + def test_create_with_retry_stale_revision(self): name = 'd1' description = 'desc' diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py b/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py index 83a43165..7136e089 100644 --- a/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py +++ b/vmware_nsxlib/tests/unit/v3/policy/test_transaction.py @@ -207,10 +207,15 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): 'Group': g}) expected_body = {'resource_type': 'Infra', - 'children': [{'resource_type': 'ChildDomain', - 'Domain': d1}, - {'resource_type': 'ChildDomain', - 'Domain': d2}]} + 'children': [ + {'resource_type': 'ChildResourceReference', + 'id': d1.get('id'), + 'target_type': d1.get('resource_type'), + 'children': d1.get('children')}, + {'resource_type': 'ChildResourceReference', + 'id': d2.get('id'), + 'target_type': d2.get('resource_type'), + 'children': d2.get('children')}]} self.assert_infra_patch_call(expected_body) @@ -260,10 +265,15 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): traffic_tag=port2['attachment']['traffic_tag']) expected_body = {'resource_type': 'Infra', - 'children': [{'resource_type': 'ChildSegment', - 'Segment': seg1}, - {'resource_type': 'ChildSegment', - 'Segment': seg2}]} + 'children': [ + {'resource_type': 'ChildResourceReference', + 'id': seg1.get('id'), + 'target_type': seg1.get('resource_type'), + 'children': seg1.get('children')}, + {'resource_type': 'ChildResourceReference', + 'id': seg2.get('id'), + 'target_type': seg2.get('resource_type'), + 'children': seg2.get('children')}]} self.assert_infra_patch_call(expected_body) @@ -292,8 +302,11 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): "resource_type": "ChildPolicyNatRule"}]} tier1_dict = {"id": tier1_id, "resource_type": "Tier1", - "children": [{"PolicyNat": policy_nat, - "resource_type": "ChildPolicyNat"}]} + "children": [ + {'resource_type': 'ChildResourceReference', + 'id': policy_nat.get('id'), + 'target_type': policy_nat.get('resource_type'), + 'children': policy_nat.get('children')}]} with trans.NsxPolicyTransaction(): self.policy_lib.tier1_nat_rule.create_or_overwrite( @@ -309,8 +322,11 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): action=constants.NAT_ACTION_DNAT) expected_body = {"resource_type": "Infra", - "children": [{"Tier1": tier1_dict, - "resource_type": "ChildTier1"}]} + "children": [ + {'resource_type': 'ChildResourceReference', + 'id': tier1_dict.get('id'), + 'target_type': tier1_dict.get('resource_type'), + 'children': tier1_dict.get('children')}]} self.assert_infra_patch_call(expected_body) @@ -337,8 +353,11 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): "resource_type": "ChildPolicyNatRule"}]} tier1_dict = {"id": tier1_id, "resource_type": "Tier1", - "children": [{"PolicyNat": policy_nat, - "resource_type": "ChildPolicyNat"}]} + "children": [ + {'resource_type': 'ChildResourceReference', + 'id': policy_nat.get('id'), + 'target_type': policy_nat.get('resource_type'), + 'children': policy_nat.get('children')}]} with trans.NsxPolicyTransaction(): self.policy_lib.tier1_nat_rule.delete( @@ -350,8 +369,11 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): nat_rule_id=nat_rule_id2) expected_body = {"resource_type": "Infra", - "children": [{"Tier1": tier1_dict, - "resource_type": "ChildTier1"}]} + "children": [ + {'resource_type': 'ChildResourceReference', + 'id': tier1_dict.get('id'), + 'target_type': tier1_dict.get('resource_type'), + 'children': tier1_dict.get('children')}]} self.assert_infra_patch_call(expected_body) @@ -401,8 +423,12 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): 'SecurityPolicy': security_policy }] domain.update({'children': child_security_policies}) - child_domains = [{'resource_type': 'ChildDomain', - 'Domain': domain}] + child_domains = [{ + 'resource_type': 'ChildResourceReference', + 'id': domain.get('id'), + 'target_type': domain.get('resource_type'), + 'children': domain.get('children') + }] expected_body = {'resource_type': 'Infra', 'children': child_domains} self.assert_infra_patch_call(expected_body) @@ -487,8 +513,10 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): }] domain.update({'children': child_security_policies}) child_domains = [{ - 'resource_type': 'ChildDomain', - 'Domain': domain + 'resource_type': 'ChildResourceReference', + 'id': domain.get('id'), + 'target_type': domain.get('resource_type'), + 'children': domain.get('children') }] expected_body = {'resource_type': 'Infra', 'children': child_domains} @@ -571,8 +599,10 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): child_security_policies[0].update({'children': child_rules}) domain.update({'children': child_security_policies}) child_domains = [{ - 'resource_type': 'ChildDomain', - 'Domain': domain + 'resource_type': 'ChildResourceReference', + 'id': domain.get('id'), + 'target_type': domain.get('resource_type'), + 'children': domain.get('children') }] expected_body = {'resource_type': 'Infra', 'children': child_domains} @@ -624,8 +654,10 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi): }] domain.update({'children': child_security_policies}) child_domains = [{ - 'resource_type': 'ChildDomain', - 'Domain': domain + 'resource_type': 'ChildResourceReference', + 'id': domain.get('id'), + 'target_type': domain.get('resource_type'), + 'children': domain.get('children') }] expected_body = {'resource_type': 'Infra', 'children': child_domains} diff --git a/vmware_nsxlib/v3/policy/constants.py b/vmware_nsxlib/v3/policy/constants.py index d0692273..15e81bfc 100644 --- a/vmware_nsxlib/v3/policy/constants.py +++ b/vmware_nsxlib/v3/policy/constants.py @@ -17,6 +17,7 @@ TCP = 'TCP' UDP = 'UDP' POLICY_INFRA_TENANT = 'infra' +POLICY_ORG_ROOT_TENANT = 'org-root' POLICY_AAA_TENANT = 'aaa' ACTION_ALLOW = 'ALLOW' diff --git a/vmware_nsxlib/v3/policy/core_defs.py b/vmware_nsxlib/v3/policy/core_defs.py index 0884e63b..74a23133 100644 --- a/vmware_nsxlib/v3/policy/core_defs.py +++ b/vmware_nsxlib/v3/policy/core_defs.py @@ -28,6 +28,9 @@ from vmware_nsxlib.v3 import utils LOG = logging.getLogger(__name__) TENANTS_PATH_PATTERN = "%s/" +ORGS_PATH_PATTERN = TENANTS_PATH_PATTERN + "orgs/" +PROJECTS_PATH_PATTERN = ORGS_PATH_PATTERN + "%s/projects/" +VPCS_PATH_PATTERN = PROJECTS_PATH_PATTERN + "%s/vpcs/" DOMAINS_PATH_PATTERN = TENANTS_PATH_PATTERN + "domains/" SHARES_PATH_PATTERN = TENANTS_PATH_PATTERN + "shares/" IP_BLOCKS_PATH_PATTERN = TENANTS_PATH_PATTERN + "ip-blocks/" @@ -321,6 +324,9 @@ class ResourceDef(object, metaclass=abc.ABCMeta): else: return False + def is_org_root_tenant(self): + return self.get_tenant() == 'org-root' + class TenantDef(ResourceDef): @property @@ -345,6 +351,82 @@ class TenantDef(ResourceDef): return 'infra/' +class TenantOrgRootDef(ResourceDef): + @property + def path_pattern(self): + return TENANTS_PATH_PATTERN + + @staticmethod + def resource_type(): + return 'OrgRoot' + + def path_defs(self): + return () + + @property + def path_ids(self): + return ('tenant',) + + def get_resource_path(self): + return 'org-root/' + + def get_section_path(self): + return 'org-root/' + + +class TenantOrgDef(ResourceDef): + @property + def path_pattern(self): + return ORGS_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'org_id') + + @staticmethod + def resource_type(): + return 'Org' + + def path_defs(self): + return (TenantOrgRootDef) + + +class ProjectDef(ResourceDef): + + @property + def path_pattern(self): + return PROJECTS_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'org_id', 'project_id') + + @staticmethod + def resource_type(): + return 'Project' + + def path_defs(self): + return (TenantOrgRootDef, TenantOrgDef) + + +class VPCDef(ResourceDef): + + @property + def path_pattern(self): + return VPCS_PATH_PATTERN + + @property + def path_ids(self): + return ('tenant', 'org_id', 'project_id', 'vpc_id') + + @staticmethod + def resource_type(): + return 'Vpc' + + def path_defs(self): + return (TenantOrgRootDef, TenantOrgDef, ProjectDef) + + class DomainDef(ResourceDef): @property diff --git a/vmware_nsxlib/v3/policy/core_resources.py b/vmware_nsxlib/v3/policy/core_resources.py index 33f9e963..730a5afa 100644 --- a/vmware_nsxlib/v3/policy/core_resources.py +++ b/vmware_nsxlib/v3/policy/core_resources.py @@ -516,6 +516,23 @@ class NsxPolicyResourceBase(object, metaclass=abc.ABCMeta): do_delete(force=force) + def is_vpc_tenant(self, tenant): + return tenant and '/projects/' in tenant + + def is_vpc_hapi(self, tenant): + transaction = trans.NsxPolicyTransaction.get_current() + return self.is_vpc_tenant(tenant) and transaction + + def get_ids(self, tenant): + if self.is_vpc_hapi(tenant): + ids = tenant.split('/') + org_id = ids[1] + project_id = ids[3] + vpc_id = ids[5] + return org_id, project_id, vpc_id,\ + constants.POLICY_ORG_ROOT_TENANT + return None, None, None, tenant + class NsxPolicyDomainApi(NsxPolicyResourceBase): """NSX Policy Domain.""" diff --git a/vmware_nsxlib/v3/policy/lb_defs.py b/vmware_nsxlib/v3/policy/lb_defs.py index 6088c17f..44303223 100644 --- a/vmware_nsxlib/v3/policy/lb_defs.py +++ b/vmware_nsxlib/v3/policy/lb_defs.py @@ -17,7 +17,13 @@ from oslo_log import log as logging from vmware_nsxlib.v3 import nsx_constants from vmware_nsxlib.v3.policy import constants +from vmware_nsxlib.v3.policy.core_defs import ProjectDef from vmware_nsxlib.v3.policy.core_defs import ResourceDef +from vmware_nsxlib.v3.policy.core_defs import TenantOrgDef +from vmware_nsxlib.v3.policy.core_defs import TenantOrgRootDef +from vmware_nsxlib.v3.policy.core_defs import VPCDef +from vmware_nsxlib.v3.policy.core_defs import VPCS_PATH_PATTERN + LOG = logging.getLogger(__name__) @@ -25,10 +31,14 @@ TENANTS_PATH_PATTERN = "%s/" LB_VIRTUAL_SERVERS_PATH_PATTERN = TENANTS_PATH_PATTERN + "lb-virtual-servers/" VPC_LB_VIRTUAL_SERVERS_PATH_PATTERN = (TENANTS_PATH_PATTERN + "vpc-lb-virtual-servers/") +VPC_LB_VIRTUAL_SERVERS_HAPI_PATH_PATTERN = (VPCS_PATH_PATTERN + + '%s/vpc-lb-virtual-servers/') LB_SERVICES_PATH_PATTERN = TENANTS_PATH_PATTERN + "lb-services/" VPC_LB_SERVICES_PATH_PATTERN = TENANTS_PATH_PATTERN + "vpc-lbs/" LB_POOL_PATH_PATTERN = TENANTS_PATH_PATTERN + "lb-pools/" VPC_LB_POOL_PATH_PATTERN = TENANTS_PATH_PATTERN + "vpc-lb-pools/" +VPC_LB_POOL_PATH_HAPI_PATTERN = (VPCS_PATH_PATTERN + + '%s/vpc-lb-pools/') LB_APP_PROFILE_PATTERN = TENANTS_PATH_PATTERN + "lb-app-profiles/" LB_MONITOR_PROFILE_PATTERN = TENANTS_PATH_PATTERN + "lb-monitor-profiles/" LB_CLIENT_SSL_PROFILE_PATTERN = (TENANTS_PATH_PATTERN + @@ -232,13 +242,22 @@ class LBPoolDef(ResourceDef): @property def path_pattern(self): - if self.is_vpc_tenant(): + if self.is_org_root_tenant(): + return VPC_LB_POOL_PATH_HAPI_PATTERN + elif self.is_vpc_tenant(): return VPC_LB_POOL_PATH_PATTERN return LB_POOL_PATH_PATTERN @property def path_ids(self): - return ('tenant', 'lb_pool_id') + if self.is_org_root_tenant(): + return ('tenant', 'org_id', 'project_id', 'vpc_id', 'lb_pool_id') + else: + return ('tenant', 'lb_pool_id') + + def path_defs(self): + if self.is_org_root_tenant(): + return (TenantOrgRootDef, TenantOrgDef, ProjectDef, VPCDef) @staticmethod def resource_type(): @@ -268,13 +287,23 @@ class LBVirtualServerDef(ResourceDef): @property def path_pattern(self): - if self.is_vpc_tenant(): + if self.is_org_root_tenant(): + return VPC_LB_VIRTUAL_SERVERS_HAPI_PATH_PATTERN + elif self.is_vpc_tenant(): return VPC_LB_VIRTUAL_SERVERS_PATH_PATTERN return LB_VIRTUAL_SERVERS_PATH_PATTERN @property def path_ids(self): - return ('tenant', 'virtual_server_id') + if self.is_org_root_tenant(): + return ('tenant', 'org_id', 'project_id', + 'vpc_id', 'virtual_server_id') + else: + return ('tenant', 'virtual_server_id') + + def path_defs(self): + if self.is_org_root_tenant(): + return (TenantOrgRootDef, TenantOrgDef, ProjectDef, VPCDef) @staticmethod def resource_type(): diff --git a/vmware_nsxlib/v3/policy/lb_resources.py b/vmware_nsxlib/v3/policy/lb_resources.py index 1809beb3..cc37963d 100644 --- a/vmware_nsxlib/v3/policy/lb_resources.py +++ b/vmware_nsxlib/v3/policy/lb_resources.py @@ -480,6 +480,7 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase): tcp_multiplexing_number=IGNORE, tenant=constants.POLICY_INFRA_TENANT): lb_pool_id = self._init_obj_uuid(lb_pool_id) + org_id, project_id, vpc_id, tenant = self.get_ids(tenant) lb_pool_def = self._init_def( lb_pool_id=lb_pool_id, name=name, @@ -492,15 +493,25 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase): snat_translation=snat_translation, tcp_multiplexing_enabled=tcp_multiplexing_enabled, tcp_multiplexing_number=tcp_multiplexing_number, - tenant=tenant) + tenant=tenant, + org_id=org_id, + project_id=project_id, + vpc_id=vpc_id + ) self._create_or_store(lb_pool_def) return lb_pool_id def delete(self, lb_pool_id, tenant=constants.POLICY_INFRA_TENANT): + org_id, project_id, vpc_id, tenant = self.get_ids(tenant) lb_pool_def = self.entry_def( - lb_pool_id=lb_pool_id, tenant=tenant) + lb_pool_id=lb_pool_id, + tenant=tenant, + org_id=org_id, + project_id=project_id, + vpc_id=vpc_id + ) self._delete_or_store(lb_pool_def) def get(self, lb_pool_id, tenant=constants.POLICY_INFRA_TENANT, @@ -807,6 +818,7 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase): tags=IGNORE, access_log_enabled=IGNORE, log_significant_event_only=IGNORE): virtual_server_id = self._init_obj_uuid(virtual_server_id) + org_id, project_id, vpc_id, tenant = self.get_ids(tenant) lbvs_def = self._init_def( virtual_server_id=virtual_server_id, name=name, @@ -826,15 +838,24 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase): access_list_control=access_list_control, tags=tags, access_log_enabled=access_log_enabled, - log_significant_event_only=log_significant_event_only + log_significant_event_only=log_significant_event_only, + org_id=org_id, + project_id=project_id, + vpc_id=vpc_id ) self._create_or_store(lbvs_def) return virtual_server_id def delete(self, virtual_server_id, tenant=constants.POLICY_INFRA_TENANT): + org_id, project_id, vpc_id, tenant = self.get_ids(tenant) lbvs_def = self.entry_def( - virtual_server_id=virtual_server_id, tenant=tenant) + virtual_server_id=virtual_server_id, + tenant=tenant, + org_id=org_id, + project_id=project_id, + vpc_id=vpc_id + ) self._delete_or_store(lbvs_def) def get(self, virtual_server_id, diff --git a/vmware_nsxlib/v3/policy/transaction.py b/vmware_nsxlib/v3/policy/transaction.py index 9eb215ef..c7b0c622 100644 --- a/vmware_nsxlib/v3/policy/transaction.py +++ b/vmware_nsxlib/v3/policy/transaction.py @@ -40,10 +40,13 @@ class NsxPolicyTransaction(object): data = threading.local() - def __init__(self): + def __init__(self, tenant=constants.POLICY_INFRA_TENANT): # For now only infra tenant is supported - self.defs = [core_defs.TenantDef( - tenant=constants.POLICY_INFRA_TENANT)] + # Org-root tenant is supported only for lb-pool and lb-virtual-server + if tenant == constants.POLICY_ORG_ROOT_TENANT: + self.defs = [core_defs.TenantOrgRootDef(tenant=tenant)] + else: + self.defs = [core_defs.TenantDef(tenant=tenant)] self.client = None def __enter__(self): @@ -111,7 +114,7 @@ class NsxPolicyTransaction(object): wrapper_dict = {'resource_type': 'ChildResourceReference', 'target_type': resource_class, 'id': node['id'], - 'children': []} + 'children': node.get('children', [])} else: wrapper_dict = {'resource_type': 'Child%s' % resource_class, resource_class: node} @@ -136,7 +139,8 @@ class NsxPolicyTransaction(object): node = {'resource_type': resource_type, 'id': parent_id, 'children': []} - return self._build_wrapper_dict(resource_class, node), node + return self._build_wrapper_dict( + resource_class, node, child_resource_ref=True), node # iterate over all objects in d, and look for resource type for child in d: