Support v4-fixed-ip and v6-fixed-ip in create_server

novaclient supports v4-fixed-ip and v6-fixed-ip as aliases for fixed_ip.
As shade used to use novaclient and passed this content through the
switch to REST resulted in a behavior regression for shade users. That's
bad, mmkay?

Add in support for the same aliases to create_server, so that users
upgrading to newer shade are hosed.

Closes-Bug: #1798489
Change-Id: I55bc88e9b2cfa5ad1b6a27640db11bc848584c21
This commit is contained in:
Monty Taylor 2018-10-18 10:25:53 -05:00
parent 4ff38e65a4
commit 6f40858c05
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
3 changed files with 163 additions and 4 deletions

View File

@ -0,0 +1,7 @@
---
fixes:
- |
Re-added support for `v4-fixed-ip` and `v6-fixed-ip` in the `nics`
parameter to `create_server`. These are aliaes for `fixed_ip` provided
by novaclient which shade used to use. The switch to REST didn't include
support for these aliases, resulting in a behavior regression.

View File

@ -6928,13 +6928,19 @@ class OpenStackCloud(
"Requested network {net} could not be found.".format( "Requested network {net} could not be found.".format(
net=nic['net-name'])) net=nic['net-name']))
net['uuid'] = nic_net['id'] net['uuid'] = nic_net['id']
for ip_key in ('v4-fixed-ip', 'v6-fixed-ip', 'fixed_ip'):
fixed_ip = nic.pop(ip_key, None)
if fixed_ip and net.get('fixed_ip'):
raise exc.OpenStackCloudException(
"Only one of v4-fixed-ip, v6-fixed-ip or fixed_ip"
" may be given")
if fixed_ip:
net['fixed_ip'] = fixed_ip
# TODO(mordred) Add support for tag if server supports microversion # TODO(mordred) Add support for tag if server supports microversion
# 2.32-2.36 or >= 2.42 # 2.32-2.36 or >= 2.42
for key in ('port', 'fixed_ip'): for key in ('port', 'port-id'):
if key in nic: if key in nic:
net[key] = nic.pop(key) net['port'] = nic.pop(key)
if 'port-id' in nic:
net['port'] = nic.pop('port-id')
if nic: if nic:
raise exc.OpenStackCloudException( raise exc.OpenStackCloudException(
"Additional unsupported keys given for server network" "Additional unsupported keys given for server network"

View File

@ -631,6 +631,152 @@ class TestCreateServer(base.RequestsMockTestCase):
network='network-name', nics=[]) network='network-name', nics=[])
self.assert_calls() self.assert_calls()
def test_create_server_network_fixed_ip(self):
"""
Verify that if 'fixed_ip' is supplied in nics, we pass it to networks
appropriately.
"""
network = {
'id': 'network-id',
'name': 'network-name'
}
fixed_ip = '10.0.0.1'
build_server = fakes.make_fake_server('1234', '', 'BUILD')
self.register_uris([
dict(method='POST',
uri=self.get_mock_url(
'compute', 'public', append=['servers']),
json={'server': build_server},
validate=dict(
json={'server': {
u'flavorRef': u'flavor-id',
u'imageRef': u'image-id',
u'max_count': 1,
u'min_count': 1,
u'networks': [{'fixed_ip': fixed_ip}],
u'name': u'server-name'}})),
dict(method='GET',
uri=self.get_mock_url(
'compute', 'public', append=['servers', '1234']),
json={'server': build_server}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'networks.json']),
json={'networks': [network]}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'subnets.json']),
json={'subnets': []}),
])
self.cloud.create_server(
'server-name', dict(id='image-id'), dict(id='flavor-id'),
nics=[{'fixed_ip': fixed_ip}])
self.assert_calls()
def test_create_server_network_v4_fixed_ip(self):
"""
Verify that if 'v4-fixed-ip' is supplied in nics, we pass it to
networks appropriately.
"""
network = {
'id': 'network-id',
'name': 'network-name'
}
fixed_ip = '10.0.0.1'
build_server = fakes.make_fake_server('1234', '', 'BUILD')
self.register_uris([
dict(method='POST',
uri=self.get_mock_url(
'compute', 'public', append=['servers']),
json={'server': build_server},
validate=dict(
json={'server': {
u'flavorRef': u'flavor-id',
u'imageRef': u'image-id',
u'max_count': 1,
u'min_count': 1,
u'networks': [{'fixed_ip': fixed_ip}],
u'name': u'server-name'}})),
dict(method='GET',
uri=self.get_mock_url(
'compute', 'public', append=['servers', '1234']),
json={'server': build_server}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'networks.json']),
json={'networks': [network]}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'subnets.json']),
json={'subnets': []}),
])
self.cloud.create_server(
'server-name', dict(id='image-id'), dict(id='flavor-id'),
nics=[{'fixed_ip': fixed_ip}])
self.assert_calls()
def test_create_server_network_v6_fixed_ip(self):
"""
Verify that if 'v6-fixed-ip' is supplied in nics, we pass it to
networks appropriately.
"""
network = {
'id': 'network-id',
'name': 'network-name'
}
# Note - it doesn't actually have to be a v6 address - it's just
# an alias.
fixed_ip = 'fe80::28da:5fff:fe57:13ed'
build_server = fakes.make_fake_server('1234', '', 'BUILD')
self.register_uris([
dict(method='POST',
uri=self.get_mock_url(
'compute', 'public', append=['servers']),
json={'server': build_server},
validate=dict(
json={'server': {
u'flavorRef': u'flavor-id',
u'imageRef': u'image-id',
u'max_count': 1,
u'min_count': 1,
u'networks': [{'fixed_ip': fixed_ip}],
u'name': u'server-name'}})),
dict(method='GET',
uri=self.get_mock_url(
'compute', 'public', append=['servers', '1234']),
json={'server': build_server}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'networks.json']),
json={'networks': [network]}),
dict(method='GET',
uri=self.get_mock_url(
'network', 'public', append=['v2.0', 'subnets.json']),
json={'subnets': []}),
])
self.cloud.create_server(
'server-name', dict(id='image-id'), dict(id='flavor-id'),
nics=[{'fixed_ip': fixed_ip}])
self.assert_calls()
def test_create_server_network_fixed_ip_conflicts(self):
"""
Verify that if 'fixed_ip' and 'v4-fixed-ip' are both supplied in nics,
we throw an exception.
"""
# Note - it doesn't actually have to be a v6 address - it's just
# an alias.
self.use_nothing()
fixed_ip = '10.0.0.1'
self.assertRaises(
exc.OpenStackCloudException, self.cloud.create_server,
'server-name', dict(id='image-id'), dict(id='flavor-id'),
nics=[{
'fixed_ip': fixed_ip,
'v4-fixed-ip': fixed_ip
}])
self.assert_calls()
def test_create_server_get_flavor_image(self): def test_create_server_get_flavor_image(self):
self.use_glance() self.use_glance()
image_id = str(uuid.uuid4()) image_id = str(uuid.uuid4())