Merge "Provide dry-run flag to validate deployment requirements"

This commit is contained in:
Jenkins 2016-03-01 15:23:08 +00:00 committed by Gerrit Code Review
commit 5ce21793b4
2 changed files with 54 additions and 2 deletions

View File

@ -39,6 +39,7 @@ from neutron.services.auto_allocate import models
LOG = logging.getLogger(__name__)
IS_DEFAULT = 'is_default'
CHECK_REQUIREMENTS = 'dry-run'
def _extend_external_network_default(self, net_res, net_db):
@ -91,6 +92,15 @@ class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin):
The topology will be provisioned upon return, if network is missing.
"""
if CHECK_REQUIREMENTS in fields:
# for dry-run requests, simply validates that subsequent
# requests can be fullfilled based on a set of requirements
# such as existence of default networks, pools, etc.
return self._check_requirements(context)
elif fields:
raise n_exc.BadRequest(resource='auto_allocate',
msg=_("Unrecognized field"))
tenant_id = self._validate(context, tenant_id)
# Check for an existent topology
network_id = self._get_auto_allocated_network(context, tenant_id)
@ -123,6 +133,16 @@ class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin):
constants.L3_ROUTER_NAT)
return self._l3_plugin
def _check_requirements(self, context):
"""Raise if requirements are not met."""
self._get_default_external_network(context)
try:
self._get_supported_subnetpools(context)
except n_exc.NotFound:
raise exceptions.AutoAllocationFailure(
reason=_("No default subnetpools defined"))
return {'id': 'dry-run=pass'}
def _validate(self, context, tenant_id):
"""Validate and return the tenant to be associated to the topology."""
if tenant_id == 'None':

View File

@ -17,10 +17,10 @@ from neutron.common import exceptions as n_exc
from neutron import context
from neutron.services.auto_allocate import db
from neutron.services.auto_allocate import exceptions
from neutron.tests import base
from neutron.tests.unit import testlib_api
class AutoAllocateTestCase(base.BaseTestCase):
class AutoAllocateTestCase(testlib_api.SqlTestCaseLight):
def setUp(self):
super(AutoAllocateTestCase, self).setUp()
@ -46,3 +46,35 @@ class AutoAllocateTestCase(base.BaseTestCase):
mock_cleanup.assert_called_once_with(
self.ctx, network_id='network_foo',
router_id='router_foo', subnets=[])
def test_get_auto_allocated_topology_dry_run_happy_path_for_kevin(self):
with mock.patch.object(self.mixin, '_check_requirements') as f:
self.mixin.get_auto_allocated_topology(
self.ctx, mock.ANY, fields=['dry-run'])
self.assertEqual(1, f.call_count)
def test_get_auto_allocated_topology_dry_run_bad_input(self):
self.assertRaises(n_exc.BadRequest,
self.mixin.get_auto_allocated_topology,
self.ctx, mock.ANY, fields=['foo'])
def test__check_requirements_fail_on_missing_ext_net(self):
self.assertRaises(exceptions.AutoAllocationFailure,
self.mixin._check_requirements, self.ctx)
def test__check_requirements_fail_on_missing_pools(self):
with mock.patch.object(
self.mixin, '_get_default_external_network'),\
mock.patch.object(
self.mixin, '_get_supported_subnetpools') as g:
g.side_effect = n_exc.NotFound()
self.assertRaises(exceptions.AutoAllocationFailure,
self.mixin._check_requirements, self.ctx)
def test__check_requirements_happy_path_for_kevin(self):
with mock.patch.object(
self.mixin, '_get_default_external_network'),\
mock.patch.object(
self.mixin, '_get_supported_subnetpools'):
result = self.mixin._check_requirements(self.ctx)
self.assertEqual(list(result.values())[0], 'dry-run=pass')