Merge "NSX|V3: create dhcp profile at boot time"
This commit is contained in:
commit
f85feb5650
@ -114,7 +114,6 @@ function neutron_plugin_configure_service {
|
||||
_nsxv3_ini_set insecure $NSX_INSECURE
|
||||
_nsxv3_ini_set ca_file $NSX_CA_FILE
|
||||
_nsxv3_ini_set default_bridge_cluster_uuid $DEFAULT_BRIDGE_CLUSTER_UUID
|
||||
_nsxv3_ini_set default_switching_profile_dhcp_uuid $DEFAULT_SWITCHING_PROFILE_DHCP_UUID
|
||||
}
|
||||
|
||||
function neutron_plugin_setup_interface_driver {
|
||||
|
@ -346,12 +346,3 @@
|
||||
# L2 gateway APIs.
|
||||
# This field must be specified on one of the active neutron servers only.
|
||||
# default_bridge_cluster_uuid =
|
||||
|
||||
# UUID of the default NSX switching profile to allow DHCP traffic. This will be
|
||||
# applied on the DHCP ports, if neutron's DHCP service is enabled.
|
||||
# In order to create the DHCP switching profile, go the NSX manager and perform
|
||||
# the following steps:
|
||||
# Create a new Switching Profile of type 'Switch Security'.
|
||||
# Disable DHCP Client Block and DHCP Server Block options for this profile.
|
||||
# Save the profile and copy the Switching Profile's UUID below.
|
||||
# default_switching_profile_dhcp_uuid =
|
||||
|
@ -207,12 +207,6 @@ nsx_v3_opts = [
|
||||
'"ca_file" is set.')),
|
||||
cfg.StrOpt('default_tier0_router_uuid',
|
||||
help=_("Default tier0 router identifier")),
|
||||
cfg.StrOpt('default_switching_profile_dhcp_uuid',
|
||||
help=_("UUID of the default NSX switching profile to allow "
|
||||
"DHCP traffic. This will be applied on the DHCP ports, "
|
||||
"if neutron's DHCP service is enabled. This profile "
|
||||
"must be created on the backend, out of band, with DHCP "
|
||||
"Server/Client Block disabled.")),
|
||||
]
|
||||
|
||||
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
||||
|
@ -170,7 +170,7 @@ class JSONRESTClient(RESTClient):
|
||||
|
||||
def _rest_call(self, *args, **kwargs):
|
||||
if kwargs.get('body') is not None:
|
||||
kwargs['body'] = jsonutils.dumps(kwargs['body'])
|
||||
kwargs['body'] = jsonutils.dumps(kwargs['body'], sort_keys=True)
|
||||
result = super(JSONRESTClient, self)._rest_call(*args, **kwargs)
|
||||
return result.json() if result.content else result
|
||||
|
||||
|
@ -122,6 +122,30 @@ class SwitchingProfile(AbstractRESTResource):
|
||||
white_list_providers=whitelist_providers,
|
||||
tags=tags or [])
|
||||
|
||||
def create_dhcp_profile(self, display_name,
|
||||
description, tags=None):
|
||||
dhcp_filter = {
|
||||
'client_block_enabled': False,
|
||||
'server_block_enabled': False
|
||||
}
|
||||
rate_limits = {
|
||||
'rx_broadcast': 0,
|
||||
'tx_broadcast': 0,
|
||||
'rx_multicast': 0,
|
||||
'tx_multicast': 0
|
||||
}
|
||||
bpdu_filter = {
|
||||
'enabled': False,
|
||||
'white_list': []
|
||||
}
|
||||
return self.create(SwitchingProfileTypes.SWITCH_SECURITY,
|
||||
display_name=display_name,
|
||||
description=description,
|
||||
tags=tags or [],
|
||||
dhcp_filter=dhcp_filter,
|
||||
rate_limits=rate_limits,
|
||||
bpdu_filter=bpdu_filter)
|
||||
|
||||
@classmethod
|
||||
def build_switch_profile_ids(cls, client, *profiles):
|
||||
ids = []
|
||||
|
@ -73,6 +73,7 @@ from vmware_nsx.nsxlib.v3 import security
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
NSX_V3_PSEC_PROFILE_NAME = 'neutron_port_spoof_guard_profile'
|
||||
NSX_V3_DHCP_PROFILE_NAME = 'neutron_port_dhcp_profile'
|
||||
|
||||
|
||||
class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
@ -133,11 +134,16 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
self._psec_profile = None
|
||||
self._psec_profile = self._init_port_security_profile()
|
||||
if not self._psec_profile:
|
||||
msg = (_("Unable to initialize NSX v3 port spoofguard "
|
||||
"switching profile: %s") % NSX_V3_PSEC_PROFILE_NAME)
|
||||
msg = _("Unable to initialize NSX v3 port spoofguard "
|
||||
"switching profile: %s") % NSX_V3_PSEC_PROFILE_NAME
|
||||
raise nsx_exc.NsxPluginException(msg)
|
||||
LOG.debug("Initializing NSX v3 DHCP switching profile")
|
||||
self._dhcp_profile = None
|
||||
self._dhcp_profile = self._init_dhcp_switching_profile()
|
||||
if not self._dhcp_profile:
|
||||
msg = _("Unable to initialize NSX v3 DHCP "
|
||||
"switching profile: %s") % NSX_V3_DHCP_PROFILE_NAME
|
||||
raise nsx_exc.NsxPluginException(msg)
|
||||
self._unsubscribe_callback_events()
|
||||
|
||||
def _unsubscribe_callback_events(self):
|
||||
@ -165,22 +171,27 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
"must be disabled") % dhcp_profile_uuid
|
||||
raise n_exc.InvalidInput(error_message=msg)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(Exception)
|
||||
def _init_dhcp_switching_profile(self):
|
||||
dhcp_profile_uuid = cfg.CONF.nsx_v3.default_switching_profile_dhcp_uuid
|
||||
if not dhcp_profile_uuid:
|
||||
LOG.warning(_LW("Switching profile for DHCP ports not configured "
|
||||
"in the config file."))
|
||||
return
|
||||
if not uuidutils.is_uuid_like(dhcp_profile_uuid):
|
||||
LOG.warning(_LW("default_switching_profile_dhcp_uuid: %s. DHCP "
|
||||
"profile must be configured with a UUID"),
|
||||
dhcp_profile_uuid)
|
||||
return
|
||||
self._validate_dhcp_profile(dhcp_profile_uuid)
|
||||
with locking.LockManager.get_lock('nsxv3_dhcp_profile_init'):
|
||||
profile = self._get_dhcp_security_profile()
|
||||
if not profile:
|
||||
self._switching_profiles.create_dhcp_profile(
|
||||
NSX_V3_DHCP_PROFILE_NAME, 'Neutron DHCP Security Profile',
|
||||
tags=utils.build_v3_tags_payload({
|
||||
'id': NSX_V3_DHCP_PROFILE_NAME,
|
||||
'tenant_id': 'neutron-nsx-plugin'}))
|
||||
return self._get_dhcp_security_profile()
|
||||
|
||||
def _get_dhcp_security_profile(self):
|
||||
if self._dhcp_profile:
|
||||
return self._dhcp_profile
|
||||
profile = self._switching_profiles.find_by_display_name(
|
||||
NSX_V3_DHCP_PROFILE_NAME)
|
||||
return nsx_resources.SwitchingProfileTypeId(
|
||||
profile_type=(nsx_resources.SwitchingProfileTypes.
|
||||
SWITCH_SECURITY),
|
||||
profile_id=dhcp_profile_uuid)
|
||||
profile_id=profile[0]['id']) if profile else None
|
||||
|
||||
def _get_port_security_profile_id(self):
|
||||
return nsx_resources.SwitchingProfile.build_switch_profile_ids(
|
||||
|
@ -12,7 +12,6 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import mock
|
||||
import six
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
@ -41,7 +40,6 @@ from oslo_utils import uuidutils
|
||||
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import client as nsx_client
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin
|
||||
from vmware_nsx.tests import unit as vmware
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
|
||||
@ -80,11 +78,6 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
|
||||
if getattr(self.plugin, '_port_client', None):
|
||||
self.plugin._port_client._client._session = self.mock_api
|
||||
|
||||
mocked_locking = mock.patch.object(
|
||||
nsx_plugin, 'locking', new=mock.Mock())
|
||||
mocked_locking.start()
|
||||
self._patchers.append(mocked_locking)
|
||||
|
||||
self.maxDiff = None
|
||||
|
||||
def tearDown(self):
|
||||
@ -354,54 +347,3 @@ class TestNsxV3Utils(NsxV3PluginTestCaseMixin):
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
|
||||
class TestNsxV3DHCPSwitchingProfile(TestPortsV2):
|
||||
|
||||
def setUp(self, plugin=PLUGIN_NAME,
|
||||
ext_mgr=None,
|
||||
service_plugins=None):
|
||||
super(TestNsxV3DHCPSwitchingProfile, self).setUp(plugin=plugin,
|
||||
ext_mgr=ext_mgr)
|
||||
dhcp_profile_uuid = uuidutils.generate_uuid()
|
||||
cfg.CONF.set_override('default_switching_profile_dhcp_uuid',
|
||||
dhcp_profile_uuid, 'nsx_v3')
|
||||
self.plugin._dhcp_profile = nsx_resources.SwitchingProfileTypeId(
|
||||
profile_type=(nsx_resources.SwitchingProfileTypes.
|
||||
SWITCH_SECURITY),
|
||||
profile_id=dhcp_profile_uuid)
|
||||
|
||||
def test_create_port_dhcp_profile(self):
|
||||
with mock.patch.object(self.plugin._port_client,
|
||||
'create') as port_create:
|
||||
with self.network() as network:
|
||||
with self.subnet(network=network):
|
||||
data = {'port': {'network_id': network['network']['id'],
|
||||
'tenant_id':
|
||||
network['network']['tenant_id'],
|
||||
'name': 'port1',
|
||||
'admin_state_up': True,
|
||||
'device_owner':
|
||||
constants.DEVICE_OWNER_DHCP}}
|
||||
port_req = self.new_create_request('ports', data)
|
||||
port_req.get_response(self.api)
|
||||
args, kwargs = port_create.call_args
|
||||
self.assertEqual(kwargs['switch_profile_ids'],
|
||||
[self.plugin._dhcp_profile])
|
||||
|
||||
def test_create_non_dhcp_port_with_dhcp_profile(self):
|
||||
with mock.patch.object(self.plugin._port_client,
|
||||
'create') as port_create:
|
||||
with self.network() as network:
|
||||
with self.subnet(network=network):
|
||||
data = {'port': {'network_id': network['network']['id'],
|
||||
'tenant_id':
|
||||
network['network']['tenant_id'],
|
||||
'name': 'port1',
|
||||
'admin_state_up': True,
|
||||
'device_owner': 'not-dhcp'}}
|
||||
port_req = self.new_create_request('ports', data)
|
||||
port_req.get_response(self.api)
|
||||
args, kwargs = port_create.call_args
|
||||
self.assertNotEqual(kwargs['switch_profile_ids'],
|
||||
[self.plugin._dhcp_profile])
|
||||
|
@ -58,7 +58,8 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/switching-profiles',
|
||||
False,
|
||||
jsonutils.dumps(self._body(qos_marking='UNTRUSTED', dscp=25)),
|
||||
jsonutils.dumps(self._body(qos_marking='UNTRUSTED', dscp=25),
|
||||
sort_keys=True),
|
||||
_JSON_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -77,7 +78,8 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/switching-profiles',
|
||||
False,
|
||||
jsonutils.dumps(self._body(qos_marking='trusted', dscp=0)),
|
||||
jsonutils.dumps(self._body(qos_marking='trusted', dscp=0),
|
||||
sort_keys=True),
|
||||
_JSON_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
|
@ -44,7 +44,7 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'resource_type': profile_types.PORT_MIRRORING,
|
||||
'display_name': 'pm-profile',
|
||||
'description': 'port mirror prof'
|
||||
}),
|
||||
}, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -71,7 +71,7 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
False, jsonutils.dumps({
|
||||
'resource_type': profile_types.PORT_MIRRORING,
|
||||
'tags': tags
|
||||
}),
|
||||
}, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -104,7 +104,53 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'description': 'spoofguard-for-neutron',
|
||||
'white_list_providers': ['LPORT_BINDINGS'],
|
||||
'tags': tags
|
||||
}),
|
||||
}, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
def test_create_dhcp_profile(self):
|
||||
|
||||
tags = [
|
||||
{
|
||||
'scope': 'os-tid',
|
||||
'tag': 'tenant-1'
|
||||
},
|
||||
{
|
||||
'scope': 'os-api-version',
|
||||
'tag': '2.1.1.0'
|
||||
}
|
||||
]
|
||||
|
||||
api = resources.SwitchingProfile(client.NSX3Client())
|
||||
with self.mocked_resource(api) as mocked:
|
||||
api.create_dhcp_profile(
|
||||
'neutron-dhcp', 'dhcp-for-neutron',
|
||||
tags=tags)
|
||||
|
||||
test_client.assert_session_call(
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/switching-profiles',
|
||||
False,
|
||||
jsonutils.dumps({
|
||||
'bpdu_filter': {
|
||||
'enabled': False,
|
||||
'white_list': []
|
||||
},
|
||||
'resource_type': profile_types.SWITCH_SECURITY,
|
||||
'display_name': 'neutron-dhcp',
|
||||
'description': 'dhcp-for-neutron',
|
||||
'tags': tags,
|
||||
'dhcp_filter': {
|
||||
'client_block_enabled': False,
|
||||
'server_block_enabled': False
|
||||
},
|
||||
'rate_limits': {
|
||||
'rx_broadcast': 0,
|
||||
'tx_broadcast': 0,
|
||||
'rx_multicast': 0,
|
||||
'tx_multicast': 0
|
||||
}
|
||||
}, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -200,7 +246,7 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/logical-ports',
|
||||
False,
|
||||
jsonutils.dumps(resp_body),
|
||||
jsonutils.dumps(resp_body, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -271,7 +317,7 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/logical-routers',
|
||||
False,
|
||||
jsonutils.dumps(data),
|
||||
jsonutils.dumps(data, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -325,7 +371,7 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/logical-router-ports',
|
||||
False,
|
||||
jsonutils.dumps(data),
|
||||
jsonutils.dumps(data, sort_keys=True),
|
||||
client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
|
@ -53,7 +53,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
test_client.assert_session_call(
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/logical-switches',
|
||||
False, jsonutils.dumps(self._create_body()),
|
||||
False, jsonutils.dumps(self._create_body(), sort_keys=True),
|
||||
nsxlib.client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -71,7 +71,8 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'https://1.2.3.4/api/v1/logical-switches',
|
||||
False,
|
||||
jsonutils.dumps(self._create_body(
|
||||
admin_state=nsx_constants.ADMIN_STATE_DOWN)),
|
||||
admin_state=nsx_constants.ADMIN_STATE_DOWN),
|
||||
sort_keys=True),
|
||||
nsxlib.client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
@ -87,7 +88,8 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
test_client.assert_session_call(
|
||||
mocked.get('post'),
|
||||
'https://1.2.3.4/api/v1/logical-switches',
|
||||
False, jsonutils.dumps(self._create_body(vlan_id='123')),
|
||||
False, jsonutils.dumps(self._create_body(vlan_id='123'),
|
||||
sort_keys=True),
|
||||
nsxlib.client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
nsxlib_testcase.NSX_CERT)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user