diff --git a/openstack_dashboard/api/neutron.py b/openstack_dashboard/api/neutron.py index c4fd3aedf7..884743e13d 100644 --- a/openstack_dashboard/api/neutron.py +++ b/openstack_dashboard/api/neutron.py @@ -31,6 +31,8 @@ from django.utils.translation import gettext_lazy as _ from keystoneauth1 import exceptions as ks_exceptions from keystoneauth1 import session 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 import openstack from openstack import exceptions as sdk_exceptions @@ -509,9 +511,12 @@ class SecurityGroupManager(object): try: rule = self.net_client.create_security_group_rule( **params).to_dict() - except sdk_exceptions.ConflictException: + except neutron_exc.OverQuotaClient: raise exceptions.Conflict( _('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]) return SecurityGroupRule(rule, sg_dict) @@ -962,6 +967,18 @@ 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 def networkclient(request): token_id, neutron_url, auth_url = get_auth_params_from_request(request) @@ -1017,52 +1034,36 @@ def list_resources_with_long_filters(list_method, try: params[filter_attr] = filter_values return list_method(**params) - 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. - # Use the excess attribute of the exception to know how many - # filter values can be inserted into a single request. + except neutron_exc.RequestURITooLong as uri_len_exc: + # The URI is too long because of too many filter values. + # Use the excess attribute of the exception to know how many + # filter values can be inserted into a single request. - # We consider only the filter condition from (filter_attr, - # filter_values) and do not consider other filter conditions - # which may be specified in **params. + # We consider only the filter condition from (filter_attr, + # filter_values) and do not consider other filter conditions + # which may be specified in **params. - if isinstance(filter_values, str): - filter_values = [filter_values] - elif not isinstance(filter_values, Sequence): - filter_values = list(filter_values) + if isinstance(filter_values, str): + filter_values = [filter_values] + elif not isinstance(filter_values, Sequence): + filter_values = list(filter_values) - # Length of each query filter is: - # =& (e.g., id=) - # The length will be key_len + value_maxlen + 2 - all_filter_len = sum(len(filter_attr) + len(val) + 2 - for val in filter_values) - # 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 + # Length of each query filter is: + # =& (e.g., id=) + # The length will be key_len + value_maxlen + 2 + all_filter_len = sum(len(filter_attr) + len(val) + 2 + for val in filter_values) + allowed_filter_len = all_filter_len - uri_len_exc.excess - val_maxlen = max(len(val) for val in filter_values) - filter_maxlen = len(filter_attr) + val_maxlen + 2 - chunk_size = allowed_filter_len // filter_maxlen + val_maxlen = max(len(val) for val in filter_values) + filter_maxlen = len(filter_attr) + val_maxlen + 2 + chunk_size = allowed_filter_len // filter_maxlen - resources = [] - for i in range(0, len(filter_values), chunk_size): - params[filter_attr] = filter_values[i:i + chunk_size] - resources.extend(list_method(**params)) - return resources - - -def _get_excess(filter_len): - MAX_URI_LEN = 8192 - return filter_len - MAX_URI_LEN + resources = [] + for i in range(0, len(filter_values), chunk_size): + params[filter_attr] = filter_values[i:i + chunk_size] + resources.extend(list_method(**params)) + return resources @profiler.trace @@ -2058,28 +2059,27 @@ def router_static_route_add(request, router_id, newroute): @profiler.trace def tenant_quota_get(request, tenant_id): - return base.QuotaSet( - networkclient(request).get_quota(tenant_id).to_dict().pop('location')) + return base.QuotaSet(neutronclient(request).show_quota(tenant_id)['quota']) @profiler.trace def tenant_quota_update(request, tenant_id, **kwargs): - return networkclient(request).update_quota(tenant_id, **kwargs).to_dict() + quotas = {'quota': kwargs} + return neutronclient(request).update_quota(tenant_id, quotas) @profiler.trace def tenant_quota_detail_get(request, tenant_id=None): tenant_id = tenant_id or request.user.tenant_id - rsp = networkclient(request).get('/quotas/%s/details' % tenant_id) - return rsp.json()['quota'] + response = neutronclient(request).get('/quotas/%s/details' % tenant_id) + return response['quota'] @profiler.trace def default_quota_get(request, tenant_id=None): tenant_id = tenant_id or request.user.tenant_id - response = networkclient(request).get_quota_default(tenant_id).to_dict() - response.pop('location') - return base.QuotaSet(response) + response = neutronclient(request).show_quota_default(tenant_id) + return base.QuotaSet(response['quota']) @profiler.trace @@ -2273,7 +2273,7 @@ def servers_update_addresses(request, servers, all_tenants=False): networks = list_resources_with_long_filters( network_list, 'id', frozenset([port.network_id for port in ports]), request=request) - except sdk_exceptions.NotFoundException as e: + except neutron_exc.NotFound as e: LOG.error('Neutron resource does not exist. %s', e) return except Exception as e: diff --git a/openstack_dashboard/dashboards/admin/rbac_policies/forms.py b/openstack_dashboard/dashboards/admin/rbac_policies/forms.py index 4e9809e8b8..0072b39e07 100644 --- a/openstack_dashboard/dashboards/admin/rbac_policies/forms.py +++ b/openstack_dashboard/dashboards/admin/rbac_policies/forms.py @@ -15,7 +15,7 @@ import logging from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -145,7 +145,7 @@ class CreatePolicyForm(forms.SelfHandlingForm): msg = _('RBAC Policy was successfully created.') messages.success(request, msg) return rbac_policy - except sdk_exceptions.ConflictException: + except neutron_exc.OverQuotaClient: redirect = reverse('horizon:admin:rbac_policies:index') msg = _('RBAC Policy quota exceeded.') exceptions.handle(request, msg, redirect=redirect) diff --git a/openstack_dashboard/dashboards/project/floating_ip_portforwardings/views.py b/openstack_dashboard/dashboards/project/floating_ip_portforwardings/views.py index dba2b1110e..dc4a64eb1a 100644 --- a/openstack_dashboard/dashboards/project/floating_ip_portforwardings/views.py +++ b/openstack_dashboard/dashboards/project/floating_ip_portforwardings/views.py @@ -17,7 +17,7 @@ import logging from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import tables @@ -59,7 +59,7 @@ class IndexView(tables.DataTableView): "Manage floating IP port forwarding rules : " + str( floating_ip.ip)) return self.get_floating_ip_rules(floating_ip) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: exceptions.handle(self.request) except Exception: exceptions.handle( @@ -92,7 +92,7 @@ class AllRulesView(IndexView): def get_data(self): try: return self.get_all_floating_ip_rules() - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: exceptions.handle(self.request) except Exception: exceptions.handle( diff --git a/openstack_dashboard/dashboards/project/floating_ip_portforwardings/workflows.py b/openstack_dashboard/dashboards/project/floating_ip_portforwardings/workflows.py index 7259574470..a8027b8c91 100644 --- a/openstack_dashboard/dashboards/project/floating_ip_portforwardings/workflows.py +++ b/openstack_dashboard/dashboards/project/floating_ip_portforwardings/workflows.py @@ -16,7 +16,7 @@ from django.core.exceptions import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -228,7 +228,7 @@ class FloatingIpPortForwardingRuleCreationWorkflow(workflows.Workflow): param.update(**api_params) api_method(request, floating_ip_id, **param) - except sdk_exceptions.BadRequestException as ex: + except neutron_exc.Conflict as ex: msg = _('The requested instance port is already' ' associated with another floating IP.') LOG.exception(msg, ex) diff --git a/openstack_dashboard/dashboards/project/floating_ips/views.py b/openstack_dashboard/dashboards/project/floating_ips/views.py index b8f5aa5f13..e211181cd4 100644 --- a/openstack_dashboard/dashboards/project/floating_ips/views.py +++ b/openstack_dashboard/dashboards/project/floating_ips/views.py @@ -25,7 +25,7 @@ import logging from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -74,7 +74,7 @@ class AllocateView(forms.ModalFormView): def get_initial(self): try: pools = api.neutron.floating_ip_pools_list(self.request) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: pools = [] exceptions.handle(self.request) except Exception: @@ -96,7 +96,7 @@ class IndexView(tables.DataTableView): search_opts = self.get_filters() floating_ips = api.neutron.tenant_floating_ip_list(self.request, **search_opts) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: floating_ips = [] exceptions.handle(self.request) except Exception: @@ -107,7 +107,7 @@ class IndexView(tables.DataTableView): try: floating_ip_pools = \ api.neutron.floating_ip_pools_list(self.request) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: floating_ip_pools = [] exceptions.handle(self.request) except Exception: diff --git a/openstack_dashboard/dashboards/project/floating_ips/workflows.py b/openstack_dashboard/dashboards/project/floating_ips/workflows.py index 09c6e63712..c36d6ca13c 100644 --- a/openstack_dashboard/dashboards/project/floating_ips/workflows.py +++ b/openstack_dashboard/dashboards/project/floating_ips/workflows.py @@ -15,7 +15,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -88,7 +88,7 @@ class AssociateIPAction(workflows.Action): redirect = reverse('horizon:project:floating_ips:index') try: ips = api.neutron.tenant_floating_ip_list(self.request) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: exceptions.handle(self.request, redirect=redirect) except Exception: exceptions.handle(self.request, @@ -170,7 +170,7 @@ class IPAssociationWorkflow(workflows.Workflow): api.neutron.floating_ip_associate(request, data['ip_id'], data['port_id']) - except sdk_exceptions.ConflictException: + except neutron_exc.Conflict: msg = _('The requested instance port is already' ' associated with another floating IP.') exceptions.handle(request, msg) diff --git a/openstack_dashboard/dashboards/project/networks/subnets/tables.py b/openstack_dashboard/dashboards/project/networks/subnets/tables.py index 7c4aadf9ec..c99aeba4bc 100644 --- a/openstack_dashboard/dashboards/project/networks/subnets/tables.py +++ b/openstack_dashboard/dashboards/project/networks/subnets/tables.py @@ -14,7 +14,7 @@ import logging -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exceptions from django.urls import reverse from django.urls import reverse_lazy @@ -79,7 +79,7 @@ class DeleteSubnet(SubnetPolicyTargetMixin, tables.DeleteAction): # normal_log_message 'Failed to delete subnet %(id)s: %(exc)s', # target_exception - sdk_exceptions.ConflictException, + neutron_exceptions.Conflict, # target_log_message 'Unable to delete subnet %(id)s with 409 Conflict: %(exc)s', # target_user_message diff --git a/openstack_dashboard/dashboards/project/networks/tables.py b/openstack_dashboard/dashboards/project/networks/tables.py index 708db43f16..ebb651cf6f 100644 --- a/openstack_dashboard/dashboards/project/networks/tables.py +++ b/openstack_dashboard/dashboards/project/networks/tables.py @@ -19,7 +19,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exceptions from horizon import exceptions from horizon import tables @@ -63,7 +63,7 @@ class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction): # normal_log_message 'Failed to delete network %(id)s: %(exc)s', # target_exception - sdk_exceptions.ConflictException, + neutron_exceptions.Conflict, # target_log_message 'Unable to delete network %(id)s with 409 Conflict: %(exc)s', # target_user_message diff --git a/openstack_dashboard/dashboards/project/routers/extensions/extraroutes/forms.py b/openstack_dashboard/dashboards/project/routers/extensions/extraroutes/forms.py index ab1f312e35..d48a61b378 100644 --- a/openstack_dashboard/dashboards/project/routers/extensions/extraroutes/forms.py +++ b/openstack_dashboard/dashboards/project/routers/extensions/extraroutes/forms.py @@ -17,7 +17,7 @@ import logging from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -49,7 +49,7 @@ class AddRouterRoute(forms.SelfHandlingForm): msg = _('Static route added') messages.success(request, msg) return True - except sdk_exceptions.BadRequestException as e: + except neutron_exc.BadRequest as e: LOG.info('Invalid format for routes %(route)s: %(exc)s', {'route': route, 'exc': e}) msg = _('Invalid format for routes: %s') % e diff --git a/openstack_dashboard/dashboards/project/routers/tables.py b/openstack_dashboard/dashboards/project/routers/tables.py index 15afcd11e1..9a697aaa1c 100644 --- a/openstack_dashboard/dashboards/project/routers/tables.py +++ b/openstack_dashboard/dashboards/project/routers/tables.py @@ -19,7 +19,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exceptions from horizon import exceptions from horizon import tables @@ -57,7 +57,7 @@ class DeleteRouter(policy.PolicyTargetMixin, tables.DeleteAction): # normal_log_message 'Failed to delete router %(id)s: %(exc)s', # target_exception - sdk_exceptions.SDKException, + neutron_exceptions.NeutronClientException, # target_log_message 'Unable to delete router %(id)s: %(exc)s', # target_user_message @@ -151,7 +151,7 @@ class ClearGateway(policy.PolicyTargetMixin, tables.BatchAction): # normal_log_message 'Unable to clear gateway for router %(id)s: %(exc)s', # target_exception - sdk_exceptions.ConflictException, + neutron_exceptions.Conflict, # target_log_message 'Unable to clear gateway for router %(id)s: %(exc)s', # target_user_message diff --git a/openstack_dashboard/dashboards/project/security_groups/views.py b/openstack_dashboard/dashboards/project/security_groups/views.py index eb7f947e71..59fdcba9db 100644 --- a/openstack_dashboard/dashboards/project/security_groups/views.py +++ b/openstack_dashboard/dashboards/project/security_groups/views.py @@ -22,7 +22,7 @@ Views for managing instances. from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from openstack import exceptions as sdk_exceptions +from neutronclient.common import exceptions as neutron_exc from horizon import exceptions from horizon import forms @@ -183,7 +183,7 @@ class IndexView(tables.DataTableView): def get_data(self): try: security_groups = api.neutron.security_group_list(self.request) - except sdk_exceptions.SDKException: + except neutron_exc.ConnectionFailed: security_groups = [] exceptions.handle(self.request) except Exception: diff --git a/openstack_dashboard/exceptions.py b/openstack_dashboard/exceptions.py index 097d391faf..4e0b95c45c 100644 --- a/openstack_dashboard/exceptions.py +++ b/openstack_dashboard/exceptions.py @@ -19,8 +19,8 @@ from cinderclient import exceptions as cinderclient from glanceclient import exc as glanceclient from keystoneclient import exceptions as keystoneclient +from neutronclient.common import exceptions as neutronclient from novaclient import exceptions as novaclient -from openstack import exceptions as sdk_exceptions from requests import exceptions as requests from swiftclient import client as swiftclient @@ -30,7 +30,7 @@ UNAUTHORIZED = ( cinderclient.Unauthorized, novaclient.Unauthorized, glanceclient.HTTPUnauthorized, - sdk_exceptions.HttpException, + neutronclient.Unauthorized, ) @@ -39,7 +39,7 @@ NOT_FOUND = ( cinderclient.NotFound, novaclient.NotFound, glanceclient.HTTPNotFound, - sdk_exceptions.NotFoundException, + neutronclient.NotFound, ) @@ -56,8 +56,8 @@ RECOVERABLE = ( novaclient.Forbidden, glanceclient.HTTPException, glanceclient.CommunicationError, - sdk_exceptions.ForbiddenException, - sdk_exceptions.SDKException, + neutronclient.Forbidden, + neutronclient.NeutronClientException, swiftclient.ClientException, requests.RequestException, ) diff --git a/openstack_dashboard/test/selenium/ui/test_actions.py b/openstack_dashboard/test/selenium/ui/test_actions.py index 8bd361c58e..2f2229d9bf 100644 --- a/openstack_dashboard/test/selenium/ui/test_actions.py +++ b/openstack_dashboard/test/selenium/ui/test_actions.py @@ -23,8 +23,8 @@ def test_delete_multiple_instance_rows(live_server, driver, dashboard_data, mock.patch.object( api.nova, 'flavor_list') as mocked_f_l, \ mock.patch( - 'openstack.network.v2._proxy.Proxy.' - 'extensions') as mocked_l_e, \ + 'neutronclient.v2_0.client.Client' + '.list_extensions') as mocked_l_e, \ mock.patch.object( api.nova, 'tenant_absolute_limits') as mocked_t_a_l, \ mock.patch.object( diff --git a/openstack_dashboard/test/test_data/exceptions.py b/openstack_dashboard/test/test_data/exceptions.py index 6f92d8f92f..9defeb3e2e 100644 --- a/openstack_dashboard/test/test_data/exceptions.py +++ b/openstack_dashboard/test/test_data/exceptions.py @@ -15,8 +15,8 @@ from cinderclient import exceptions as cinder_exceptions import glanceclient.exc as glance_exceptions from keystoneclient import exceptions as keystone_exceptions +from neutronclient.common import exceptions as neutron_exceptions from novaclient import exceptions as nova_exceptions -from openstack import exceptions as sdk_exceptions from swiftclient import client as swift_exceptions from openstack_dashboard.test.test_data import utils @@ -67,7 +67,7 @@ def data(TEST): glance_exception = glance_exceptions.ClientException TEST.exceptions.glance = create_stubbed_exception(glance_exception) - neutron_exception = sdk_exceptions.SDKException + neutron_exception = neutron_exceptions.NeutronClientException TEST.exceptions.neutron = create_stubbed_exception(neutron_exception) swift_exception = swift_exceptions.ClientException diff --git a/openstack_dashboard/test/unit/api/test_neutron.py b/openstack_dashboard/test/unit/api/test_neutron.py index 922c0d256c..8de129523f 100644 --- a/openstack_dashboard/test/unit/api/test_neutron.py +++ b/openstack_dashboard/test/unit/api/test_neutron.py @@ -15,6 +15,7 @@ import copy from unittest import mock import netaddr +from neutronclient.common import exceptions as neutron_exc from openstack import exceptions as sdk_exceptions from openstack.network.v2 import port as sdk_port from openstack.network.v2 import subnet_pool as sdk_subnet_pool @@ -32,19 +33,19 @@ from openstack_dashboard.test.test_data import neutron_data class NeutronApiTests(test.APIMockTestCase): @mock.patch.object(api.neutron, 'networkclient') - def test_network_list(self, mock_networkclient): + def test_network_list(self, mock_neutronclient): networks = self.api_networks_sdk subnets = self.api_subnets_sdk - networkclient = mock_networkclient.return_value - networkclient.networks.return_value = networks - networkclient.subnets.return_value = subnets + neutronclient = mock_neutronclient.return_value + neutronclient.networks.return_value = networks + neutronclient.subnets.return_value = subnets ret_val = api.neutron.network_list(self.request) for n in ret_val: self.assertIsInstance(n, api.neutron.Network) - networkclient.networks.assert_called_once_with() - networkclient.subnets.assert_called_once_with() + neutronclient.networks.assert_called_once_with() + neutronclient.subnets.assert_called_once_with() @override_settings(OPENSTACK_NEUTRON_NETWORK={ 'enable_auto_allocated_network': True}) @@ -918,17 +919,17 @@ class NeutronApiTests(test.APIMockTestCase): subnet_id = self.api_networks_sdk[0]['subnets'][0] subnetv6_id = self.api_networks_sdk[0]['subnets'][1] - networkclient = mock_networkclient.return_value - networkclient.get_network.return_value = network - networkclient.get_subnet.side_effect = [subnet, subnetv6] + neutronclient = mock_networkclient.return_value + neutronclient.get_network.return_value = network + neutronclient.get_subnet.side_effect = [subnet, subnetv6] ret_val = api.neutron.network_get(self.request, network_id) self.assertIsInstance(ret_val, api.neutron.Network) self.assertEqual(2, len(ret_val['subnets'])) self.assertIsInstance(ret_val['subnets'][0], api.neutron.Subnet) - networkclient.get_network.assert_called_once_with(network_id) - networkclient.get_subnet.assert_has_calls([ + neutronclient.get_network.assert_called_once_with(network_id) + neutronclient.get_subnet.assert_has_calls([ mock.call(subnet_id), mock.call(subnetv6_id), ]) @@ -939,57 +940,57 @@ class NeutronApiTests(test.APIMockTestCase): network_id = self.api_networks_sdk[0]['id'] subnet_id = self.api_networks_sdk[0]['subnet_ids'][0] - networkclient = mock_networkclient.return_value - networkclient.get_network.return_value = network - networkclient.get_subnet.side_effect = sdk_exceptions.ResourceNotFound + neutronclient = mock_networkclient.return_value + neutronclient.get_network.return_value = network + neutronclient.get_subnet.side_effect = sdk_exceptions.ResourceNotFound ret_val = api.neutron.network_get(self.request, network_id) self.assertIsInstance(ret_val, api.neutron.Network) self.assertEqual(2, len(ret_val['subnet_ids'])) self.assertNotIsInstance(ret_val['subnet_ids'][0], api.neutron.Subnet) self.assertIsInstance(ret_val['subnet_ids'][0], str) - networkclient.get_network.assert_called_once_with(network_id) - networkclient.get_subnet.assert_called_once_with(subnet_id) + neutronclient.get_network.assert_called_once_with(network_id) + neutronclient.get_subnet.assert_called_once_with(subnet_id) @mock.patch.object(api.neutron, 'networkclient') def test_network_create(self, mock_networkclient): network = self.api_networks_sdk[0] form_data = {'name': 'net1', 'tenant_id': self.request.user.project_id} - networkclient = mock_networkclient.return_value - networkclient.create_network.return_value = network + neutronclient = mock_networkclient.return_value + neutronclient.create_network.return_value = network ret_val = api.neutron.network_create(self.request, name='net1') self.assertIsInstance(ret_val, api.neutron.Network) - networkclient.create_network.assert_called_once_with(**form_data) + neutronclient.create_network.assert_called_once_with(**form_data) @mock.patch.object(api.neutron, 'networkclient') def test_network_update(self, mock_networkclient): network = self.api_networks_sdk[0] network_id = self.api_networks_sdk[0]['id'] - networkclient = mock_networkclient.return_value + neutronclient = mock_networkclient.return_value form_data = {'name': 'net1'} - networkclient.update_network.return_value = network + neutronclient.update_network.return_value = network ret_val = api.neutron.network_update(self.request, network_id, name='net1') self.assertIsInstance(ret_val, api.neutron.Network) - networkclient.update_network.assert_called_once_with(network_id, + neutronclient.update_network.assert_called_once_with(network_id, **form_data) @mock.patch.object(api.neutron, 'networkclient') def test_network_delete(self, mock_networkclient): network_id = self.api_networks_sdk[0]['id'] - networkclient = mock_networkclient.return_value - networkclient.delete_network.return_value = None + neutronclient = mock_networkclient.return_value + neutronclient.delete_network.return_value = None api.neutron.network_delete(self.request, network_id) - networkclient.delete_network.assert_called_once_with(network_id) + neutronclient.delete_network.assert_called_once_with(network_id) @mock.patch.object(api.neutron, 'networkclient') def test_get_network_ip_availability(self, mock_networkclient): @@ -1028,27 +1029,27 @@ class NeutronApiTests(test.APIMockTestCase): def test_subnet_list(self, mock_networkclient): subnets = self.api_subnets_sdk - networkclient = mock_networkclient.return_value - networkclient.subnets.return_value = subnets + neutronclient = mock_networkclient.return_value + neutronclient.subnets.return_value = subnets ret_val = api.neutron.subnet_list(self.request) for n in ret_val: self.assertIsInstance(n, api.neutron.Subnet) - networkclient.subnets.assert_called_once_with() + neutronclient.subnets.assert_called_once_with() @mock.patch.object(api.neutron, 'networkclient') def test_subnet_get(self, mock_networkclient): subnet = self.api_subnets_sdk[0] subnet_id = self.api_subnets_sdk[0]['id'] - networkclient = mock_networkclient.return_value - networkclient.get_subnet.return_value = subnet + neutronclient = mock_networkclient.return_value + neutronclient.get_subnet.return_value = subnet ret_val = api.neutron.subnet_get(self.request, subnet_id) self.assertIsInstance(ret_val, api.neutron.Subnet) - networkclient.get_subnet.assert_called_once_with(subnet_id) + neutronclient.get_subnet.assert_called_once_with(subnet_id) @mock.patch.object(api.neutron, 'networkclient') def test_subnet_create(self, mock_networkclient): @@ -1060,13 +1061,13 @@ class NeutronApiTests(test.APIMockTestCase): 'ip_version': subnet_data['ip_version'], 'gateway_ip': subnet_data['gateway_ip']} - networkclient = mock_networkclient.return_value - networkclient.create_subnet.return_value = subnet_data + neutronclient = mock_networkclient.return_value + neutronclient.create_subnet.return_value = subnet_data ret_val = api.neutron.subnet_create(self.request, **params) self.assertIsInstance(ret_val, api.neutron.Subnet) - networkclient.create_subnet.assert_called_once_with(**params) + neutronclient.create_subnet.assert_called_once_with(**params) @mock.patch.object(api.neutron, 'networkclient') def test_subnet_update(self, mock_networkclient): @@ -1075,25 +1076,25 @@ class NeutronApiTests(test.APIMockTestCase): params = {'name': subnet_data['name'], 'gateway_ip': subnet_data['gateway_ip']} - networkclient = mock_networkclient.return_value - networkclient.update_subnet.return_value = subnet_data + neutronclient = mock_networkclient.return_value + neutronclient.update_subnet.return_value = subnet_data ret_val = api.neutron.subnet_update(self.request, subnet_id, **params) self.assertIsInstance(ret_val, api.neutron.Subnet) - networkclient.update_subnet.assert_called_once_with( + neutronclient.update_subnet.assert_called_once_with( subnet_id, **params) @mock.patch.object(api.neutron, 'networkclient') def test_subnet_delete(self, mock_networkclient): subnet_id = self.api_subnets_sdk[0]['id'] - networkclient = mock_networkclient.return_value - networkclient.delete_subnet.return_value = None + neutronclient = mock_networkclient.return_value + neutronclient.delete_subnet.return_value = None api.neutron.subnet_delete(self.request, subnet_id) - networkclient.delete_subnet.assert_called_once_with(subnet_id) + neutronclient.delete_subnet.assert_called_once_with(subnet_id) @mock.patch.object(api.neutron, 'networkclient') def test_subnetpool_list(self, mock_networkclient): @@ -1187,7 +1188,7 @@ class NeutronApiTests(test.APIMockTestCase): trunks = self.api_tp_trunks_sdk # list_extensions is decorated with memoized_with_request, so - # networkclient() is not called. We need to mock it separately. + # neutronclient() is not called. We need to mock it separately. mock_is_extension_supported.return_value = True # trunk network_client = mock_networkclient.return_value @@ -1739,10 +1740,7 @@ class NeutronApiTests(test.APIMockTestCase): self._test_get_router_ha_permission_with_policy_check(False) @mock.patch.object(api.neutron, 'networkclient') - @mock.patch.object(api.neutron, '_get_excess') - def test_list_resources_with_long_filters(self, - mock_excess, - mock_networkclient): + def test_list_resources_with_long_filters(self, mock_networkclient): # In this tests, port_list is called with id=[10 port ID] # filter. It generates about 40*10 char length URI. # Each port ID is converted to "id=&" in URI and @@ -1758,16 +1756,7 @@ class NeutronApiTests(test.APIMockTestCase): port_ids = tuple([port['id'] for port in ports]) network_client = mock_networkclient.return_value - 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 - + uri_len_exc = neutron_exc.RequestURITooLong(excess=220) list_ports_retval = [uri_len_exc] for i in range(0, 10, 4): list_ports_retval.append(ports[i:i + 4]) @@ -2050,7 +2039,9 @@ class NeutronApiSecurityGroupTests(test.APIMockTestCase): def setUp(self): super().setUp() + neutronclient = mock.patch.object(api.neutron, 'neutronclient').start() networkclient = mock.patch.object(api.neutron, 'networkclient').start() + self.qclient = neutronclient.return_value self.netclient = networkclient.return_value self.sg_dict = dict([(sg['id'], sg['name']) for sg in self.api_security_groups_sdk]) diff --git a/requirements.txt b/requirements.txt index f5ba70c78a..21dc565b14 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,6 @@ futurist>=1.2.0 # Apache-2.0 iso8601>=0.1.11 # MIT keystoneauth1>=4.3.1 # Apache-2.0 netaddr>=0.7.18 # BSD -openstacksdk>=4.5.0 # Apache-2.0 oslo.concurrency>=4.5.0 # Apache-2.0 oslo.config>=8.8.0 # Apache-2.0 oslo.i18n>=5.1.0 # Apache-2.0 @@ -26,6 +25,7 @@ Pillow>=9.1.0 # PIL License python-cinderclient>=8.0.0 # Apache-2.0 python-glanceclient>=2.8.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-swiftclient>=3.2.0 # Apache-2.0 PyYAML>=6.0 # MIT