Add Tier0RouteRedistributionConfig methods

Change-Id: Ibf19d356dad33871ce18d7b785286d97beb1df74
This commit is contained in:
Danting Liu 2019-11-27 00:32:01 -08:00 committed by asarfaty
parent 468bf288a7
commit 737f127a22
5 changed files with 315 additions and 4 deletions

View File

@ -3775,6 +3775,67 @@ class TestPolicyTier0(NsxPolicyLibTestCase):
pt_mock.assert_called_once_with(logical_router_id)
self.assertIsNotNone(result)
def test_build_route_redistribution_rule(self):
name = "rule_name"
types = ["T1_CONNECTED", "T1_SEGMENT"]
route_map_path = "/infra/route_map_path"
rule = self.resourceApi.build_route_redistribution_rule(
name, types, route_map_path)
self.assertEqual(name, rule.name)
self.assertEqual(types, rule.route_redistribution_types)
self.assertEqual(route_map_path, rule.route_map_path)
def test_build_route_redistribution_config(self):
enabled = True
rules = ["redistribution_types"]
config = self.resourceApi.build_route_redistribution_config(
enabled, rules)
self.assertEqual(enabled, config.enabled)
self.assertEqual(rules, config.redistribution_rules)
def test_get_route_redistribution_config(self):
tier0_id = '111'
config = 'redistribution_config'
with mock.patch.object(
self.resourceApi, "get_locale_services",
return_value=[{'route_redistribution_config': config}]):
result = self.resourceApi.get_route_redistribution_config(
tier0_id, tenant=TEST_TENANT)
self.assertEqual(config, result)
def test_update_route_redistribution_config(self):
tier0_id = '111'
service_id = '222'
config = 'redistribution_config'
with mock.patch.object(
self.policy_api, "create_or_update") as api_call:
self.resourceApi.update_route_redistribution_config(
tier0_id, config, service_id, tenant=TEST_TENANT)
expected_def = core_defs.Tier0LocaleServiceDef(
nsx_version='3.0.0', tier0_id=tier0_id, service_id=service_id,
route_redistribution_config=config, tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
with mock.patch.object(self.resourceApi, "get_locale_services",
return_value=[]):
self.assertRaises(
nsxlib_exc.ManagerError,
self.resourceApi.update_route_redistribution_config,
tier0_id, config, tenant=TEST_TENANT)
def test_feature_supported(self):
with mock.patch.object(self.policy_lib, "get_version",
return_value='2.5.0'):
self.assertFalse(
self.policy_lib.feature_supported(
nsx_constants.FEATURE_ROUTE_REDISTRIBUTION_CONFIG))
with mock.patch.object(self.policy_lib, "get_version",
return_value='3.0.0'):
self.assertTrue(
self.policy_lib.feature_supported(
nsx_constants.FEATURE_ROUTE_REDISTRIBUTION_CONFIG))
class TestPolicyTier1Segment(NsxPolicyLibTestCase):

View File

@ -180,6 +180,7 @@ FEATURE_CONTAINER_CLUSTER_INVENTORY = 'Container Cluster Inventory'
FEATURE_IPV6 = 'IPV6 Forwarding and Address Allocation'
FEATURE_MP2P_MIGRATION = 'MP to Policy Migration'
FEATURE_SPOOFGUARD_CIDR = 'Spoofguard IPv4 CIDR'
FEATURE_ROUTE_REDISTRIBUTION_CONFIG = 'Tier0 route redistribution config'
# Features available depending on the Policy Manager backend version
FEATURE_NSX_POLICY = 'NSX Policy'

View File

@ -167,13 +167,13 @@ class NsxPolicyLib(lib.NsxLibBase):
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_2_4_0)):
# Features available since 2.4
if (feature == nsx_constants.FEATURE_NSX_POLICY_NETWORKING):
if feature == nsx_constants.FEATURE_NSX_POLICY_NETWORKING:
return True
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_2_5_0)):
# Features available since 2.5
if (feature == nsx_constants.FEATURE_ENS_WITH_QOS):
if feature == nsx_constants.FEATURE_ENS_WITH_QOS:
return True
if (version.LooseVersion(self.get_version()) >=
@ -187,11 +187,13 @@ class NsxPolicyLib(lib.NsxLibBase):
return True
if feature == nsx_constants.FEATURE_NSX_POLICY_DHCP:
return True
if (feature == nsx_constants.FEATURE_NSX_POLICY_GLOBAL_CONFIG):
if feature == nsx_constants.FEATURE_NSX_POLICY_GLOBAL_CONFIG:
return True
if feature == nsx_constants.FEATURE_ROUTE_REDISTRIBUTION_CONFIG:
return True
if feature == nsx_constants.FEATURE_NSX_POLICY_ADMIN_STATE:
return True
if (feature == nsx_constants.FEATURE_RELAX_SCALE_VALIDATION):
if feature == nsx_constants.FEATURE_RELAX_SCALE_VALIDATION:
return True
if (version.LooseVersion(self.get_version()) >=

View File

@ -522,6 +522,32 @@ class Tier0LocaleServiceDef(RouterLocaleServiceDef):
def path_defs(self):
return (TenantDef, Tier0Def)
def get_obj_dict(self):
body = super(Tier0LocaleServiceDef, self).get_obj_dict()
if (self.has_attr('route_redistribution_config') and
self._version_dependant_attr_supported(
'route_redistribution_config')):
config = self.get_attr('route_redistribution_config')
body['route_redistribution_config'] = (
config.get_obj_dict()
if isinstance(config, Tier0RouteRedistributionConfig)
else config)
return body
def _version_dependant_attr_supported(self, attr):
if (version.LooseVersion(self.nsx_version) >=
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
if attr == 'route_redistribution_config':
return True
LOG.warning(
"Ignoring %s for %s %s: this feature is not supported."
"Current NSX version: %s. Minimum supported version: %s",
attr, self.resource_type, self.attrs.get('name', ''),
self.nsx_version, nsx_constants.NSX_VERSION_3_0_0)
return False
class Tier1LocaleServiceDef(RouterLocaleServiceDef):
@ -2426,3 +2452,188 @@ class NsxPolicyApi(object):
def get_intent_consolidated_status(self, path, silent=False):
return self.client.get(REALIZATION_STATUS_PATH % path,
silent=silent)
class RouteMapEntry(object):
def __init__(self, action, community_list_matches=None,
prefix_list_matches=None, entry_set=None):
self.action = action
self.community_list_matches = community_list_matches
self.prefix_list_matches = prefix_list_matches
self.entry_set = entry_set
def get_obj_dict(self):
body = {'action': self.action}
if self.community_list_matches:
body['community_list_matches'] = [community.get_obj_dict()
for community in
self.community_list_matches]
if self.prefix_list_matches:
body['prefix_list_matches'] = (
self.prefix_list_matches
if isinstance(self.prefix_list_matches, list) else
[self.prefix_list_matches])
if self.entry_set:
body['set'] = self.entry_set.get_obj_dict()
return body
class RouteMapEntrySet(object):
def __init__(self, local_preference=100, as_path_prepend=None,
community=None, med=None, weight=None):
self.local_preference = local_preference
self.as_path_prepend = as_path_prepend
self.community = community
self.med = med
self.weight = weight
def get_obj_dict(self):
body = {'local_preference': self.local_preference}
if self.as_path_prepend:
body['as_path_prepend'] = self.as_path_prepend
if self.community:
body['community'] = self.community
if self.med:
body['med'] = self.med
if self.weight:
body['weight'] = self.weight
return body
class CommunityMatchCriteria(object):
def __init__(self, criteria, match_operator=None):
self.criteria = criteria
self.match_operator = match_operator
def get_obj_dict(self):
body = {'criteria': self.criteria}
if self.match_operator:
body['match_operator'] = self.match_operator
return body
class Tier0RouteMapDef(ResourceDef):
@property
def path_pattern(self):
return TIER0S_PATH_PATTERN + "%s/route-maps/"
@property
def path_ids(self):
return ('tenant', 'tier0_id', 'route_map_id')
@staticmethod
def resource_type():
return 'Tier0RouteMap'
def path_defs(self):
return (TenantDef, Tier0Def)
def get_obj_dict(self):
body = super(Tier0RouteMapDef, self).get_obj_dict()
entries = self.get_attr('entries')
if entries:
entries = [entry.get_obj_dict()
if isinstance(entry, RouteMapEntry) else entry
for entry in self.get_attr('entries')]
body['entries'] = entries
return body
class PrefixEntry(object):
def __init__(self, network, le=None, ge=None,
action=constants.ADV_RULE_PERMIT):
self.network = network
self.le = le
self.ge = ge
self.action = action
def get_obj_dict(self):
body = {'network': self.network,
'action': self.action}
if self.le is not None:
body['le'] = self.le
if self.ge is not None:
body['ge'] = self.ge
return body
class Tier0PrefixListDef(ResourceDef):
@property
def path_pattern(self):
return TIER0S_PATH_PATTERN + "%s/prefix-lists/"
@property
def path_ids(self):
return ('tenant', 'tier0_id', 'prefix_list_id')
@staticmethod
def resource_type():
return 'PrefixList'
def path_defs(self):
return (TenantDef, Tier0Def)
def get_obj_dict(self):
body = super(Tier0PrefixListDef, self).get_obj_dict()
prefixes = self.get_attr('prefixes')
if prefixes:
prefixes = [prefix.get_obj_dict() for prefix in prefixes]
body['prefixes'] = prefixes
return body
class BgpRoutingConfigDef(ResourceDef):
@staticmethod
def resource_type():
return 'BgpRoutingConfig'
@property
def path_pattern(self):
return TIER0_LOCALE_SERVICES_PATH_PATTERN + "%s/bgp"
@property
def path_ids(self):
# Adding dummy key to satisfy get_section_path
# This resource has no keys, since it is a single object
return ('tenant', 'tier0_id', 'service_id', 'dummy')
class Tier0RouteRedistributionConfig(object):
def __init__(self, enabled=None, redistribution_rules=None):
self.enabled = enabled
self.redistribution_rules = redistribution_rules
def get_obj_dict(self):
body = {}
if self.enabled:
body['enabled'] = self.enabled
if self.redistribution_rules is not None:
rules = [rule.get_obj_dict()
if isinstance(rule, Tier0RouteRedistributionRule) else
rule for rule in self.redistribution_rules]
body['redistribution_rules'] = rules
return body
class Tier0RouteRedistributionRule(object):
def __init__(self, name=None, route_redistribution_types=None,
route_map_path=None):
self.name = name
self.route_redistribution_types = route_redistribution_types or []
self.route_map_path = route_map_path
def get_obj_dict(self):
body = {'route_redistribution_types': self.route_redistribution_types}
if self.name:
body['name'] = self.name
if self.route_map_path:
body['route_map_path'] = self.route_map_path
return body

View File

@ -1608,6 +1608,42 @@ class NsxPolicyTier0Api(NsxPolicyResourceBase):
subnet.get('prefix_len')))
return cidrs
def build_route_redistribution_rule(self, name=None, types=None,
route_map_path=None):
return core_defs.Tier0RouteRedistributionRule(
name, types, route_map_path)
def build_route_redistribution_config(self, enabled=None, rules=None):
return core_defs.Tier0RouteRedistributionConfig(enabled, rules)
def get_route_redistribution_config(self, tier0_id,
tenant=constants.POLICY_INFRA_TENANT):
services = self.get_locale_services(tier0_id, tenant=tenant)
for srv in services:
if srv.get('route_redistribution_config'):
return srv['route_redistribution_config']
def update_route_redistribution_config(
self, tier0_id, redistribution_config, service_id=None,
tenant=constants.POLICY_INFRA_TENANT):
if not service_id:
# Update on the first locale service
services = self.get_locale_services(tier0_id, tenant=tenant)
if len(services) > 0:
service_id = services[0]['id']
if not service_id:
err_msg = (_("Cannot update route redistribution config without "
"locale service on Tier0 router"))
raise exceptions.ManagerError(details=err_msg)
service_def = core_defs.Tier0LocaleServiceDef(
nsx_version=self.version,
tier0_id=tier0_id,
service_id=service_id,
route_redistribution_config=redistribution_config,
tenant=tenant)
self.policy_api.create_or_update(service_def)
class NsxPolicyTier0NatRuleApi(NsxPolicyResourceBase):
DEFAULT_NAT_ID = 'USER'