Support policy segment & port admin state

Change-Id: I1254d4bccec44c1b7fa65c106a1261e00c57f2f2
This commit is contained in:
asarfaty 2020-01-14 11:14:04 +02:00
parent a135d7f5ee
commit 9e4f33500d
5 changed files with 144 additions and 14 deletions

View File

@ -3613,7 +3613,8 @@ class TestPolicySegment(NsxPolicyLibTestCase):
super(TestPolicySegment, self).setUp() super(TestPolicySegment, self).setUp()
self.resourceApi = self.policy_lib.segment self.resourceApi = self.policy_lib.segment
def _test_create(self, tier1_id=None, mdproxy=None, dhcp_server=None): def _test_create(self, tier1_id=None, mdproxy=None, dhcp_server=None,
admin_state=None):
name = 'test' name = 'test'
description = 'desc' description = 'desc'
tier1_id = '111' tier1_id = '111'
@ -3625,18 +3626,20 @@ class TestPolicySegment(NsxPolicyLibTestCase):
if tier1_id: if tier1_id:
kwargs['tier1_id'] = tier1_id kwargs['tier1_id'] = tier1_id
if mdproxy: if mdproxy:
kwargs['metadata_proxy_id'] = mdproxy kwargs['metadata_proxy_id'] = mdproxy
if dhcp_server: if dhcp_server:
kwargs['dhcp_server_config_id'] = dhcp_server kwargs['dhcp_server_config_id'] = dhcp_server
if admin_state:
kwargs['admin_state'] = admin_state
with mock.patch.object(self.policy_api, with mock.patch.object(self.policy_api,
"create_or_update") as api_call: "create_or_update") as api_call:
result = self.resourceApi.create_or_overwrite( result = self.resourceApi.create_or_overwrite(
name, **kwargs) name, **kwargs)
if admin_state:
kwargs['admin_state'] = admin_state if 'UP' else 'DOWN'
expected_def = core_defs.SegmentDef( expected_def = core_defs.SegmentDef(
nsx_version='3.0.0', nsx_version='3.0.0',
segment_id=mock.ANY, segment_id=mock.ANY,
@ -3655,6 +3658,12 @@ class TestPolicySegment(NsxPolicyLibTestCase):
def test_create_with_dhcp_server_config(self): def test_create_with_dhcp_server_config(self):
self._test_create(dhcp_server='dhcp1') self._test_create(dhcp_server='dhcp1')
def test_create_with_admin_state_up(self):
self._test_create(admin_state=True)
def test_create_with_admin_state_down(self):
self._test_create(admin_state=False)
def test_delete(self): def test_delete(self):
segment_id = '111' segment_id = '111'
with mock.patch.object(self.policy_api, "delete") as api_call: with mock.patch.object(self.policy_api, "delete") as api_call:
@ -3684,14 +3693,18 @@ class TestPolicySegment(NsxPolicyLibTestCase):
def test_update(self): def test_update(self):
segment_id = '111' segment_id = '111'
name = 'new name' name = 'new name'
admin_state = False
with self.mock_get(segment_id, name), \ with self.mock_get(segment_id, name), \
self.mock_create_update() as update_call: self.mock_create_update() as update_call:
self.resourceApi.update(segment_id, self.resourceApi.update(segment_id,
name=name, name=name,
admin_state=admin_state,
tenant=TEST_TENANT) tenant=TEST_TENANT)
expected_def = core_defs.SegmentDef(segment_id=segment_id, expected_def = core_defs.SegmentDef(nsx_version='3.0.0',
segment_id=segment_id,
name=name, name=name,
admin_state=admin_state,
tenant=TEST_TENANT) tenant=TEST_TENANT)
self.assert_called_with_def(update_call, expected_def) self.assert_called_with_def(update_call, expected_def)
@ -4091,6 +4104,7 @@ class TestPolicySegmentPort(NsxPolicyLibTestCase):
traffic_tag = 10 traffic_tag = 10
allocate_addresses = "BOTH" allocate_addresses = "BOTH"
tags = [{'scope': 'a', 'tag': 'b'}] tags = [{'scope': 'a', 'tag': 'b'}]
admin_state = True
with mock.patch.object(self.policy_api, with mock.patch.object(self.policy_api,
"create_or_update") as api_call: "create_or_update") as api_call:
@ -4099,10 +4113,56 @@ class TestPolicySegmentPort(NsxPolicyLibTestCase):
address_bindings=address_bindings, address_bindings=address_bindings,
attachment_type=attachment_type, vif_id=vif_id, app_id=app_id, attachment_type=attachment_type, vif_id=vif_id, app_id=app_id,
context_id=context_id, traffic_tag=traffic_tag, context_id=context_id, traffic_tag=traffic_tag,
allocate_addresses=allocate_addresses, tags=tags, allocate_addresses=allocate_addresses,
admin_state=admin_state, tags=tags,
tenant=TEST_TENANT) tenant=TEST_TENANT)
expected_def = core_defs.SegmentPortDef( expected_def = core_defs.SegmentPortDef(
nsx_version='3.0.0',
segment_id=segment_id,
port_id=mock.ANY,
name=name,
description=description,
address_bindings=address_bindings,
attachment_type=attachment_type,
vif_id=vif_id,
app_id=app_id,
context_id=context_id,
traffic_tag=traffic_tag,
allocate_addresses=allocate_addresses,
admin_state=admin_state,
tags=tags,
tenant=TEST_TENANT)
self.assert_called_with_def(api_call, expected_def)
self.assertIsNotNone(result)
def test_create_with_unsupported_attribute(self):
name = 'test'
description = 'desc'
segment_id = "segment"
address_bindings = []
attachment_type = "CHILD"
vif_id = "vif"
app_id = "app"
context_id = "context"
traffic_tag = 10
allocate_addresses = "BOTH"
tags = [{'scope': 'a', 'tag': 'b'}]
admin_state = False
with mock.patch.object(
self.policy_api, "create_or_update") as api_call, \
mock.patch.object(self.resourceApi, 'version', '0.0.0'):
result = self.resourceApi.create_or_overwrite(
name, segment_id, description=description,
address_bindings=address_bindings,
attachment_type=attachment_type, vif_id=vif_id, app_id=app_id,
context_id=context_id, traffic_tag=traffic_tag,
allocate_addresses=allocate_addresses, tags=tags,
tenant=TEST_TENANT, admin_state=admin_state)
expected_def = core_defs.SegmentPortDef(
nsx_version=self.policy_lib.get_version(),
segment_id=segment_id, segment_id=segment_id,
port_id=mock.ANY, port_id=mock.ANY,
name=name, name=name,

View File

@ -177,6 +177,7 @@ FEATURE_NSX_POLICY_NETWORKING = 'NSX Policy Networking'
FEATURE_NSX_POLICY_MDPROXY = 'NSX Policy Metadata Proxy' FEATURE_NSX_POLICY_MDPROXY = 'NSX Policy Metadata Proxy'
FEATURE_NSX_POLICY_DHCP = 'NSX Policy DHCP' FEATURE_NSX_POLICY_DHCP = 'NSX Policy DHCP'
FEATURE_NSX_POLICY_GLOBAL_CONFIG = 'NSX Policy Global Config' FEATURE_NSX_POLICY_GLOBAL_CONFIG = 'NSX Policy Global Config'
FEATURE_NSX_POLICY_ADMIN_STATE = 'NSX Policy Segment admin state'
# FEATURE available depending on Inventory service backend version # FEATURE available depending on Inventory service backend version
FEATURE_CONTAINER_CLUSTER_INVENTORY = 'Container Cluster Inventory' FEATURE_CONTAINER_CLUSTER_INVENTORY = 'Container Cluster Inventory'

View File

@ -37,7 +37,6 @@ class NsxPolicyLib(lib.NsxLibBase):
def init_api(self): def init_api(self):
# Initialize the policy client # Initialize the policy client
# TODO(annak): move the API class to separate file
self.policy_api = core_defs.NsxPolicyApi(self.client) self.policy_api = core_defs.NsxPolicyApi(self.client)
# NSX manager api will be used as a pass-through for apis which are # NSX manager api will be used as a pass-through for apis which are
@ -178,6 +177,8 @@ class NsxPolicyLib(lib.NsxLibBase):
return True return True
if feature == nsx_constants.FEATURE_NSX_POLICY_GLOBAL_CONFIG: if feature == nsx_constants.FEATURE_NSX_POLICY_GLOBAL_CONFIG:
return True return True
if feature == nsx_constants.FEATURE_NSX_POLICY_ADMIN_STATE:
return True
return (feature == nsx_constants.FEATURE_NSX_POLICY) return (feature == nsx_constants.FEATURE_NSX_POLICY)

View File

@ -824,9 +824,9 @@ class SegmentDef(BaseSegmentDef):
def _version_dependant_attr_supported(self, attr): def _version_dependant_attr_supported(self, attr):
if (version.LooseVersion(self.nsx_version) >= if (version.LooseVersion(self.nsx_version) >=
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)): version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
if attr == 'metadata_proxy_id': if attr in ('metadata_proxy_id',
return True 'dhcp_server_config_id',
if attr == 'dhcp_server_config_id': 'admin_state'):
return True return True
else: else:
LOG.warning( LOG.warning(
@ -889,6 +889,15 @@ class SegmentDef(BaseSegmentDef):
body_attr='dhcp_config_path', body_attr='dhcp_config_path',
value=path) value=path)
if (self.has_attr('admin_state') and
self._version_dependant_attr_supported('admin_state')):
if self.get_attr('admin_state'):
admin_state = nsx_constants.ADMIN_STATE_UP
else:
admin_state = nsx_constants.ADMIN_STATE_DOWN
self._set_attr_if_specified(body, 'admin_state',
value=admin_state)
return body return body
@ -939,6 +948,15 @@ class DhcpV6StaticBindingConfig(DhcpV4StaticBindingConfig):
'ip_addresses', 'ip_addresses',
'sntp_servers', 'sntp_servers',
'preferred_time']) 'preferred_time'])
if (self.has_attr('admin_state') and
self._version_dependant_attr_supported('admin_state')):
if self.get_attr('admin_state'):
admin_state = nsx_constants.ADMIN_STATE_UP
else:
admin_state = nsx_constants.ADMIN_STATE_DOWN
self._set_attr_if_specified(body, 'admin_state',
value=admin_state)
return body return body
@ -1003,8 +1021,40 @@ class SegmentPortDef(ResourceDef):
'allocate_addresses']) 'allocate_addresses'])
body['attachment'] = attachment body['attachment'] = attachment
if (self.has_attr('admin_state') and
self._version_dependant_attr_supported('admin_state')):
if self.get_attr('admin_state'):
admin_state = nsx_constants.ADMIN_STATE_UP
else:
admin_state = nsx_constants.ADMIN_STATE_DOWN
self._set_attr_if_specified(body, 'admin_state',
value=admin_state)
return body 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 == 'admin_state':
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 SegmentBindingMapDefBase(ResourceDef):
@property
def path_ids(self):
return ('tenant', 'segment_id', 'map_id')
def path_defs(self):
return (TenantDef, SegmentDef)
class SegmentPortBindingMapDefBase(ResourceDef): class SegmentPortBindingMapDefBase(ResourceDef):

View File

@ -15,6 +15,7 @@
# #
import abc import abc
from distutils import version
import sys import sys
import decorator import decorator
@ -1812,6 +1813,7 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
transport_zone_id=IGNORE, transport_zone_id=IGNORE,
metadata_proxy_id=IGNORE, metadata_proxy_id=IGNORE,
dhcp_server_config_id=IGNORE, dhcp_server_config_id=IGNORE,
admin_state=IGNORE,
tags=IGNORE, tags=IGNORE,
tenant=constants.POLICY_INFRA_TENANT): tenant=constants.POLICY_INFRA_TENANT):
@ -1834,6 +1836,7 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
transport_zone_id=transport_zone_id, transport_zone_id=transport_zone_id,
metadata_proxy_id=metadata_proxy_id, metadata_proxy_id=metadata_proxy_id,
dhcp_server_config_id=dhcp_server_config_id, dhcp_server_config_id=dhcp_server_config_id,
admin_state=admin_state,
tags=tags, tags=tags,
tenant=tenant) tenant=tenant)
self._create_or_store(segment_def) self._create_or_store(segment_def)
@ -1864,9 +1867,9 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
def update(self, segment_id, name=IGNORE, description=IGNORE, def update(self, segment_id, name=IGNORE, description=IGNORE,
tier1_id=IGNORE, subnets=IGNORE, tier1_id=IGNORE, subnets=IGNORE,
dns_domain_name=IGNORE, dns_domain_name=IGNORE,
vlan_ids=IGNORE, tags=IGNORE, metadata_proxy_id=IGNORE, vlan_ids=IGNORE, metadata_proxy_id=IGNORE,
dhcp_server_config_id=IGNORE, dhcp_server_config_id=IGNORE, admin_state=IGNORE,
tenant=constants.POLICY_INFRA_TENANT): tags=IGNORE, tenant=constants.POLICY_INFRA_TENANT):
if (metadata_proxy_id != IGNORE and if (metadata_proxy_id != IGNORE and
not self.nsxpolicy.feature_supported( not self.nsxpolicy.feature_supported(
@ -1883,6 +1886,7 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
vlan_ids=vlan_ids, vlan_ids=vlan_ids,
metadata_proxy_id=metadata_proxy_id, metadata_proxy_id=metadata_proxy_id,
dhcp_server_config_id=dhcp_server_config_id, dhcp_server_config_id=dhcp_server_config_id,
admin_state=admin_state,
tags=tags, tags=tags,
tenant=tenant) tenant=tenant)
@ -1953,7 +1957,12 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
@check_allowed_passthrough @check_allowed_passthrough
def set_admin_state(self, segment_id, admin_state, def set_admin_state(self, segment_id, admin_state,
tenant=constants.POLICY_INFRA_TENANT): tenant=constants.POLICY_INFRA_TENANT):
"""Set the segment admin state using the passthrough api""" """Set the segment admin state using the passthrough/policy api"""
if (version.LooseVersion(self.version) >=
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
return self.update(segment_id, admin_state=admin_state,
tenant=tenant)
realization_info = self.wait_until_realized( realization_info = self.wait_until_realized(
segment_id, entity_type='RealizedLogicalSwitch', tenant=tenant) segment_id, entity_type='RealizedLogicalSwitch', tenant=tenant)
@ -1994,6 +2003,7 @@ class NsxPolicySegmentPortApi(NsxPolicyResourceBase):
context_id=IGNORE, context_id=IGNORE,
traffic_tag=IGNORE, traffic_tag=IGNORE,
allocate_addresses=IGNORE, allocate_addresses=IGNORE,
admin_state=IGNORE,
tags=IGNORE, tags=IGNORE,
tenant=constants.POLICY_INFRA_TENANT): tenant=constants.POLICY_INFRA_TENANT):
@ -2009,6 +2019,7 @@ class NsxPolicySegmentPortApi(NsxPolicyResourceBase):
context_id=context_id, context_id=context_id,
traffic_tag=traffic_tag, traffic_tag=traffic_tag,
allocate_addresses=allocate_addresses, allocate_addresses=allocate_addresses,
admin_state=admin_state,
tags=tags, tags=tags,
tenant=tenant) tenant=tenant)
self._create_or_store(port_def) self._create_or_store(port_def)
@ -2037,6 +2048,7 @@ class NsxPolicySegmentPortApi(NsxPolicyResourceBase):
name=IGNORE, name=IGNORE,
description=IGNORE, description=IGNORE,
address_bindings=IGNORE, address_bindings=IGNORE,
admin_state=IGNORE,
tags=IGNORE, tags=IGNORE,
tenant=constants.POLICY_INFRA_TENANT): tenant=constants.POLICY_INFRA_TENANT):
@ -2045,6 +2057,7 @@ class NsxPolicySegmentPortApi(NsxPolicyResourceBase):
name=name, name=name,
description=description, description=description,
address_bindings=address_bindings, address_bindings=address_bindings,
admin_state=admin_state,
tags=tags, tags=tags,
tenant=tenant) tenant=tenant)
@ -2119,7 +2132,12 @@ class NsxPolicySegmentPortApi(NsxPolicyResourceBase):
@check_allowed_passthrough @check_allowed_passthrough
def set_admin_state(self, segment_id, port_id, admin_state, def set_admin_state(self, segment_id, port_id, admin_state,
tenant=constants.POLICY_INFRA_TENANT): tenant=constants.POLICY_INFRA_TENANT):
"""Set the segment port admin state using the passthrough api""" """Set the segment port admin state using the passthrough/policy api"""
if (version.LooseVersion(self.version) >=
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
return self.update(segment_id, port_id, admin_state=admin_state,
tenant=tenant)
realization_info = self.wait_until_realized( realization_info = self.wait_until_realized(
segment_id, port_id, entity_type='RealizedLogicalPort', segment_id, port_id, entity_type='RealizedLogicalPort',
tenant=tenant) tenant=tenant)