Exemple #1
0
    def test_get_string(self):
        v1_string = '3.23'
        v1 = api_version_request.APIVersionRequest(v1_string)
        self.assertEqual(v1_string, v1.get_string())

        self.assertRaises(ValueError,
                          api_version_request.APIVersionRequest().get_string)
Exemple #2
0
        def decorator(f):
            obj_min_ver = api_version.APIVersionRequest(min_ver)
            if max_ver:
                obj_max_ver = api_version.APIVersionRequest(max_ver)
            else:
                obj_max_ver = api_version.APIVersionRequest()

            # Add to list of versioned methods registered
            func_name = f.__name__
            new_func = versioned_method.VersionedMethod(
                func_name, obj_min_ver, obj_max_ver, experimental, f)

            func_dict = getattr(cls, VER_METHOD_ATTR, {})
            if not func_dict:
                setattr(cls, VER_METHOD_ATTR, func_dict)

            func_list = func_dict.get(func_name, [])
            if not func_list:
                func_dict[func_name] = func_list
            func_list.append(new_func)
            # Ensure the list is sorted by minimum version (reversed)
            # so later when we work through the list in order we find
            # the method which has the latest version which supports
            # the version requested.
            # TODO(cyeoh): Add check to ensure that there are no overlapping
            # ranges of valid versions as that is ambiguous
            func_list.sort(reverse=True)

            return f
    def test_get_pools_by_volume_type(self, version, support_volume_type,
                                      mock_reject_invalid_filters,
                                      mock_get_pools):
        req = fakes.HTTPRequest.blank('/v3/%s/scheduler-stats/get_pools?'
                                      'volume_type=lvm' % fake.PROJECT_ID)
        mock_get_pools.return_value = [{
            'name': 'pool1',
            'capabilities': {
                'foo': 'bar'
            }
        }]
        req.api_version_request = api_version.APIVersionRequest(version)
        req.environ['cinder.context'] = self.ctxt
        res = self.controller.get_pools(req)

        expected = {'pools': [{'name': 'pool1'}]}

        filters = dict()
        if support_volume_type:
            filters = {'volume_type': 'lvm'}
        filters = webob.multidict.MultiDict(filters)
        mock_reject_invalid_filters.assert_called_once_with(
            self.ctxt, filters, 'pool', True)
        self.assertDictEqual(expected, res)
        mock_get_pools.assert_called_with(mock.ANY, filters=filters)
Exemple #4
0
def get_api_version(version):
    """Gets a ``APIVersionRequest`` instance.

    :param version: The microversion needed.
    :return: The ``APIVersionRequest`` instance.
    """
    return api_version.APIVersionRequest(version)
Exemple #5
0
    def test_version_comparisons(self):
        v1 = api_version_request.APIVersionRequest('2.0')
        v2 = api_version_request.APIVersionRequest('2.5')
        v3 = api_version_request.APIVersionRequest('5.23')
        v4 = api_version_request.APIVersionRequest('2.0')
        v_null = api_version_request.APIVersionRequest()

        self.assertTrue(v1 < v2)
        self.assertTrue(v1 <= v2)
        self.assertTrue(v3 > v2)
        self.assertTrue(v3 >= v2)
        self.assertTrue(v1 != v2)
        self.assertTrue(v1 == v4)
        self.assertTrue(v1 != v_null)
        self.assertTrue(v_null == v_null)
        self.assertFalse(v1 == '2.0')
Exemple #6
0
    def test_snapshot_show(self, max_ver, snapshot_get_by_id, volume_get_by_id,
                           snapshot_metadata_get):
        snapshot = {
            'id': UUID,
            'volume_id': fake.VOLUME_ID,
            'status': fields.SnapshotStatus.AVAILABLE,
            'volume_size': 100,
            'display_name': 'Default name',
            'display_description': 'Default description',
            'expected_attrs': ['metadata'],
            'group_snapshot_id': None,
        }
        ctx = context.RequestContext(fake.PROJECT_ID, fake.USER_ID, True)
        snapshot_obj = fake_snapshot.fake_snapshot_obj(ctx, **snapshot)
        fake_volume_obj = fake_volume.fake_volume_obj(ctx)
        snapshot_get_by_id.return_value = snapshot_obj
        volume_get_by_id.return_value = fake_volume_obj
        req = fakes.HTTPRequest.blank('/v3/snapshots/%s' % UUID)
        req.api_version_request = api_version.APIVersionRequest(max_ver)
        resp_dict = self.controller.show(req, UUID)

        self.assertIn('snapshot', resp_dict)
        self.assertEqual(UUID, resp_dict['snapshot']['id'])
        self.assertIn('updated_at', resp_dict['snapshot'])
        if max_ver == '3.14':
            self.assertIn('group_snapshot_id', resp_dict['snapshot'])
            self.assertNotIn('user_id', resp_dict['snapshot'])
        elif max_ver == '3.13':
            self.assertNotIn('group_snapshot_id', resp_dict['snapshot'])
            self.assertNotIn('user_id', resp_dict['snapshot'])
        elif max_ver == '3.41':
            self.assertIn('user_id', resp_dict['snapshot'])
Exemple #7
0
    def test_volume_creation_from_snapshot(self, max_ver, create, get_snapshot,
                                           volume_type_get, group_get):
        create.side_effect = stubs.stub_volume_api_create
        get_snapshot.side_effect = stubs.stub_snapshot_get
        volume_type_get.side_effect = stubs.stub_volume_type_get
        fake_group = {
            'id': fake.GROUP_ID,
            'group_type_id': fake.GROUP_TYPE_ID,
            'name': 'fake_group'
        }
        group_get.return_value = fake_group

        snapshot_id = fake.SNAPSHOT_ID
        vol = self._vol_in_request_body(snapshot_id=snapshot_id,
                                        group_id=fake.GROUP_ID)
        body = {"volume": vol}
        req = fakes.HTTPRequest.blank('/v3/volumes')
        req.api_version_request = api_version.APIVersionRequest(max_ver)
        res_dict = self.controller.create(req, body)
        ex = self._expected_vol_from_controller(
            snapshot_id=snapshot_id, req_version=req.api_version_request)
        self.assertEqual(ex, res_dict)

        context = req.environ['cinder.context']
        get_snapshot.assert_called_once_with(self.controller.volume_api,
                                             context, snapshot_id)

        kwargs = self._expected_volume_api_create_kwargs(
            stubs.stub_snapshot(snapshot_id),
            test_group=fake_group,
            req_version=req.api_version_request)
        create.assert_called_once_with(self.controller.volume_api, context,
                                       vol['size'], stubs.DEFAULT_VOL_NAME,
                                       stubs.DEFAULT_VOL_DESCRIPTION, **kwargs)
Exemple #8
0
    def test_get_all_messages_with_sort(self):
        self.create_message_for_tests()

        url = '/v3/messages?sort=event_id:asc'
        req = fakes.HTTPRequest.blank(url)
        req.method = 'GET'
        req.content_type = 'application/json'
        req.headers["OpenStack-API-Version"] = "volume 3.5"
        req.api_version_request = api_version.APIVersionRequest('3.5')
        req.environ['cinder.context'].is_admin = True

        res = self.controller.index(req)

        expect_result = [
            "VOLUME_VOLUME_001_002",
            "VOLUME_VOLUME_002_002",
            "VOLUME_VOLUME_003_002",
            "VOLUME_VOLUME_003_002",
        ]
        expect_result.sort()

        self.assertEqual(4, len(res['messages']))
        self.assertEqual(expect_result[0], res['messages'][0]['event_id'])
        self.assertEqual(expect_result[1], res['messages'][1]['event_id'])
        self.assertEqual(expect_result[2], res['messages'][2]['event_id'])
        self.assertEqual(expect_result[3], res['messages'][3]['event_id'])
Exemple #9
0
    def test_version_comparisons(self):
        v1 = api_version_request.APIVersionRequest('2.0')
        v2 = api_version_request.APIVersionRequest('2.5')
        v3 = api_version_request.APIVersionRequest('5.23')
        v4 = api_version_request.APIVersionRequest('2.0')
        v_null = api_version_request.APIVersionRequest()

        self.assertLess(v1, v2)
        self.assertLessEqual(v1, v2)
        self.assertGreater(v3, v2)
        self.assertGreaterEqual(v3, v2)
        self.assertNotEqual(v1, v2)
        self.assertEqual(v1, v4)
        self.assertNotEqual(v1, v_null)
        self.assertEqual(v_null, v_null)
        self.assertNotEqual('2.0', v1)
Exemple #10
0
    def test_matches_versioned_method(self):

        request = api_version_request.APIVersionRequest('2.0')

        self.assertRaises(exception.InvalidParameterValue,
                          request.matches_versioned_method,
                          'fake_method')
Exemple #11
0
    def test_get_all_messages_with_sort(self):
        self.create_message_for_tests()

        url = '/v3/messages?sort=event_id:asc'
        req = fakes.HTTPRequest.blank(url)
        req.method = 'GET'
        req.content_type = 'application/json'
        req.headers["OpenStack-API-Version"] = "volume 3.5"
        req.api_version_request = api_version.APIVersionRequest('3.5')
        req.environ['cinder.context'].is_admin = True

        res = self.controller.index(req)

        expect_result = [
            defined_messages.EventIds.UNKNOWN_ERROR,
            defined_messages.EventIds.UNABLE_TO_ALLOCATE,
            defined_messages.EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA,
            defined_messages.EventIds.ATTACH_READONLY_VOLUME
        ]
        expect_result.sort()

        self.assertEqual(4, len(res['messages']))
        self.assertEqual(expect_result[0], res['messages'][0]['event_id'])
        self.assertEqual(expect_result[1], res['messages'][1]['event_id'])
        self.assertEqual(expect_result[2], res['messages'][2]['event_id'])
        self.assertEqual(expect_result[3], res['messages'][3]['event_id'])
Exemple #12
0
    def test_volume_revert_update_status_failed(self, mock_volume, mock_update,
                                                mock_latest):
        fake_volume = self._fake_create_volume()
        fake_snapshot = self._fake_create_snapshot(fake_volume['id'])
        mock_volume.return_value = fake_volume
        mock_latest.return_value = fake_snapshot
        req = fakes.HTTPRequest.blank('/v3/volumes/%s/revert' %
                                      fake_volume['id'])
        req.headers = {
            'OpenStack-API-Version': 'volume %s' % REVERT_TO_SNAPSHOT_VERSION
        }
        req.api_version_request = api_version.APIVersionRequest(
            REVERT_TO_SNAPSHOT_VERSION)
        # update volume's status failed
        mock_update.side_effect = [False, True]

        self.assertRaises(webob.exc.HTTPConflict, self.controller.revert, req,
                          fake_volume['id'],
                          {'revert': {
                              'snapshot_id': fake_snapshot['id']
                          }})

        # update snapshot's status failed
        mock_update.side_effect = [True, False]

        self.assertRaises(webob.exc.HTTPConflict, self.controller.revert, req,
                          fake_volume['id'],
                          {'revert': {
                              'snapshot_id': fake_snapshot['id']
                          }})
Exemple #13
0
    def set_api_version_request(self, url):
        """Set API version request based on the request header information.

        Microversions starts with /v3, so if a client sends a request for
        version 1.0 or 2.0 with the /v3 endpoint, throw an exception.
        Sending a header with any microversion to a /v1 or /v2 endpoint will
        be ignored.
        Note that a microversion must be set for the legacy endpoints. This
        will appear as 1.0 and 2.0 for /v1 and /v2.
        """
        if API_VERSION_REQUEST_HEADER in self.headers and 'v3' in url:
            hdr_string = self.headers[API_VERSION_REQUEST_HEADER]
            # 'latest' is a special keyword which is equivalent to requesting
            # the maximum version of the API supported
            hdr_string_list = hdr_string.split(",")
            volume_version = None
            for hdr in hdr_string_list:
                if VOLUME_SERVICE in hdr:
                    service, volume_version = hdr.split()
                    break
            if not volume_version:
                raise exception.VersionNotFoundForAPIMethod(
                    version=volume_version)
            if volume_version == 'latest':
                self.api_version_request = api_version.max_api_version()
            else:
                self.api_version_request = api_version.APIVersionRequest(
                    volume_version)

                # Check that the version requested is within the global
                # minimum/maximum of supported API versions
                if not self.api_version_request.matches(
                        api_version.min_api_version(),
                        api_version.max_api_version()):
                    raise exception.InvalidGlobalAPIVersion(
                        req_ver=self.api_version_request.get_string(),
                        min_ver=api_version.min_api_version().get_string(),
                        max_ver=api_version.max_api_version().get_string())

        else:
            if 'v1' in url:
                self.api_version_request = api_version.legacy_api_version1()
            elif 'v2' in url:
                self.api_version_request = api_version.legacy_api_version2()
            else:
                self.api_version_request = api_version.APIVersionRequest(
                    api_version._MIN_API_VERSION)
Exemple #14
0
    def test_str(self, major, minor):
        request_input = '%s.%s' % (major, minor)
        request = api_version_request.APIVersionRequest(request_input)
        request_string = six.text_type(request)

        self.assertEqual(
            'API Version Request '
            'Major: %s, Minor: %s' % (major, minor), request_string)
Exemple #15
0
 def _fake_update_request(self, backup_id, version=mv.BACKUP_UPDATE):
     req = fakes.HTTPRequest.blank('/v3/%s/backups/%s/update' %
                                   (fake.PROJECT_ID, backup_id))
     req.environ['cinder.context'].is_admin = True
     req.headers['Content-Type'] = 'application/json'
     req.headers['OpenStack-API-Version'] = 'volume ' + version
     req.api_version_request = api_version.APIVersionRequest(version)
     return req
Exemple #16
0
 def test__set_log_invalid_level(self, level, exceptions):
     body = {'level': level}
     url = '/v3/%s/os-services/set-log' % fake.PROJECT_ID
     req = fakes.HTTPRequest.blank(url)
     req.api_version_request = api_version.APIVersionRequest("3.32")
     self.assertRaises(exceptions,
                       self.controller._set_log, req, self.context,
                       body=body)
Exemple #17
0
 def _fake_volumes_summary_request(self, version='3.12', all_tenant=False,
                                   is_admin=False):
     req_url = '/v3/volumes/summary'
     if all_tenant:
         req_url += '?all_tenants=True'
     req = fakes.HTTPRequest.blank(req_url, use_admin_context=is_admin)
     req.headers = {'OpenStack-API-Version': 'volume ' + version}
     req.api_version_request = api_version.APIVersionRequest(version)
     return req
Exemple #18
0
def create_snapshot_query_with_metadata(metadata_query_string,
                                        api_microversion):
    """Helper to create metadata querystring with microversion"""
    req = fakes.HTTPRequest.blank('/v3/snapshots?metadata=' +
                                  metadata_query_string)
    req.headers["OpenStack-API-Version"] = "volume " + api_microversion
    req.api_version_request = api_version.APIVersionRequest(api_microversion)

    return req
Exemple #19
0
 def test_volume_index_filter_by_group_id_in_unsupport_version(self):
     self._create_volume_with_consistency_group()
     req = fakes.HTTPRequest.blank(
         ("/v3/volumes?group_id=%s") % fake.CONSISTENCY_GROUP2_ID)
     req.headers["OpenStack-API-Version"] = "volume 3.9"
     req.api_version_request = api_version.APIVersionRequest('3.9')
     req.environ['cinder.context'] = self.ctxt
     res_dict = self.controller.index(req)
     volumes = res_dict['volumes']
     self.assertEqual(2, len(volumes))
Exemple #20
0
 def test_volume_index_filter_by_glance_metadata_in_unsupport_version(self):
     self._create_volume_with_glance_metadata()
     req = fakes.HTTPRequest.blank("/v3/volumes?glance_metadata="
                                   "{'image_name': 'imageTestOne'}")
     req.headers["OpenStack-API-Version"] = "volume 3.0"
     req.api_version_request = api_version.APIVersionRequest('3.0')
     req.environ['cinder.context'] = self.ctxt
     res_dict = self.controller.index(req)
     volumes = res_dict['volumes']
     self.assertEqual(2, len(volumes))
Exemple #21
0
    def test_versions_response_fault(self):
        version = '3.0'
        req = self.build_request(header_version=version)
        req.api_version_request = (
            api_version_request.APIVersionRequest(version))

        app = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='what?'))
        response = req.get_response(app)

        self.assertEqual(HTTPStatus.BAD_REQUEST, response.status_int)
        self.check_response(response, '3.0')
Exemple #22
0
 def _get_resp_create(self, body, version='3.0'):
     url = '/v3/%s/os-volume-manage' % fake.PROJECT_ID
     req = webob.Request.blank(url, base_url='http://localhost.com' + url)
     req.method = 'POST'
     req.headers['Content-Type'] = 'application/json'
     req.environ['cinder.context'] = self._admin_ctxt
     req.body = jsonutils.dump_as_bytes(body)
     req.headers = {'OpenStack-API-Version': 'volume %s' % version}
     req.api_version_request = api_version.APIVersionRequest(version)
     res = self.controller.create(req, body)
     return res
Exemple #23
0
 def _get_resp_post_v3(self, body, version):
     """Helper to execute a POST os-volume-manage API call."""
     req = webob.Request.blank('/v3/%s/os-volume-manage' % fake.PROJECT_ID)
     req.method = 'POST'
     req.headers['Content-Type'] = 'application/json'
     req.environ['cinder.context'] = self._admin_ctxt
     req.headers["OpenStack-API-Version"] = "volume " + version
     req.api_version_request = api_version.APIVersionRequest(version)
     req.body = jsonutils.dump_as_bytes(body)
     res = req.get_response(app_v3())
     return res
Exemple #24
0
 def test_copy_volume_to_image_public_not_authorized(self):
     """Test unauthorized create public image from volume."""
     id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
     req = fakes.HTTPRequest.blank('/v3/tenant1/volumes/%s/action' % id)
     req.environ['cinder.context'].is_admin = False
     req.headers = {'OpenStack-API-Version': 'volume 3.1'}
     req.api_version_request = api_version.APIVersionRequest('3.1')
     body = self._get_os_volume_upload_image()
     body['os-volume_upload_image']['visibility'] = 'public'
     self.assertRaises(exception.PolicyNotAuthorized,
                       self.controller._volume_upload_image, req, id, body)
Exemple #25
0
 def test_volume_index_filter_by_group_id(self):
     vols = self._create_volume_with_group()
     req = fakes.HTTPRequest.blank(
         ("/v3/volumes?group_id=%s") % fake.GROUP_ID)
     req.headers["OpenStack-API-Version"] = "volume 3.10"
     req.api_version_request = api_version.APIVersionRequest('3.10')
     req.environ['cinder.context'] = self.ctxt
     res_dict = self.controller.index(req)
     volumes = res_dict['volumes']
     self.assertEqual(1, len(volumes))
     self.assertEqual(vols[0].id, volumes[0]['id'])
Exemple #26
0
    def test_get_limit_with_project_id(self, ver_project, mock_get_quotas):
        max_ver, has_project = ver_project
        req = fakes.HTTPRequest.blank('/v3/limits', use_admin_context=True)
        if has_project:
            req = fakes.HTTPRequest.blank('/v3/limits?project_id=%s' %
                                          fake.UUID1,
                                          use_admin_context=True)
        req.api_version_request = api_version.APIVersionRequest(max_ver)

        def get_project_quotas(context,
                               project_id,
                               quota_class=None,
                               defaults=True,
                               usages=True):
            if project_id == fake.UUID1:
                return {"gigabytes": {'limit': 5}}
            return {"gigabytes": {'limit': 10}}

        mock_get_quotas.side_effect = get_project_quotas

        resp_dict = self.controller.index(req)
        # if admin, only LIMITS_FILTER and req contains project_id filter,
        # cinder returns the specified project's quota.
        if max_ver == LIMITS_FILTER and has_project:
            self.assertEqual(
                5, resp_dict['limits']['absolute']['maxTotalVolumeGigabytes'])
        else:
            self.assertEqual(
                10, resp_dict['limits']['absolute']['maxTotalVolumeGigabytes'])

        # if non-admin, cinder always returns self quota.
        req = fakes.HTTPRequest.blank('/v3/limits', use_admin_context=False)
        if has_project:
            req = fakes.HTTPRequest.blank('/v3/limits?project_id=%s' %
                                          fake.UUID1,
                                          use_admin_context=False)
        req.api_version_request = api_version.APIVersionRequest(max_ver)
        resp_dict = self.controller.index(req)

        self.assertEqual(
            10, resp_dict['limits']['absolute']['maxTotalVolumeGigabytes'])
Exemple #27
0
 def __init__(self, is_admin=True, version=mv.CLUSTER_SUPPORT, **kwargs):
     self.GET = kwargs
     self.headers = {'OpenStack-API-Version': 'volume ' + version}
     self.api_version_request = api_version.APIVersionRequest(version)
     self.environ = {
         'cinder.context':
         context.RequestContext(user_id=None,
                                project_id=None,
                                is_admin=is_admin,
                                read_deleted='no',
                                overwrite=False)
     }
Exemple #28
0
    def test_get_all_messages_with_limit_and_offset(self):
        self.create_message_for_tests()

        url = '/v3/messages?limit=2&offset=1'
        req = fakes.HTTPRequest.blank(url)
        req.method = 'GET'
        req.content_type = 'application/json'
        req.headers["OpenStack-API-Version"] = "volume 3.5"
        req.api_version_request = api_version.APIVersionRequest('3.5')
        req.environ['cinder.context'].is_admin = True

        res = self.controller.index(req)
        self.assertEqual(2, len(res['messages']))
Exemple #29
0
    def test_get_all_messages_with_filter(self):
        self.create_message_for_tests()

        url = ('/v3/messages?' 'event_id=%s') % defined_messages.UNKNOWN_ERROR
        req = fakes.HTTPRequest.blank(url)
        req.method = 'GET'
        req.content_type = 'application/json'
        req.headers["OpenStack-API-Version"] = "volume 3.5"
        req.api_version_request = api_version.APIVersionRequest('3.5')
        req.environ['cinder.context'].is_admin = True

        res = self.controller.index(req)
        self.assertEqual(1, len(res['messages']))
Exemple #30
0
    def test_versions_response_fault(self, version):
        req = self.build_request(header_version=version)
        req.api_version_request = (
            api_version_request.APIVersionRequest(version))

        app = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='what?'))
        response = req.get_response(app)

        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
        if version == '3.0':
            self.check_response(response, '3.0')
        else:
            self.assertNotIn(VERSION_HEADER_NAME, response.headers)