Add support for provider network options

This has been asked for by the Ansible community.

Change-Id: Ib11beb42901cdf6b5c9a5d8f8e3a2a0f2fbf382d
This commit is contained in:
David Shrewsbury 2016-02-15 16:38:12 -05:00
parent ef263d6a23
commit 11a8527558
4 changed files with 86 additions and 3 deletions

View File

@ -0,0 +1,3 @@
---
features:
- Network provider options are now accepted in create_network().

View File

@ -1634,16 +1634,17 @@ class OpenStackCloud(object):
"Unable to delete keypair %s: %s" % (name, e)) "Unable to delete keypair %s: %s" % (name, e))
return True return True
# TODO(Shrews): This will eventually need to support tenant ID and
# provider networks, which are admin-level params.
def create_network(self, name, shared=False, admin_state_up=True, def create_network(self, name, shared=False, admin_state_up=True,
external=False): external=False, provider=None):
"""Create a network. """Create a network.
:param string name: Name of the network being created. :param string name: Name of the network being created.
:param bool shared: Set the network as shared. :param bool shared: Set the network as shared.
:param bool admin_state_up: Set the network administrative state to up. :param bool admin_state_up: Set the network administrative state to up.
:param bool external: Whether this network is externally accessible. :param bool external: Whether this network is externally accessible.
:param dict provider: A dict of network provider options. Example::
{ 'network_type': 'vlan', 'segmentation_id': 'vlan1' }
:returns: The network object. :returns: The network object.
:raises: OpenStackCloudException on operation error. :raises: OpenStackCloudException on operation error.
@ -1655,6 +1656,17 @@ class OpenStackCloud(object):
'admin_state_up': admin_state_up, 'admin_state_up': admin_state_up,
} }
if provider:
if not isinstance(provider, dict):
raise OpenStackCloudException(
"Parameter 'provider' must be a dict")
# Only pass what we know
for attr in ('physical_network', 'network_type',
'segmentation_id'):
if attr in provider:
arg = "provider:" + attr
network[arg] = provider[attr]
# Do not send 'router:external' unless it is explicitly # Do not send 'router:external' unless it is explicitly
# set since sending it *might* cause "Forbidden" errors in # set since sending it *might* cause "Forbidden" errors in
# some situations. It defaults to False in the client, anyway. # some situations. It defaults to False in the client, anyway.

View File

@ -67,6 +67,21 @@ class TestNetwork(base.TestCase):
self.assertTrue(net1['shared']) self.assertTrue(net1['shared'])
self.assertFalse(net1['admin_state_up']) self.assertFalse(net1['admin_state_up'])
def test_create_network_provider_flat(self):
net1 = self.cloud.create_network(
name=self.network_name,
shared=True,
provider={
'physical_network': 'private',
'network_type': 'flat',
}
)
self.assertIn('id', net1)
self.assertEqual(self.network_name, net1['name'])
self.assertEqual('flat', net1['provider:network_type'])
self.assertEqual('private', net1['provider:physical_network'])
self.assertIsNone(net1['provider:segmentation_id'])
def test_list_networks_filtered(self): def test_list_networks_filtered(self):
net1 = self.cloud.create_network(name=self.network_name) net1 = self.cloud.create_network(name=self.network_name)
self.assertIsNotNone(net1) self.assertIsNotNone(net1)

View File

@ -50,6 +50,59 @@ class TestNetwork(base.TestCase):
) )
) )
@mock.patch.object(shade.OpenStackCloud, 'neutron_client')
def test_create_network_provider(self, mock_neutron):
provider_opts = {'physical_network': 'mynet',
'network_type': 'vlan',
'segmentation_id': 'vlan1'}
self.cloud.create_network("netname", provider=provider_opts)
mock_neutron.create_network.assert_called_once_with(
body=dict(
network={
'name': 'netname',
'shared': False,
'admin_state_up': True,
'provider:physical_network':
provider_opts['physical_network'],
'provider:network_type':
provider_opts['network_type'],
'provider:segmentation_id':
provider_opts['segmentation_id'],
}
)
)
@mock.patch.object(shade.OpenStackCloud, 'neutron_client')
def test_create_network_provider_ignored_value(self, mock_neutron):
provider_opts = {'physical_network': 'mynet',
'network_type': 'vlan',
'segmentation_id': 'vlan1',
'should_not_be_passed': 1}
self.cloud.create_network("netname", provider=provider_opts)
mock_neutron.create_network.assert_called_once_with(
body=dict(
network={
'name': 'netname',
'shared': False,
'admin_state_up': True,
'provider:physical_network':
provider_opts['physical_network'],
'provider:network_type':
provider_opts['network_type'],
'provider:segmentation_id':
provider_opts['segmentation_id'],
}
)
)
def test_create_network_provider_wrong_type(self):
provider_opts = "invalid"
with testtools.ExpectedException(
shade.OpenStackCloudException,
"Parameter 'provider' must be a dict"
):
self.cloud.create_network("netname", provider=provider_opts)
@mock.patch.object(shade.OpenStackCloud, 'get_network') @mock.patch.object(shade.OpenStackCloud, 'get_network')
@mock.patch.object(shade.OpenStackCloud, 'neutron_client') @mock.patch.object(shade.OpenStackCloud, 'neutron_client')
def test_delete_network(self, mock_neutron, mock_get): def test_delete_network(self, mock_neutron, mock_get):