Merge "Handle invalid setting of public network"

This commit is contained in:
Jenkins 2015-04-22 10:40:24 +00:00 committed by Gerrit Code Review
commit a0b412ca70
5 changed files with 81 additions and 24 deletions

View File

@ -27,10 +27,7 @@ from ec2api.db import api as db_api
from ec2api import exception
from ec2api.i18n import _
CONF = cfg.CONF
CONF.import_opt('external_network', 'ec2api.api.internet_gateway')
"""Address related API implementation
"""
@ -213,11 +210,8 @@ class AddressEngineNeutron(object):
def allocate_address(self, context, domain=None):
if not domain or domain == 'standard':
return AddressEngineNova().allocate_address(context)
os_public_network = ec2utils.get_os_public_network(context)
neutron = clients.neutron(context)
# TODO(ft): check no public network exists
search_opts = {'router:external': True, 'name': CONF.external_network}
os_networks = neutron.list_networks(**search_opts)['networks']
os_public_network = os_networks[0]
with common.OnCrashCleaner() as cleaner:
os_floating_ip = {'floating_network_id': os_public_network['id']}

View File

@ -15,16 +15,26 @@
import re
from glanceclient.common import exceptions as glance_exception
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import timeutils
from ec2api.api import clients
from ec2api.db import api as db_api
from ec2api import exception
from ec2api.i18n import _
from ec2api.i18n import _, _LE
LOG = logging.getLogger(__name__)
ec2_opts = [
cfg.StrOpt('external_network',
default=None,
help='Name of the external network, which is used to connect'
'VPCs to Internet and to allocate Elastic IPs.'),
]
CONF = cfg.CONF
CONF.register_opts(ec2_opts)
_c2u = re.compile('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
@ -311,3 +321,25 @@ def get_os_image(context, ec2_image_id):
return glance.images.get(image['os_id'])
except glance_exception.HTTPNotFound:
raise exception.InvalidAMIIDNotFound(id=ec2_image_id)
def get_os_public_network(context):
neutron = clients.neutron(context)
search_opts = {'router:external': True, 'name': CONF.external_network}
os_networks = neutron.list_networks(**search_opts)['networks']
if len(os_networks) != 1:
if CONF.external_network:
if len(os_networks) == 0:
msg = _LE("No external network with name '%s' is found")
else:
msg = _LE("More than one external network with name '%s' "
"is found")
LOG.error(msg, CONF.external_network)
else:
if len(os_networks) == 0:
msg = _LE('No external network is found')
else:
msg = _LE('More than one external network is found')
LOG.error(msg)
raise exception.Unsupported(_('Feature is restricted by OS admin'))
return os_networks[0]

View File

@ -19,7 +19,6 @@ datastore.
"""
from neutronclient.common import exceptions as neutron_exception
from oslo_config import cfg
from oslo_log import log as logging
from ec2api.api import clients
@ -29,19 +28,8 @@ from ec2api.db import api as db_api
from ec2api import exception
from ec2api.i18n import _
LOG = logging.getLogger(__name__)
ec2_opts = [
cfg.StrOpt('external_network',
default=None,
help='Name of the external network, which is used to connect'
'VPCs to Internet and to allocate Elastic IPs'),
]
CONF = cfg.CONF
CONF.register_opts(ec2_opts)
"""Internet gateway related API implementation
"""
@ -70,11 +58,8 @@ def attach_internet_gateway(context, internet_gateway_id, vpc_id):
"attached") % {'vpc_id': vpc['id']}
raise exception.InvalidParameterValue(msg)
os_public_network = ec2utils.get_os_public_network(context)
neutron = clients.neutron(context)
# TODO(ft): check no public network exists
search_opts = {'router:external': True, 'name': CONF.external_network}
os_networks = neutron.list_networks(**search_opts)['networks']
os_public_network = os_networks[0]
# TODO(ft): set attaching state into db
with common.OnCrashCleaner() as cleaner:

View File

@ -78,6 +78,9 @@ class AddressTestCase(base.ApiTestCase):
def test_allocate_address_overlimit(self):
address.address_engine = (
address.AddressEngineNeutron())
self.configure(external_network=fakes.NAME_OS_PUBLIC_NETWORK)
self.neutron.list_networks.return_value = (
{'networks': [{'id': fakes.ID_OS_PUBLIC_NETWORK}]})
self.neutron.create_floatingip.side_effect = (
neutron_exception.OverQuotaClient())
self.assert_execution_error('AddressLimitExceeded', 'AllocateAddress',

View File

@ -13,8 +13,10 @@
# limitations under the License.
import fixtures
from glanceclient.common import exceptions as glance_exception
import mock
from oslo_config import fixture as config_fixture
import testtools
from ec2api.api import ec2utils
@ -265,3 +267,44 @@ class EC2UtilsTestCase(testtools.TestCase):
exception.InvalidAMIIDNotFound,
ec2utils.get_os_image,
fake_context, fakes.random_ec2_id('ami'))
@mock.patch('neutronclient.v2_0.client.Client')
def test_get_os_public_network(self, neutron):
neutron = neutron.return_value
context = mock.Mock(service_catalog=[{'type': 'fake'}])
conf = self.useFixture(config_fixture.Config())
conf.config(external_network='fake_public_network')
neutron.list_networks.return_value = {'networks': ['network_object']}
net = ec2utils.get_os_public_network(context)
self.assertEqual('network_object', net)
neutron.list_networks.assert_called_once_with(
**{'router:external': True, 'name': 'fake_public_network'})
neutron.list_networks.return_value = {'networks': []}
with fixtures.FakeLogger() as log:
self.assertRaises(exception.Unsupported,
ec2utils.get_os_public_network, context)
self.assertNotEqual(0, len(log.output))
self.assertIn('fake_public_network', log.output)
neutron.list_networks.return_value = {'networks': ['obj1', 'obj2']}
with fixtures.FakeLogger() as log:
self.assertRaises(exception.Unsupported,
ec2utils.get_os_public_network, context)
self.assertNotEqual(0, len(log.output))
self.assertIn('fake_public_network', log.output)
conf.config(external_network=None)
with fixtures.FakeLogger() as log:
self.assertRaises(exception.Unsupported,
ec2utils.get_os_public_network, context)
self.assertNotEqual(0, len(log.output))
self.assertNotIn('None', log.output)
neutron.list_networks.return_value = {'networks': []}
with fixtures.FakeLogger() as log:
self.assertRaises(exception.Unsupported,
ec2utils.get_os_public_network, context)
self.assertNotEqual(0, len(log.output))
self.assertNotIn('None', log.output)