SDK: Remove remaining neutronclient calls

Migrate Neutron Quotas API to SDK.
Remove remaing references to neutronclient exceptions
and mentions in the API.

Related-Bug: #1999774
Change-Id: I85dc5668d13eb7971acfa19681643f23e2a4db1f
Signed-off-by: elajkat <lajos.katona@est.tech>
This commit is contained in:
elajkat
2025-06-25 11:02:16 +02:00
committed by Lajos Katona
parent 8287a65103
commit 933667d07b
16 changed files with 141 additions and 132 deletions

View File

@@ -31,8 +31,6 @@ from django.utils.translation import gettext_lazy as _
from keystoneauth1 import exceptions as ks_exceptions from keystoneauth1 import exceptions as ks_exceptions
from keystoneauth1 import session from keystoneauth1 import session
from keystoneauth1 import token_endpoint from keystoneauth1 import token_endpoint
from neutronclient.common import exceptions as neutron_exc
from neutronclient.v2_0 import client as neutron_client
from novaclient import exceptions as nova_exc from novaclient import exceptions as nova_exc
import openstack import openstack
from openstack import exceptions as sdk_exceptions from openstack import exceptions as sdk_exceptions
@@ -511,12 +509,9 @@ class SecurityGroupManager(object):
try: try:
rule = self.net_client.create_security_group_rule( rule = self.net_client.create_security_group_rule(
**params).to_dict() **params).to_dict()
except neutron_exc.OverQuotaClient: except sdk_exceptions.ConflictException:
raise exceptions.Conflict( raise exceptions.Conflict(
_('Security group rule quota exceeded.')) _('Security group rule quota exceeded.'))
except neutron_exc.Conflict:
raise exceptions.Conflict(
_('Security group rule already exists.'))
sg_dict = self._sg_name_dict(parent_group_id, [rule]) sg_dict = self._sg_name_dict(parent_group_id, [rule])
return SecurityGroupRule(rule, sg_dict) return SecurityGroupRule(rule, sg_dict)
@@ -967,18 +962,6 @@ def get_auth_params_from_request(request):
) )
@memoized
def neutronclient(request):
token_id, neutron_url, auth_url = get_auth_params_from_request(request)
insecure = settings.OPENSTACK_SSL_NO_VERIFY
cacert = settings.OPENSTACK_SSL_CACERT
c = neutron_client.Client(token=token_id,
auth_url=auth_url,
endpoint_url=neutron_url,
insecure=insecure, ca_cert=cacert)
return c
@memoized @memoized
def networkclient(request): def networkclient(request):
token_id, neutron_url, auth_url = get_auth_params_from_request(request) token_id, neutron_url, auth_url = get_auth_params_from_request(request)
@@ -1034,7 +1017,12 @@ def list_resources_with_long_filters(list_method,
try: try:
params[filter_attr] = filter_values params[filter_attr] = filter_values
return list_method(**params) return list_method(**params)
except neutron_exc.RequestURITooLong as uri_len_exc: except sdk_exceptions.HttpException as uri_len_exc:
# Note: neutronclient.RequestURITooLong was rised
# in case of http414
if uri_len_exc.status_code != 414:
pass
else:
# The URI is too long because of too many filter values. # The URI is too long because of too many filter values.
# Use the excess attribute of the exception to know how many # Use the excess attribute of the exception to know how many
# filter values can be inserted into a single request. # filter values can be inserted into a single request.
@@ -1053,7 +1041,13 @@ def list_resources_with_long_filters(list_method,
# The length will be key_len + value_maxlen + 2 # The length will be key_len + value_maxlen + 2
all_filter_len = sum(len(filter_attr) + len(val) + 2 all_filter_len = sum(len(filter_attr) + len(val) + 2
for val in filter_values) for val in filter_values)
allowed_filter_len = all_filter_len - uri_len_exc.excess # Note(lajoskatona): with python-neutronclient excess
# was an arg of RequestURITooLong exception, see:
# https://opendev.org/openstack/python-neutronclient/src/commit/
# 5f7d102f0e8111d6e90d958ab22682d07876a073/neutronclient/
# client.py#L177
excess = _get_excess(all_filter_len)
allowed_filter_len = all_filter_len - excess
val_maxlen = max(len(val) for val in filter_values) val_maxlen = max(len(val) for val in filter_values)
filter_maxlen = len(filter_attr) + val_maxlen + 2 filter_maxlen = len(filter_attr) + val_maxlen + 2
@@ -1066,6 +1060,11 @@ def list_resources_with_long_filters(list_method,
return resources return resources
def _get_excess(filter_len):
MAX_URI_LEN = 8192
return filter_len - MAX_URI_LEN
@profiler.trace @profiler.trace
def trunk_show(request, trunk_id): def trunk_show(request, trunk_id):
LOG.debug("trunk_show(): trunk_id=%s", trunk_id) LOG.debug("trunk_show(): trunk_id=%s", trunk_id)
@@ -2059,27 +2058,28 @@ def router_static_route_add(request, router_id, newroute):
@profiler.trace @profiler.trace
def tenant_quota_get(request, tenant_id): def tenant_quota_get(request, tenant_id):
return base.QuotaSet(neutronclient(request).show_quota(tenant_id)['quota']) return base.QuotaSet(
networkclient(request).get_quota(tenant_id).to_dict().pop('location'))
@profiler.trace @profiler.trace
def tenant_quota_update(request, tenant_id, **kwargs): def tenant_quota_update(request, tenant_id, **kwargs):
quotas = {'quota': kwargs} return networkclient(request).update_quota(tenant_id, **kwargs).to_dict()
return neutronclient(request).update_quota(tenant_id, quotas)
@profiler.trace @profiler.trace
def tenant_quota_detail_get(request, tenant_id=None): def tenant_quota_detail_get(request, tenant_id=None):
tenant_id = tenant_id or request.user.tenant_id tenant_id = tenant_id or request.user.tenant_id
response = neutronclient(request).get('/quotas/%s/details' % tenant_id) rsp = networkclient(request).get('/quotas/%s/details' % tenant_id)
return response['quota'] return rsp.json()['quota']
@profiler.trace @profiler.trace
def default_quota_get(request, tenant_id=None): def default_quota_get(request, tenant_id=None):
tenant_id = tenant_id or request.user.tenant_id tenant_id = tenant_id or request.user.tenant_id
response = neutronclient(request).show_quota_default(tenant_id) response = networkclient(request).get_quota_default(tenant_id).to_dict()
return base.QuotaSet(response['quota']) response.pop('location')
return base.QuotaSet(response)
@profiler.trace @profiler.trace
@@ -2273,7 +2273,7 @@ def servers_update_addresses(request, servers, all_tenants=False):
networks = list_resources_with_long_filters( networks = list_resources_with_long_filters(
network_list, 'id', frozenset([port.network_id for port in ports]), network_list, 'id', frozenset([port.network_id for port in ports]),
request=request) request=request)
except neutron_exc.NotFound as e: except sdk_exceptions.NotFoundException as e:
LOG.error('Neutron resource does not exist. %s', e) LOG.error('Neutron resource does not exist. %s', e)
return return
except Exception as e: except Exception as e:

View File

@@ -15,7 +15,7 @@ import logging
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -145,7 +145,7 @@ class CreatePolicyForm(forms.SelfHandlingForm):
msg = _('RBAC Policy was successfully created.') msg = _('RBAC Policy was successfully created.')
messages.success(request, msg) messages.success(request, msg)
return rbac_policy return rbac_policy
except neutron_exc.OverQuotaClient: except sdk_exceptions.ConflictException:
redirect = reverse('horizon:admin:rbac_policies:index') redirect = reverse('horizon:admin:rbac_policies:index')
msg = _('RBAC Policy quota exceeded.') msg = _('RBAC Policy quota exceeded.')
exceptions.handle(request, msg, redirect=redirect) exceptions.handle(request, msg, redirect=redirect)

View File

@@ -17,7 +17,7 @@ import logging
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
@@ -59,7 +59,7 @@ class IndexView(tables.DataTableView):
"Manage floating IP port forwarding rules : " + str( "Manage floating IP port forwarding rules : " + str(
floating_ip.ip)) floating_ip.ip))
return self.get_floating_ip_rules(floating_ip) return self.get_floating_ip_rules(floating_ip)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:
exceptions.handle( exceptions.handle(
@@ -92,7 +92,7 @@ class AllRulesView(IndexView):
def get_data(self): def get_data(self):
try: try:
return self.get_all_floating_ip_rules() return self.get_all_floating_ip_rules()
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:
exceptions.handle( exceptions.handle(

View File

@@ -16,7 +16,7 @@ from django.core.exceptions import ValidationError
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -228,7 +228,7 @@ class FloatingIpPortForwardingRuleCreationWorkflow(workflows.Workflow):
param.update(**api_params) param.update(**api_params)
api_method(request, floating_ip_id, **param) api_method(request, floating_ip_id, **param)
except neutron_exc.Conflict as ex: except sdk_exceptions.BadRequestException as ex:
msg = _('The requested instance port is already' msg = _('The requested instance port is already'
' associated with another floating IP.') ' associated with another floating IP.')
LOG.exception(msg, ex) LOG.exception(msg, ex)

View File

@@ -25,7 +25,7 @@ import logging
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -74,7 +74,7 @@ class AllocateView(forms.ModalFormView):
def get_initial(self): def get_initial(self):
try: try:
pools = api.neutron.floating_ip_pools_list(self.request) pools = api.neutron.floating_ip_pools_list(self.request)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
pools = [] pools = []
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:
@@ -96,7 +96,7 @@ class IndexView(tables.DataTableView):
search_opts = self.get_filters() search_opts = self.get_filters()
floating_ips = api.neutron.tenant_floating_ip_list(self.request, floating_ips = api.neutron.tenant_floating_ip_list(self.request,
**search_opts) **search_opts)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
floating_ips = [] floating_ips = []
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:
@@ -107,7 +107,7 @@ class IndexView(tables.DataTableView):
try: try:
floating_ip_pools = \ floating_ip_pools = \
api.neutron.floating_ip_pools_list(self.request) api.neutron.floating_ip_pools_list(self.request)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
floating_ip_pools = [] floating_ip_pools = []
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:

View File

@@ -15,7 +15,7 @@
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -88,7 +88,7 @@ class AssociateIPAction(workflows.Action):
redirect = reverse('horizon:project:floating_ips:index') redirect = reverse('horizon:project:floating_ips:index')
try: try:
ips = api.neutron.tenant_floating_ip_list(self.request) ips = api.neutron.tenant_floating_ip_list(self.request)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
exceptions.handle(self.request, redirect=redirect) exceptions.handle(self.request, redirect=redirect)
except Exception: except Exception:
exceptions.handle(self.request, exceptions.handle(self.request,
@@ -170,7 +170,7 @@ class IPAssociationWorkflow(workflows.Workflow):
api.neutron.floating_ip_associate(request, api.neutron.floating_ip_associate(request,
data['ip_id'], data['ip_id'],
data['port_id']) data['port_id'])
except neutron_exc.Conflict: except sdk_exceptions.ConflictException:
msg = _('The requested instance port is already' msg = _('The requested instance port is already'
' associated with another floating IP.') ' associated with another floating IP.')
exceptions.handle(request, msg) exceptions.handle(request, msg)

View File

@@ -14,7 +14,7 @@
import logging import logging
from neutronclient.common import exceptions as neutron_exceptions from openstack import exceptions as sdk_exceptions
from django.urls import reverse from django.urls import reverse
from django.urls import reverse_lazy from django.urls import reverse_lazy
@@ -79,7 +79,7 @@ class DeleteSubnet(SubnetPolicyTargetMixin, tables.DeleteAction):
# normal_log_message # normal_log_message
'Failed to delete subnet %(id)s: %(exc)s', 'Failed to delete subnet %(id)s: %(exc)s',
# target_exception # target_exception
neutron_exceptions.Conflict, sdk_exceptions.ConflictException,
# target_log_message # target_log_message
'Unable to delete subnet %(id)s with 409 Conflict: %(exc)s', 'Unable to delete subnet %(id)s with 409 Conflict: %(exc)s',
# target_user_message # target_user_message

View File

@@ -19,7 +19,7 @@ from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy from django.utils.translation import ngettext_lazy
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
from neutronclient.common import exceptions as neutron_exceptions from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
@@ -63,7 +63,7 @@ class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction):
# normal_log_message # normal_log_message
'Failed to delete network %(id)s: %(exc)s', 'Failed to delete network %(id)s: %(exc)s',
# target_exception # target_exception
neutron_exceptions.Conflict, sdk_exceptions.ConflictException,
# target_log_message # target_log_message
'Unable to delete network %(id)s with 409 Conflict: %(exc)s', 'Unable to delete network %(id)s with 409 Conflict: %(exc)s',
# target_user_message # target_user_message

View File

@@ -17,7 +17,7 @@ import logging
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -49,7 +49,7 @@ class AddRouterRoute(forms.SelfHandlingForm):
msg = _('Static route added') msg = _('Static route added')
messages.success(request, msg) messages.success(request, msg)
return True return True
except neutron_exc.BadRequest as e: except sdk_exceptions.BadRequestException as e:
LOG.info('Invalid format for routes %(route)s: %(exc)s', LOG.info('Invalid format for routes %(route)s: %(exc)s',
{'route': route, 'exc': e}) {'route': route, 'exc': e})
msg = _('Invalid format for routes: %s') % e msg = _('Invalid format for routes: %s') % e

View File

@@ -19,7 +19,7 @@ from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy from django.utils.translation import ngettext_lazy
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
from neutronclient.common import exceptions as neutron_exceptions from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
@@ -57,7 +57,7 @@ class DeleteRouter(policy.PolicyTargetMixin, tables.DeleteAction):
# normal_log_message # normal_log_message
'Failed to delete router %(id)s: %(exc)s', 'Failed to delete router %(id)s: %(exc)s',
# target_exception # target_exception
neutron_exceptions.NeutronClientException, sdk_exceptions.SDKException,
# target_log_message # target_log_message
'Unable to delete router %(id)s: %(exc)s', 'Unable to delete router %(id)s: %(exc)s',
# target_user_message # target_user_message
@@ -151,7 +151,7 @@ class ClearGateway(policy.PolicyTargetMixin, tables.BatchAction):
# normal_log_message # normal_log_message
'Unable to clear gateway for router %(id)s: %(exc)s', 'Unable to clear gateway for router %(id)s: %(exc)s',
# target_exception # target_exception
neutron_exceptions.Conflict, sdk_exceptions.ConflictException,
# target_log_message # target_log_message
'Unable to clear gateway for router %(id)s: %(exc)s', 'Unable to clear gateway for router %(id)s: %(exc)s',
# target_user_message # target_user_message

View File

@@ -22,7 +22,7 @@ Views for managing instances.
from django.urls import reverse from django.urls import reverse
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
@@ -183,7 +183,7 @@ class IndexView(tables.DataTableView):
def get_data(self): def get_data(self):
try: try:
security_groups = api.neutron.security_group_list(self.request) security_groups = api.neutron.security_group_list(self.request)
except neutron_exc.ConnectionFailed: except sdk_exceptions.SDKException:
security_groups = [] security_groups = []
exceptions.handle(self.request) exceptions.handle(self.request)
except Exception: except Exception:

View File

@@ -19,8 +19,8 @@
from cinderclient import exceptions as cinderclient from cinderclient import exceptions as cinderclient
from glanceclient import exc as glanceclient from glanceclient import exc as glanceclient
from keystoneclient import exceptions as keystoneclient from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient from novaclient import exceptions as novaclient
from openstack import exceptions as sdk_exceptions
from requests import exceptions as requests from requests import exceptions as requests
from swiftclient import client as swiftclient from swiftclient import client as swiftclient
@@ -30,7 +30,7 @@ UNAUTHORIZED = (
cinderclient.Unauthorized, cinderclient.Unauthorized,
novaclient.Unauthorized, novaclient.Unauthorized,
glanceclient.HTTPUnauthorized, glanceclient.HTTPUnauthorized,
neutronclient.Unauthorized, sdk_exceptions.HttpException,
) )
@@ -39,7 +39,7 @@ NOT_FOUND = (
cinderclient.NotFound, cinderclient.NotFound,
novaclient.NotFound, novaclient.NotFound,
glanceclient.HTTPNotFound, glanceclient.HTTPNotFound,
neutronclient.NotFound, sdk_exceptions.NotFoundException,
) )
@@ -56,8 +56,8 @@ RECOVERABLE = (
novaclient.Forbidden, novaclient.Forbidden,
glanceclient.HTTPException, glanceclient.HTTPException,
glanceclient.CommunicationError, glanceclient.CommunicationError,
neutronclient.Forbidden, sdk_exceptions.ForbiddenException,
neutronclient.NeutronClientException, sdk_exceptions.SDKException,
swiftclient.ClientException, swiftclient.ClientException,
requests.RequestException, requests.RequestException,
) )

View File

@@ -23,8 +23,8 @@ def test_delete_multiple_instance_rows(live_server, driver, dashboard_data,
mock.patch.object( mock.patch.object(
api.nova, 'flavor_list') as mocked_f_l, \ api.nova, 'flavor_list') as mocked_f_l, \
mock.patch( mock.patch(
'neutronclient.v2_0.client.Client' 'openstack.network.v2._proxy.Proxy.'
'.list_extensions') as mocked_l_e, \ 'extensions') as mocked_l_e, \
mock.patch.object( mock.patch.object(
api.nova, 'tenant_absolute_limits') as mocked_t_a_l, \ api.nova, 'tenant_absolute_limits') as mocked_t_a_l, \
mock.patch.object( mock.patch.object(

View File

@@ -15,8 +15,8 @@
from cinderclient import exceptions as cinder_exceptions from cinderclient import exceptions as cinder_exceptions
import glanceclient.exc as glance_exceptions import glanceclient.exc as glance_exceptions
from keystoneclient import exceptions as keystone_exceptions from keystoneclient import exceptions as keystone_exceptions
from neutronclient.common import exceptions as neutron_exceptions
from novaclient import exceptions as nova_exceptions from novaclient import exceptions as nova_exceptions
from openstack import exceptions as sdk_exceptions
from swiftclient import client as swift_exceptions from swiftclient import client as swift_exceptions
from openstack_dashboard.test.test_data import utils from openstack_dashboard.test.test_data import utils
@@ -67,7 +67,7 @@ def data(TEST):
glance_exception = glance_exceptions.ClientException glance_exception = glance_exceptions.ClientException
TEST.exceptions.glance = create_stubbed_exception(glance_exception) TEST.exceptions.glance = create_stubbed_exception(glance_exception)
neutron_exception = neutron_exceptions.NeutronClientException neutron_exception = sdk_exceptions.SDKException
TEST.exceptions.neutron = create_stubbed_exception(neutron_exception) TEST.exceptions.neutron = create_stubbed_exception(neutron_exception)
swift_exception = swift_exceptions.ClientException swift_exception = swift_exceptions.ClientException

View File

@@ -15,7 +15,6 @@ import copy
from unittest import mock from unittest import mock
import netaddr import netaddr
from neutronclient.common import exceptions as neutron_exc
from openstack import exceptions as sdk_exceptions from openstack import exceptions as sdk_exceptions
from openstack.network.v2 import port as sdk_port from openstack.network.v2 import port as sdk_port
from openstack.network.v2 import subnet_pool as sdk_subnet_pool from openstack.network.v2 import subnet_pool as sdk_subnet_pool
@@ -33,19 +32,19 @@ from openstack_dashboard.test.test_data import neutron_data
class NeutronApiTests(test.APIMockTestCase): class NeutronApiTests(test.APIMockTestCase):
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_network_list(self, mock_neutronclient): def test_network_list(self, mock_networkclient):
networks = self.api_networks_sdk networks = self.api_networks_sdk
subnets = self.api_subnets_sdk subnets = self.api_subnets_sdk
neutronclient = mock_neutronclient.return_value networkclient = mock_networkclient.return_value
neutronclient.networks.return_value = networks networkclient.networks.return_value = networks
neutronclient.subnets.return_value = subnets networkclient.subnets.return_value = subnets
ret_val = api.neutron.network_list(self.request) ret_val = api.neutron.network_list(self.request)
for n in ret_val: for n in ret_val:
self.assertIsInstance(n, api.neutron.Network) self.assertIsInstance(n, api.neutron.Network)
neutronclient.networks.assert_called_once_with() networkclient.networks.assert_called_once_with()
neutronclient.subnets.assert_called_once_with() networkclient.subnets.assert_called_once_with()
@override_settings(OPENSTACK_NEUTRON_NETWORK={ @override_settings(OPENSTACK_NEUTRON_NETWORK={
'enable_auto_allocated_network': True}) 'enable_auto_allocated_network': True})
@@ -919,17 +918,17 @@ class NeutronApiTests(test.APIMockTestCase):
subnet_id = self.api_networks_sdk[0]['subnets'][0] subnet_id = self.api_networks_sdk[0]['subnets'][0]
subnetv6_id = self.api_networks_sdk[0]['subnets'][1] subnetv6_id = self.api_networks_sdk[0]['subnets'][1]
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.get_network.return_value = network networkclient.get_network.return_value = network
neutronclient.get_subnet.side_effect = [subnet, subnetv6] networkclient.get_subnet.side_effect = [subnet, subnetv6]
ret_val = api.neutron.network_get(self.request, network_id) ret_val = api.neutron.network_get(self.request, network_id)
self.assertIsInstance(ret_val, api.neutron.Network) self.assertIsInstance(ret_val, api.neutron.Network)
self.assertEqual(2, len(ret_val['subnets'])) self.assertEqual(2, len(ret_val['subnets']))
self.assertIsInstance(ret_val['subnets'][0], api.neutron.Subnet) self.assertIsInstance(ret_val['subnets'][0], api.neutron.Subnet)
neutronclient.get_network.assert_called_once_with(network_id) networkclient.get_network.assert_called_once_with(network_id)
neutronclient.get_subnet.assert_has_calls([ networkclient.get_subnet.assert_has_calls([
mock.call(subnet_id), mock.call(subnet_id),
mock.call(subnetv6_id), mock.call(subnetv6_id),
]) ])
@@ -940,57 +939,57 @@ class NeutronApiTests(test.APIMockTestCase):
network_id = self.api_networks_sdk[0]['id'] network_id = self.api_networks_sdk[0]['id']
subnet_id = self.api_networks_sdk[0]['subnet_ids'][0] subnet_id = self.api_networks_sdk[0]['subnet_ids'][0]
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.get_network.return_value = network networkclient.get_network.return_value = network
neutronclient.get_subnet.side_effect = sdk_exceptions.ResourceNotFound networkclient.get_subnet.side_effect = sdk_exceptions.ResourceNotFound
ret_val = api.neutron.network_get(self.request, network_id) ret_val = api.neutron.network_get(self.request, network_id)
self.assertIsInstance(ret_val, api.neutron.Network) self.assertIsInstance(ret_val, api.neutron.Network)
self.assertEqual(2, len(ret_val['subnet_ids'])) self.assertEqual(2, len(ret_val['subnet_ids']))
self.assertNotIsInstance(ret_val['subnet_ids'][0], api.neutron.Subnet) self.assertNotIsInstance(ret_val['subnet_ids'][0], api.neutron.Subnet)
self.assertIsInstance(ret_val['subnet_ids'][0], str) self.assertIsInstance(ret_val['subnet_ids'][0], str)
neutronclient.get_network.assert_called_once_with(network_id) networkclient.get_network.assert_called_once_with(network_id)
neutronclient.get_subnet.assert_called_once_with(subnet_id) networkclient.get_subnet.assert_called_once_with(subnet_id)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_network_create(self, mock_networkclient): def test_network_create(self, mock_networkclient):
network = self.api_networks_sdk[0] network = self.api_networks_sdk[0]
form_data = {'name': 'net1', form_data = {'name': 'net1',
'tenant_id': self.request.user.project_id} 'tenant_id': self.request.user.project_id}
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.create_network.return_value = network networkclient.create_network.return_value = network
ret_val = api.neutron.network_create(self.request, name='net1') ret_val = api.neutron.network_create(self.request, name='net1')
self.assertIsInstance(ret_val, api.neutron.Network) self.assertIsInstance(ret_val, api.neutron.Network)
neutronclient.create_network.assert_called_once_with(**form_data) networkclient.create_network.assert_called_once_with(**form_data)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_network_update(self, mock_networkclient): def test_network_update(self, mock_networkclient):
network = self.api_networks_sdk[0] network = self.api_networks_sdk[0]
network_id = self.api_networks_sdk[0]['id'] network_id = self.api_networks_sdk[0]['id']
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
form_data = {'name': 'net1'} form_data = {'name': 'net1'}
neutronclient.update_network.return_value = network networkclient.update_network.return_value = network
ret_val = api.neutron.network_update(self.request, network_id, ret_val = api.neutron.network_update(self.request, network_id,
name='net1') name='net1')
self.assertIsInstance(ret_val, api.neutron.Network) self.assertIsInstance(ret_val, api.neutron.Network)
neutronclient.update_network.assert_called_once_with(network_id, networkclient.update_network.assert_called_once_with(network_id,
**form_data) **form_data)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_network_delete(self, mock_networkclient): def test_network_delete(self, mock_networkclient):
network_id = self.api_networks_sdk[0]['id'] network_id = self.api_networks_sdk[0]['id']
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.delete_network.return_value = None networkclient.delete_network.return_value = None
api.neutron.network_delete(self.request, network_id) api.neutron.network_delete(self.request, network_id)
neutronclient.delete_network.assert_called_once_with(network_id) networkclient.delete_network.assert_called_once_with(network_id)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_get_network_ip_availability(self, mock_networkclient): def test_get_network_ip_availability(self, mock_networkclient):
@@ -1029,27 +1028,27 @@ class NeutronApiTests(test.APIMockTestCase):
def test_subnet_list(self, mock_networkclient): def test_subnet_list(self, mock_networkclient):
subnets = self.api_subnets_sdk subnets = self.api_subnets_sdk
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.subnets.return_value = subnets networkclient.subnets.return_value = subnets
ret_val = api.neutron.subnet_list(self.request) ret_val = api.neutron.subnet_list(self.request)
for n in ret_val: for n in ret_val:
self.assertIsInstance(n, api.neutron.Subnet) self.assertIsInstance(n, api.neutron.Subnet)
neutronclient.subnets.assert_called_once_with() networkclient.subnets.assert_called_once_with()
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_subnet_get(self, mock_networkclient): def test_subnet_get(self, mock_networkclient):
subnet = self.api_subnets_sdk[0] subnet = self.api_subnets_sdk[0]
subnet_id = self.api_subnets_sdk[0]['id'] subnet_id = self.api_subnets_sdk[0]['id']
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.get_subnet.return_value = subnet networkclient.get_subnet.return_value = subnet
ret_val = api.neutron.subnet_get(self.request, subnet_id) ret_val = api.neutron.subnet_get(self.request, subnet_id)
self.assertIsInstance(ret_val, api.neutron.Subnet) self.assertIsInstance(ret_val, api.neutron.Subnet)
neutronclient.get_subnet.assert_called_once_with(subnet_id) networkclient.get_subnet.assert_called_once_with(subnet_id)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_subnet_create(self, mock_networkclient): def test_subnet_create(self, mock_networkclient):
@@ -1061,13 +1060,13 @@ class NeutronApiTests(test.APIMockTestCase):
'ip_version': subnet_data['ip_version'], 'ip_version': subnet_data['ip_version'],
'gateway_ip': subnet_data['gateway_ip']} 'gateway_ip': subnet_data['gateway_ip']}
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.create_subnet.return_value = subnet_data networkclient.create_subnet.return_value = subnet_data
ret_val = api.neutron.subnet_create(self.request, **params) ret_val = api.neutron.subnet_create(self.request, **params)
self.assertIsInstance(ret_val, api.neutron.Subnet) self.assertIsInstance(ret_val, api.neutron.Subnet)
neutronclient.create_subnet.assert_called_once_with(**params) networkclient.create_subnet.assert_called_once_with(**params)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_subnet_update(self, mock_networkclient): def test_subnet_update(self, mock_networkclient):
@@ -1076,25 +1075,25 @@ class NeutronApiTests(test.APIMockTestCase):
params = {'name': subnet_data['name'], params = {'name': subnet_data['name'],
'gateway_ip': subnet_data['gateway_ip']} 'gateway_ip': subnet_data['gateway_ip']}
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.update_subnet.return_value = subnet_data networkclient.update_subnet.return_value = subnet_data
ret_val = api.neutron.subnet_update(self.request, subnet_id, **params) ret_val = api.neutron.subnet_update(self.request, subnet_id, **params)
self.assertIsInstance(ret_val, api.neutron.Subnet) self.assertIsInstance(ret_val, api.neutron.Subnet)
neutronclient.update_subnet.assert_called_once_with( networkclient.update_subnet.assert_called_once_with(
subnet_id, **params) subnet_id, **params)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_subnet_delete(self, mock_networkclient): def test_subnet_delete(self, mock_networkclient):
subnet_id = self.api_subnets_sdk[0]['id'] subnet_id = self.api_subnets_sdk[0]['id']
neutronclient = mock_networkclient.return_value networkclient = mock_networkclient.return_value
neutronclient.delete_subnet.return_value = None networkclient.delete_subnet.return_value = None
api.neutron.subnet_delete(self.request, subnet_id) api.neutron.subnet_delete(self.request, subnet_id)
neutronclient.delete_subnet.assert_called_once_with(subnet_id) networkclient.delete_subnet.assert_called_once_with(subnet_id)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_subnetpool_list(self, mock_networkclient): def test_subnetpool_list(self, mock_networkclient):
@@ -1188,7 +1187,7 @@ class NeutronApiTests(test.APIMockTestCase):
trunks = self.api_tp_trunks_sdk trunks = self.api_tp_trunks_sdk
# list_extensions is decorated with memoized_with_request, so # list_extensions is decorated with memoized_with_request, so
# neutronclient() is not called. We need to mock it separately. # networkclient() is not called. We need to mock it separately.
mock_is_extension_supported.return_value = True # trunk mock_is_extension_supported.return_value = True # trunk
network_client = mock_networkclient.return_value network_client = mock_networkclient.return_value
@@ -1740,7 +1739,10 @@ class NeutronApiTests(test.APIMockTestCase):
self._test_get_router_ha_permission_with_policy_check(False) self._test_get_router_ha_permission_with_policy_check(False)
@mock.patch.object(api.neutron, 'networkclient') @mock.patch.object(api.neutron, 'networkclient')
def test_list_resources_with_long_filters(self, mock_networkclient): @mock.patch.object(api.neutron, '_get_excess')
def test_list_resources_with_long_filters(self,
mock_excess,
mock_networkclient):
# In this tests, port_list is called with id=[10 port ID] # In this tests, port_list is called with id=[10 port ID]
# filter. It generates about 40*10 char length URI. # filter. It generates about 40*10 char length URI.
# Each port ID is converted to "id=<UUID>&" in URI and # Each port ID is converted to "id=<UUID>&" in URI and
@@ -1756,7 +1758,16 @@ class NeutronApiTests(test.APIMockTestCase):
port_ids = tuple([port['id'] for port in ports]) port_ids = tuple([port['id'] for port in ports])
network_client = mock_networkclient.return_value network_client = mock_networkclient.return_value
uri_len_exc = neutron_exc.RequestURITooLong(excess=220) uri_len_exc = sdk_exceptions.HttpException(http_status=414)
# Note(lajoskatona): with neutronclient http414 (RequestURITooLong)
# had the excess argument, in SDK no such option, so have to
# workaround that and count from the uri and MAX_URI_LEN, 8192,
# see the code in api/neutron.py. From this test mocking can help
# to force the use of smaller excess value.
# This can be a discussion topic to have similar exception in SDK.
mock_excess.return_value = 220
list_ports_retval = [uri_len_exc] list_ports_retval = [uri_len_exc]
for i in range(0, 10, 4): for i in range(0, 10, 4):
list_ports_retval.append(ports[i:i + 4]) list_ports_retval.append(ports[i:i + 4])
@@ -2039,9 +2050,7 @@ class NeutronApiSecurityGroupTests(test.APIMockTestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
neutronclient = mock.patch.object(api.neutron, 'neutronclient').start()
networkclient = mock.patch.object(api.neutron, 'networkclient').start() networkclient = mock.patch.object(api.neutron, 'networkclient').start()
self.qclient = neutronclient.return_value
self.netclient = networkclient.return_value self.netclient = networkclient.return_value
self.sg_dict = dict([(sg['id'], sg['name']) for sg self.sg_dict = dict([(sg['id'], sg['name']) for sg
in self.api_security_groups_sdk]) in self.api_security_groups_sdk])

View File

@@ -12,6 +12,7 @@ futurist>=1.2.0 # Apache-2.0
iso8601>=0.1.11 # MIT iso8601>=0.1.11 # MIT
keystoneauth1>=4.3.1 # Apache-2.0 keystoneauth1>=4.3.1 # Apache-2.0
netaddr>=0.7.18 # BSD netaddr>=0.7.18 # BSD
openstacksdk>=4.5.0 # Apache-2.0
oslo.concurrency>=4.5.0 # Apache-2.0 oslo.concurrency>=4.5.0 # Apache-2.0
oslo.config>=8.8.0 # Apache-2.0 oslo.config>=8.8.0 # Apache-2.0
oslo.i18n>=5.1.0 # Apache-2.0 oslo.i18n>=5.1.0 # Apache-2.0
@@ -25,7 +26,6 @@ Pillow>=9.1.0 # PIL License
python-cinderclient>=8.0.0 # Apache-2.0 python-cinderclient>=8.0.0 # Apache-2.0
python-glanceclient>=2.8.0 # Apache-2.0 python-glanceclient>=2.8.0 # Apache-2.0
python-keystoneclient>=3.22.0 # Apache-2.0 python-keystoneclient>=3.22.0 # Apache-2.0
python-neutronclient>=8.1.0 # Apache-2.0
python-novaclient>=9.1.0 # Apache-2.0 python-novaclient>=9.1.0 # Apache-2.0
python-swiftclient>=3.2.0 # Apache-2.0 python-swiftclient>=3.2.0 # Apache-2.0
PyYAML>=6.0 # MIT PyYAML>=6.0 # MIT