Stop normalizing floating ips
Next steps of a cleanup of the cloud layer are: - stop doing normalization of floating ips in case of neutron - stop inheriting from _normalize in the floating_ip class (move 2 required functions locally). Soon this is going to be reworked in favor of making better object support for those still using nova networking Change-Id: If67c2f8b78240c03f86daefcf0f472502821365a
This commit is contained in:
parent
dc6be6e906
commit
2267d458bb
@ -18,8 +18,8 @@ import ipaddress
|
||||
import threading
|
||||
import time
|
||||
import types # noqa
|
||||
import warnings
|
||||
|
||||
from openstack.cloud import _normalize
|
||||
from openstack.cloud import _utils
|
||||
from openstack.cloud import exc
|
||||
from openstack.cloud import meta
|
||||
@ -32,7 +32,7 @@ _CONFIG_DOC_URL = (
|
||||
"user/config/configuration.html")
|
||||
|
||||
|
||||
class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
class FloatingIPCloudMixin:
|
||||
|
||||
def __init__(self):
|
||||
self.private = self.config.config.get('private', False)
|
||||
@ -64,20 +64,14 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
def search_floating_ips(self, id=None, filters=None):
|
||||
# `filters` could be a jmespath expression which Neutron server doesn't
|
||||
# understand, obviously.
|
||||
warnings.warn(
|
||||
"search_floating_ips is deprecated. "
|
||||
"Use search_resource instead.")
|
||||
if self._use_neutron_floating() and isinstance(filters, dict):
|
||||
filter_keys = ['router_id', 'status', 'tenant_id', 'project_id',
|
||||
'revision_number', 'description',
|
||||
'floating_network_id', 'fixed_ip_address',
|
||||
'floating_ip_address', 'port_id', 'sort_dir',
|
||||
'sort_key', 'tags', 'tags-any', 'not-tags',
|
||||
'not-tags-any', 'fields']
|
||||
neutron_filters = {k: v for k, v in filters.items()
|
||||
if k in filter_keys}
|
||||
kwargs = {'filters': neutron_filters}
|
||||
return list(self.network.ips(**filters))
|
||||
else:
|
||||
kwargs = {}
|
||||
floating_ips = self.list_floating_ips(**kwargs)
|
||||
return _utils._filter_list(floating_ips, id, filters)
|
||||
floating_ips = self.list_floating_ips()
|
||||
return _utils._filter_list(floating_ips, id, filters)
|
||||
|
||||
def _neutron_list_floating_ips(self, filters=None):
|
||||
if not filters:
|
||||
@ -121,8 +115,7 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
def _list_floating_ips(self, filters=None):
|
||||
if self._use_neutron_floating():
|
||||
try:
|
||||
return self._normalize_floating_ips(
|
||||
self._neutron_list_floating_ips(filters))
|
||||
return self._neutron_list_floating_ips(filters)
|
||||
except exc.OpenStackCloudURINotFound as e:
|
||||
# Nova-network don't support server-side floating ips
|
||||
# filtering, so it's safer to return and empty list than
|
||||
@ -223,13 +216,15 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
""" Get a floating ip by ID
|
||||
|
||||
:param id: ID of the floating ip.
|
||||
:returns: A floating ip ``munch.Munch``.
|
||||
:returns: A floating ip
|
||||
`:class:`~openstack.network.v2.floating_ip.FloatingIP` or
|
||||
``munch.Munch``.
|
||||
"""
|
||||
error_message = "Error getting floating ip with ID {id}".format(id=id)
|
||||
|
||||
if self._use_neutron_floating():
|
||||
fip = self.network.get_ip(id)
|
||||
return self._normalize_floating_ip(fip)
|
||||
return fip
|
||||
else:
|
||||
data = proxy._json_response(
|
||||
self.compute.get('/os-floating-ips/{id}'.format(id=id)),
|
||||
@ -372,9 +367,8 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
"""
|
||||
if self._use_neutron_floating():
|
||||
try:
|
||||
f_ips = self._normalize_floating_ips(
|
||||
self._neutron_available_floating_ips(
|
||||
network=network, server=server))
|
||||
f_ips = self._neutron_available_floating_ips(
|
||||
network=network, server=server)
|
||||
return f_ips[0]
|
||||
except exc.OpenStackCloudURINotFound as e:
|
||||
self.log.debug(
|
||||
@ -458,8 +452,7 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
|
||||
def _submit_create_fip(self, kwargs):
|
||||
# Split into a method to aid in test mocking
|
||||
data = self.network.create_ip(**kwargs)
|
||||
return self._normalize_floating_ip(data)
|
||||
return self.network.create_ip(**kwargs)
|
||||
|
||||
def _neutron_create_floating_ip(
|
||||
self, network_name_or_id=None, server=None,
|
||||
@ -651,7 +644,7 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
processed = []
|
||||
if self._use_neutron_floating():
|
||||
for ip in self.list_floating_ips():
|
||||
if not ip['attached']:
|
||||
if not bool(ip.port_id):
|
||||
processed.append(self.delete_floating_ip(
|
||||
floating_ip_id=ip['id'], retry=retry))
|
||||
return len(processed) if all(processed) else False
|
||||
@ -794,7 +787,7 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
|
||||
def _neutron_detach_ip_from_server(self, server_id, floating_ip_id):
|
||||
f_ip = self.get_floating_ip(id=floating_ip_id)
|
||||
if f_ip is None or not f_ip['attached']:
|
||||
if f_ip is None or not bool(f_ip.port_id):
|
||||
return False
|
||||
try:
|
||||
self.network.update_ip(
|
||||
@ -1184,3 +1177,103 @@ class FloatingIPCloudMixin(_normalize.Normalizer):
|
||||
def _use_neutron_floating(self):
|
||||
return (self.has_service('network')
|
||||
and self._floating_ip_source == 'neutron')
|
||||
|
||||
def _normalize_floating_ips(self, ips):
|
||||
"""Normalize the structure of floating IPs
|
||||
|
||||
Unfortunately, not all the Neutron floating_ip attributes are available
|
||||
with Nova and not all Nova floating_ip attributes are available with
|
||||
Neutron.
|
||||
This function extract attributes that are common to Nova and Neutron
|
||||
floating IP resource.
|
||||
If the whole structure is needed inside shade, shade provides private
|
||||
methods that returns "original" objects (e.g.
|
||||
_neutron_allocate_floating_ip)
|
||||
|
||||
:param list ips: A list of Neutron floating IPs.
|
||||
|
||||
:returns:
|
||||
A list of normalized dicts with the following attributes::
|
||||
|
||||
[
|
||||
{
|
||||
"id": "this-is-a-floating-ip-id",
|
||||
"fixed_ip_address": "192.0.2.10",
|
||||
"floating_ip_address": "198.51.100.10",
|
||||
"network": "this-is-a-net-or-pool-id",
|
||||
"attached": True,
|
||||
"status": "ACTIVE"
|
||||
}, ...
|
||||
]
|
||||
|
||||
"""
|
||||
return [
|
||||
self._normalize_floating_ip(ip) for ip in ips
|
||||
]
|
||||
|
||||
def _normalize_floating_ip(self, ip):
|
||||
# Copy incoming floating ip because of shared dicts in unittests
|
||||
# Only import munch when we really need it
|
||||
import munch
|
||||
|
||||
location = self._get_current_location(
|
||||
project_id=ip.get('owner'))
|
||||
# This copy is to keep things from getting epically weird in tests
|
||||
ip = ip.copy()
|
||||
|
||||
ret = munch.Munch(location=location)
|
||||
|
||||
fixed_ip_address = ip.pop('fixed_ip_address', ip.pop('fixed_ip', None))
|
||||
floating_ip_address = ip.pop('floating_ip_address', ip.pop('ip', None))
|
||||
network_id = ip.pop(
|
||||
'floating_network_id', ip.pop('network', ip.pop('pool', None)))
|
||||
project_id = ip.pop('tenant_id', '')
|
||||
project_id = ip.pop('project_id', project_id)
|
||||
|
||||
instance_id = ip.pop('instance_id', None)
|
||||
router_id = ip.pop('router_id', None)
|
||||
id = ip.pop('id')
|
||||
port_id = ip.pop('port_id', None)
|
||||
created_at = ip.pop('created_at', None)
|
||||
updated_at = ip.pop('updated_at', None)
|
||||
# Note - description may not always be on the underlying cloud.
|
||||
# Normalizing it here is easy - what do we do when people want to
|
||||
# set a description?
|
||||
description = ip.pop('description', '')
|
||||
revision_number = ip.pop('revision_number', None)
|
||||
|
||||
if self._use_neutron_floating():
|
||||
attached = bool(port_id)
|
||||
status = ip.pop('status', 'UNKNOWN')
|
||||
else:
|
||||
attached = bool(instance_id)
|
||||
# In neutron's terms, Nova floating IPs are always ACTIVE
|
||||
status = 'ACTIVE'
|
||||
|
||||
ret = munch.Munch(
|
||||
attached=attached,
|
||||
fixed_ip_address=fixed_ip_address,
|
||||
floating_ip_address=floating_ip_address,
|
||||
id=id,
|
||||
location=self._get_current_location(project_id=project_id),
|
||||
network=network_id,
|
||||
port=port_id,
|
||||
router=router_id,
|
||||
status=status,
|
||||
created_at=created_at,
|
||||
updated_at=updated_at,
|
||||
description=description,
|
||||
revision_number=revision_number,
|
||||
properties=ip.copy(),
|
||||
)
|
||||
# Backwards compat
|
||||
if not self.strict_mode:
|
||||
ret['port_id'] = port_id
|
||||
ret['router_id'] = router_id
|
||||
ret['project_id'] = project_id
|
||||
ret['tenant_id'] = project_id
|
||||
ret['floating_network_id'] = network_id
|
||||
for key, val in ret['properties'].items():
|
||||
ret.setdefault(key, val)
|
||||
|
||||
return ret
|
||||
|
@ -404,113 +404,6 @@ class Normalizer:
|
||||
ret.setdefault(key, val)
|
||||
return ret
|
||||
|
||||
# TODO(stephenfin): Remove this once we get rid of support for nova
|
||||
# floating IPs
|
||||
def _normalize_floating_ips(self, ips):
|
||||
"""Normalize the structure of floating IPs
|
||||
|
||||
Unfortunately, not all the Neutron floating_ip attributes are available
|
||||
with Nova and not all Nova floating_ip attributes are available with
|
||||
Neutron.
|
||||
This function extract attributes that are common to Nova and Neutron
|
||||
floating IP resource.
|
||||
If the whole structure is needed inside shade, shade provides private
|
||||
methods that returns "original" objects (e.g.
|
||||
_neutron_allocate_floating_ip)
|
||||
|
||||
:param list ips: A list of Neutron floating IPs.
|
||||
|
||||
:returns:
|
||||
A list of normalized dicts with the following attributes::
|
||||
|
||||
[
|
||||
{
|
||||
"id": "this-is-a-floating-ip-id",
|
||||
"fixed_ip_address": "192.0.2.10",
|
||||
"floating_ip_address": "198.51.100.10",
|
||||
"network": "this-is-a-net-or-pool-id",
|
||||
"attached": True,
|
||||
"status": "ACTIVE"
|
||||
}, ...
|
||||
]
|
||||
|
||||
"""
|
||||
return [
|
||||
self._normalize_floating_ip(ip) for ip in ips
|
||||
]
|
||||
|
||||
# TODO(stephenfin): Remove this once we get rid of support for nova
|
||||
# floating IPs
|
||||
def _normalize_floating_ip(self, ip):
|
||||
# Copy incoming floating ip because of shared dicts in unittests
|
||||
if isinstance(ip, resource.Resource):
|
||||
ip = ip.to_dict(ignore_none=True, original_names=True)
|
||||
location = ip.pop(
|
||||
'location',
|
||||
self._get_current_location(project_id=ip.get('owner')))
|
||||
else:
|
||||
location = self._get_current_location(
|
||||
project_id=ip.get('owner'))
|
||||
# This copy is to keep things from getting epically weird in tests
|
||||
ip = ip.copy()
|
||||
|
||||
ret = munch.Munch(location=location)
|
||||
|
||||
fixed_ip_address = ip.pop('fixed_ip_address', ip.pop('fixed_ip', None))
|
||||
floating_ip_address = ip.pop('floating_ip_address', ip.pop('ip', None))
|
||||
network_id = ip.pop(
|
||||
'floating_network_id', ip.pop('network', ip.pop('pool', None)))
|
||||
project_id = ip.pop('tenant_id', '')
|
||||
project_id = ip.pop('project_id', project_id)
|
||||
|
||||
instance_id = ip.pop('instance_id', None)
|
||||
router_id = ip.pop('router_id', None)
|
||||
id = ip.pop('id')
|
||||
port_id = ip.pop('port_id', None)
|
||||
created_at = ip.pop('created_at', None)
|
||||
updated_at = ip.pop('updated_at', None)
|
||||
# Note - description may not always be on the underlying cloud.
|
||||
# Normalizing it here is easy - what do we do when people want to
|
||||
# set a description?
|
||||
description = ip.pop('description', '')
|
||||
revision_number = ip.pop('revision_number', None)
|
||||
|
||||
if self._use_neutron_floating():
|
||||
attached = bool(port_id)
|
||||
status = ip.pop('status', 'UNKNOWN')
|
||||
else:
|
||||
attached = bool(instance_id)
|
||||
# In neutron's terms, Nova floating IPs are always ACTIVE
|
||||
status = 'ACTIVE'
|
||||
|
||||
ret = munch.Munch(
|
||||
attached=attached,
|
||||
fixed_ip_address=fixed_ip_address,
|
||||
floating_ip_address=floating_ip_address,
|
||||
id=id,
|
||||
location=self._get_current_location(project_id=project_id),
|
||||
network=network_id,
|
||||
port=port_id,
|
||||
router=router_id,
|
||||
status=status,
|
||||
created_at=created_at,
|
||||
updated_at=updated_at,
|
||||
description=description,
|
||||
revision_number=revision_number,
|
||||
properties=ip.copy(),
|
||||
)
|
||||
# Backwards compat
|
||||
if not self.strict_mode:
|
||||
ret['port_id'] = port_id
|
||||
ret['router_id'] = router_id
|
||||
ret['project_id'] = project_id
|
||||
ret['tenant_id'] = project_id
|
||||
ret['floating_network_id'] = network_id
|
||||
for key, val in ret['properties'].items():
|
||||
ret.setdefault(key, val)
|
||||
|
||||
return ret
|
||||
|
||||
def _normalize_compute_usage(self, usage):
|
||||
""" Normalize a compute usage object """
|
||||
|
||||
|
@ -144,23 +144,7 @@ class TestFloatingIP(base.TestCase):
|
||||
u'version': 4,
|
||||
u'OS-EXT-IPS-MAC:mac_addr':
|
||||
u'fa:16:3e:ae:7d:42'}]})
|
||||
self.floating_ip = self.cloud._normalize_floating_ips(
|
||||
self.mock_floating_ip_list_rep['floatingips'])[0]
|
||||
|
||||
def test_float_no_status(self):
|
||||
floating_ips = [
|
||||
{
|
||||
'fixed_ip_address': '10.0.0.4',
|
||||
'floating_ip_address': '172.24.4.229',
|
||||
'floating_network_id': 'my-network-id',
|
||||
'id': '2f245a7b-796b-4f26-9cf9-9e82d248fda8',
|
||||
'port_id': None,
|
||||
'router_id': None,
|
||||
'tenant_id': '4969c491a3c74ee4af974e6d800c62df'
|
||||
}
|
||||
]
|
||||
normalized = self.cloud._normalize_floating_ips(floating_ips)
|
||||
self.assertEqual('UNKNOWN', normalized[0]['status'])
|
||||
self.floating_ip = self.mock_floating_ip_list_rep['floatingips'][0]
|
||||
|
||||
def test_list_floating_ips(self):
|
||||
self.register_uris([
|
||||
@ -195,11 +179,11 @@ class TestFloatingIP(base.TestCase):
|
||||
json=self.mock_floating_ip_list_rep)])
|
||||
|
||||
floating_ips = self.cloud.search_floating_ips(
|
||||
filters={'attached': False})
|
||||
filters={'updated_at': 'never'})
|
||||
|
||||
self.assertIsInstance(floating_ips, list)
|
||||
self.assertAreInstances(floating_ips, dict)
|
||||
self.assertEqual(1, len(floating_ips))
|
||||
self.assertEqual(0, len(floating_ips))
|
||||
self.assert_calls()
|
||||
|
||||
def test_get_floating_ip(self):
|
||||
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
No Munch conversion and normalization of the floating ips is happening
|
||||
anymore. For Neutron network a pure FloatingIP object is being returned,
|
||||
for Nova still munch object.
|
||||
deprecations:
|
||||
- |
|
||||
search_floating_ips method is deprecated and should not be used anymore. It
|
||||
is going to be dropped approximately after one major cycle.
|
Loading…
x
Reference in New Issue
Block a user