Add DHPC relay service to router port

Create/update a router port with a DHCP service UUID
This will be supported only if the nsx version is 2.0.0
or above.

Change-Id: I0843fd91e1631bec80ec19e9fa1edcc013523c28
This commit is contained in:
Adit Sarfaty 2017-07-09 17:24:35 +03:00
parent 4686b560e1
commit 05a0f019e0
6 changed files with 102 additions and 17 deletions

View File

@ -18,6 +18,7 @@ import copy
import mock
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
from vmware_nsxlib.tests.unit.v3 import mocks
from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase
@ -603,26 +604,32 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
returns the correct response and 201 status
"""
fake_router_port = test_constants.FAKE_ROUTER_PORT.copy()
fake_relay_uuid = uuidutils.generate_uuid()
lrport = self._mocked_lrport()
lrport.create(fake_router_port['logical_router_id'],
fake_router_port['display_name'],
None,
fake_router_port['resource_type'],
None, None, None)
data = {
'display_name': fake_router_port['display_name'],
'logical_router_id': fake_router_port['logical_router_id'],
'resource_type': fake_router_port['resource_type'],
'tags': []
'tags': [],
'service_bindings': [{'service_id': {
'target_type': 'LogicalService',
'target_id': fake_relay_uuid}}]
}
test_client.assert_json_call(
'post', lrport,
'https://1.2.3.4/api/v1/logical-router-ports',
data=jsonutils.dumps(data, sort_keys=True))
with mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.0.0'):
lrport.create(fake_router_port['logical_router_id'],
fake_router_port['display_name'],
None,
fake_router_port['resource_type'],
None, None, None,
relay_service_uuid=fake_relay_uuid)
test_client.assert_json_call(
'post', lrport,
'https://1.2.3.4/api/v1/logical-router-ports',
data=jsonutils.dumps(data, sort_keys=True))
def test_logical_router_port_max_attempts(self):
"""Test a router port api has the configured retries."""
@ -641,6 +648,32 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
'delete', lrport,
'https://1.2.3.4/api/v1/logical-router-ports/%s' % uuid)
def test_update_logical_router_port(self):
fake_router_port = test_constants.FAKE_ROUTER_PORT.copy()
uuid = fake_router_port['id']
fake_relay_uuid = uuidutils.generate_uuid()
lrport = self._mocked_lrport()
with mock.patch.object(lrport, 'get', return_value=fake_router_port),\
mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.0.0'):
lrport.update(uuid,
relay_service_uuid=fake_relay_uuid)
data = {
'id': uuid,
'display_name': fake_router_port['display_name'],
'logical_router_id': fake_router_port['logical_router_id'],
'resource_type': fake_router_port['resource_type'],
"revision": 0,
'service_bindings': [{'service_id': {
'target_type': 'LogicalService',
'target_id': fake_relay_uuid}}]
}
test_client.assert_json_call(
'put', lrport,
'https://1.2.3.4/api/v1/logical-router-ports/%s' % uuid,
data=jsonutils.dumps(data, sort_keys=True))
def test_get_logical_router_port_by_router_id(self):
"""Test getting a router port by router id."""
fake_router_port = test_constants.FAKE_ROUTER_PORT.copy()

View File

@ -177,6 +177,8 @@ class NsxLib(NsxLibBase):
self.client, self.nsxlib_config, nsxlib=self)
self.transport_zone = core_resources.NsxLibTransportZone(
self.client, self.nsxlib_config, nsxlib=self)
self.relay_service = core_resources.NsxLibDhcpRelayService(
self.client, self.nsxlib_config, nsxlib=self)
self.native_dhcp_profile = core_resources.NsxLibDhcpProfile(
self.client, self.nsxlib_config, nsxlib=self)
self.native_md_proxy = core_resources.NsxLibMetadataProxy(
@ -225,7 +227,8 @@ class NsxLib(NsxLibBase):
# when the actual version of NSX has been decided.
if (feature == nsx_constants.FEATURE_EXCLUDE_PORT_BY_TAG or
feature == nsx_constants.FEATURE_ROUTER_FIREWALL or
feature == nsx_constants.FEATURE_LOAD_BALANCER):
feature == nsx_constants.FEATURE_LOAD_BALANCER or
feature == nsx_constants.FEATURE_DHCP_RELAY):
return True
if (version.LooseVersion(self.get_version()) >=

View File

@ -670,6 +670,17 @@ class NsxLibDhcpProfile(utils.NsxLibApiBase):
return 'DhcpProfile'
class NsxLibDhcpRelayService(utils.NsxLibApiBase):
@property
def uri_segment(self):
return 'dhcp/relays'
@property
def resource_type(self):
return 'DhcpRelayService'
class NsxLibMetadataProxy(utils.NsxLibApiBase):
@property

View File

@ -129,4 +129,5 @@ FEATURE_DYNAMIC_CRITERIA = 'Dynamic criteria'
FEATURE_EXCLUDE_PORT_BY_TAG = 'Exclude Port by Tag'
FEATURE_ROUTER_FIREWALL = 'Router Firewall'
FEATURE_LOAD_BALANCER = 'Load Balancer'
FEATURE_DHCP_RELAY = 'DHCP Relay'
FEATURE_NSX_POLICY = 'NSX Policy'

View File

@ -253,6 +253,11 @@ class LogicalRouterPort(utils.NsxLibApiBase):
def uri_segment(self):
return 'logical-router-ports'
@staticmethod
def _get_relay_binding(relay_service_uuid):
return {'service_id': {'target_type': 'LogicalService',
'target_id': relay_service_uuid}}
def create(self, logical_router_id,
display_name,
tags,
@ -260,7 +265,8 @@ class LogicalRouterPort(utils.NsxLibApiBase):
logical_port_id,
address_groups,
edge_cluster_member_index=None,
urpf_mode=None):
urpf_mode=None,
relay_service_uuid=None):
body = {'display_name': display_name,
'resource_type': resource_type,
'logical_router_id': logical_router_id,
@ -280,6 +286,15 @@ class LogicalRouterPort(utils.NsxLibApiBase):
body['edge_cluster_member_index'] = edge_cluster_member_index
if urpf_mode:
body['urpf_mode'] = urpf_mode
if relay_service_uuid:
if (self.nsxlib and
self.nsxlib.feature_supported(
nsx_constants.FEATURE_DHCP_RELAY)):
body['service_bindings'] = [self._get_relay_binding(
relay_service_uuid)]
else:
LOG.error("Ignoring relay_service_uuid for router %s port: "
"This feature is not supported.", logical_router_id)
return self.client.create(self.get_path(), body=body)
@ -290,6 +305,25 @@ class LogicalRouterPort(utils.NsxLibApiBase):
max_attempts=self.client.max_attempts)
def _do_update():
logical_router_port = self.get(logical_port_id)
# special treatment for updating/removing the relay service
if 'relay_service_uuid' in kwargs:
if kwargs['relay_service_uuid']:
if (self.nsxlib and
self.nsxlib.feature_supported(
nsx_constants.FEATURE_DHCP_RELAY)):
logical_router_port['service_bindings'] = [
self._get_relay_binding(
kwargs['relay_service_uuid'])]
else:
LOG.error("Ignoring relay_service_uuid for router "
"port %s: This feature is not supported.",
logical_port_id)
else:
# delete the current one
if 'service_bindings' in logical_router_port:
logical_router_port['service_bindings'] = []
del kwargs['relay_service_uuid']
for k in kwargs:
logical_router_port[k] = kwargs[k]
# If revision_id of the payload that we send is older than what

View File

@ -169,7 +169,8 @@ class RouterLib(object):
ls_id,
logical_switch_port_id,
address_groups,
urpf_mode=None):
urpf_mode=None,
relay_service_uuid=None):
try:
port = self._router_port_client.get_by_lswitch_id(ls_id)
except exceptions.ResourceNotFound:
@ -180,10 +181,12 @@ class RouterLib(object):
nsx_constants.LROUTERPORT_DOWNLINK,
logical_switch_port_id,
address_groups,
urpf_mode=urpf_mode)
urpf_mode=urpf_mode,
relay_service_uuid=relay_service_uuid)
else:
return self._router_port_client.update(
port['id'], subnets=address_groups)
port['id'], subnets=address_groups,
relay_service_uuid=relay_service_uuid)
def add_fip_nat_rules(self, logical_router_id, ext_ip, int_ip,
match_ports=None, bypass_firewall=True):