# Copyright 2021 Red Hat, Inc.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import io

from oslo_utils import units
from tempest.common import utils
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest.scenario import manager

CONF = config.CONF


class ImageQuotaTest(manager.ScenarioTest):
    credentials = ['primary', 'system_admin']

    @classmethod
    def resource_setup(cls):
        super(ImageQuotaTest, cls).resource_setup()

        # Figure out and record the glance service id
        services = cls.os_system_admin.identity_services_v3_client.\
            list_services()
        glance_services = [x for x in services['services']
                           if x['name'] == 'glance']
        cls.glance_service_id = glance_services[0]['id']

        # Pre-create all the quota limits and record their IDs so we can
        # update them in-place without needing to know which ones have been
        # created and in which order.
        cls.limit_ids = {}

        try:
            cls.limit_ids['image_size_total'] = cls._create_limit(
                'image_size_total', 10)
            cls.limit_ids['image_stage_total'] = cls._create_limit(
                'image_stage_total', 10)
            cls.limit_ids['image_count_total'] = cls._create_limit(
                'image_count_total', 10)
            cls.limit_ids['image_count_uploading'] = cls._create_limit(
                'image_count_uploading', 10)
        except lib_exc.Forbidden:
            # If we fail to set limits, it means they are not
            # registered, and thus we will skip these tests once we
            # have our os_system_admin client and run
            # check_quotas_enabled().
            pass

    def setUp(self):
        super(ImageQuotaTest, self).setUp()
        self.created_images = []

    def create_image(self, data=None, **kwargs):
        """Wrapper that returns a test image."""

        if 'name' not in kwargs:
            name = data_utils.rand_name(
                prefix=CONF.resource_name_prefix,
                name=self.__name__ + "-image")
            kwargs['name'] = name

        params = dict(kwargs)
        if data:
            # NOTE: On glance v1 API, the data should be passed on
            # a header. Then here handles the data separately.
            params['data'] = data

        image = self.image_client.create_image(**params)
        # Image objects returned by the v1 client have the image
        # data inside a dict that is keyed against 'image'.
        if 'image' in image:
            image = image['image']
        self.created_images.append(image['id'])
        self.addCleanup(
            self.image_client.wait_for_resource_deletion,
            image['id'])
        self.addCleanup(
            test_utils.call_and_ignore_notfound_exc,
            self.image_client.delete_image, image['id'])
        return image

    def check_quotas_enabled(self):
        # Check to see if we should even be running these tests. Use
        # the presence of a registered limit that we recognize as an
        # indication.  This will be set up by the operator (or
        # devstack) if glance is configured to use/honor the unified
        # limits. If one is set, they must all be set, because glance
        # has a single all-or-nothing flag for whether or not to use
        # keystone limits. If anything, checking only one helps to
        # assert the assumption that, if enabled, they must all be at
        # least registered for proper operation.
        registered_limits = self.os_system_admin.identity_limits_client.\
            get_registered_limits()['registered_limits']
        if 'image_count_total' not in [x['resource_name']
                                       for x in registered_limits]:
            raise self.skipException('Target system is not configured with '
                                     'glance unified limits')

    @classmethod
    def _create_limit(cls, name, value):
        return cls.os_system_admin.identity_limits_client.create_limit(
            CONF.identity.region, cls.glance_service_id,
            cls.image_client.tenant_id, name, value)['limits'][0]['id']

    def _update_limit(self, name, value):
        self.os_system_admin.identity_limits_client.update_limit(
            self.limit_ids[name], value)

    def _cleanup_images(self):
        while self.created_images:
            image_id = self.created_images.pop()
            try:
                self.image_client.delete_image(image_id)
            except lib_exc.NotFound:
                pass

    @decorators.idempotent_id('9b74fe24-183b-41e6-bf42-84c2958a7be8')
    @utils.services('image', 'identity')
    def test_image_count_quota(self):
        self.check_quotas_enabled()

        # Set a quota on the number of images for our tenant to one.
        self._update_limit('image_count_total', 1)

        # Create one image
        image = self.create_image(name='first',
                                  container_format='bare',
                                  disk_format='raw',
                                  visibility='private')

        # Second image would put us over quota, so expect failure.
        self.assertRaises(lib_exc.OverLimit,
                          self.create_image,
                          name='second',
                          container_format='bare',
                          disk_format='raw',
                          visibility='private')

        # Update our limit to two.
        self._update_limit('image_count_total', 2)

        # Now the same create should succeed.
        self.create_image(name='second',
                          container_format='bare',
                          disk_format='raw',
                          visibility='private')

        # Third image would put us over quota, so expect failure.
        self.assertRaises(lib_exc.OverLimit,
                          self.create_image,
                          name='third',
                          container_format='bare',
                          disk_format='raw',
                          visibility='private')

        # Delete the first image to put us under quota.
        self.image_client.delete_image(image['id'])

        # Now the same create should succeed.
        self.create_image(name='third',
                          container_format='bare',
                          disk_format='raw',
                          visibility='private')

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()

    @decorators.idempotent_id('b103788b-5329-4aa9-8b0d-97f8733460db')
    @utils.services('image', 'identity')
    def test_image_count_uploading_quota(self):
        if not CONF.image_feature_enabled.import_image:
            skip_msg = (
                "%s skipped as image import is not available" % __name__)
            raise self.skipException(skip_msg)

        self.check_quotas_enabled()

        # Set a quota on the number of images we can have in uploading state.
        self._update_limit('image_stage_total', 10)
        self._update_limit('image_size_total', 10)
        self._update_limit('image_count_total', 10)
        self._update_limit('image_count_uploading', 1)

        file_content = data_utils.random_bytes(1 * units.Mi)

        # Create and stage an image
        image1 = self.create_image(name='first',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image1['id'],
                                           io.BytesIO(file_content))

        # Check that we can not stage another
        image2 = self.create_image(name='second',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file,
                          image2['id'], io.BytesIO(file_content))

        # ... nor upload directly
        image3 = self.create_image(name='third',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file,
                          image3['id'],
                          io.BytesIO(file_content))

        # Update our quota to make room
        self._update_limit('image_count_uploading', 2)

        # Now our upload should work
        self.image_client.store_image_file(image3['id'],
                                           io.BytesIO(file_content))

        # ...and because that is no longer in uploading state, we should be
        # able to stage our second image from above.
        self.image_client.stage_image_file(image2['id'],
                                           io.BytesIO(file_content))

        # Finish our import of image2
        self.image_client.image_import(image2['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image2['id'])

        # Set our quota back to one
        self._update_limit('image_count_uploading', 1)

        # Since image1 is still staged, we should not be able to upload
        # an image.
        image4 = self.create_image(name='fourth',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file,
                          image4['id'],
                          io.BytesIO(file_content))

        # Finish our import of image1 to make space in our uploading quota.
        self.image_client.image_import(image1['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image1['id'])

        # Make sure that freed up the one upload quota to complete our upload
        self.image_client.store_image_file(image4['id'],
                                           io.BytesIO(file_content))

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()

    @decorators.idempotent_id('05e8d064-c39a-4801-8c6a-465df375ec5b')
    @utils.services('image', 'identity')
    def test_image_size_quota(self):
        self.check_quotas_enabled()

        # Set a quota on the image size for our tenant to 1MiB, and allow ten
        # images.
        self._update_limit('image_size_total', 1)
        self._update_limit('image_count_total', 10)
        self._update_limit('image_count_uploading', 10)

        file_content = data_utils.random_bytes(1 * units.Mi)

        # Create and upload a 1MiB image.
        image1 = self.create_image(name='first',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.store_image_file(image1['id'],
                                           io.BytesIO(file_content))

        # Create and upload a second 1MiB image. This succeeds, but
        # after completion, we are over quota. Despite us being at
        # quota above, the initial quota check for the second
        # operation has no idea what the image size will be, and thus
        # uses delta=0. This will succeed because we're not
        # technically over-quota and have not asked for any more (this
        # is oslo.limit behavior). After the second operation,
        # however, we will be over-quota regardless of the delta and
        # subsequent attempts will fail. Because glance goes not
        # require an image size to be declared before upload, this is
        # really the best it can do without an API change.
        image2 = self.create_image(name='second',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.store_image_file(image2['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to upload a third 1MiB image. This should fail to
        # upload (but not create) because we are over quota.
        image3 = self.create_image(name='third',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file,
                          image3['id'], io.BytesIO(file_content))

        # Increase our size quota to 2MiB.
        self._update_limit('image_size_total', 2)

        # Now the upload of the already-created image is allowed, but
        # after completion, we are over quota again.
        self.image_client.store_image_file(image3['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to upload a fourth 1MiB image. This should
        # fail to upload (but not create) because we are over quota.
        image4 = self.create_image(name='fourth',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.store_image_file,
                          image4['id'], io.BytesIO(file_content))

        # Delete our first image to make space in our existing 2MiB quota.
        self.image_client.delete_image(image1['id'])

        # Now the upload of the already-created image is allowed.
        self.image_client.store_image_file(image4['id'],
                                           io.BytesIO(file_content))

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()

    @decorators.idempotent_id('fc76b8d9-aae5-46fb-9285-099e37f311f7')
    @utils.services('image', 'identity')
    def test_image_stage_quota(self):
        if not CONF.image_feature_enabled.import_image:
            skip_msg = (
                "%s skipped as image import is not available" % __name__)
            raise self.skipException(skip_msg)

        self.check_quotas_enabled()

        # Create a staging quota of 1MiB, allow 10MiB of active
        # images, and a total of ten images.
        self._update_limit('image_stage_total', 1)
        self._update_limit('image_size_total', 10)
        self._update_limit('image_count_total', 10)
        self._update_limit('image_count_uploading', 10)

        file_content = data_utils.random_bytes(1 * units.Mi)

        # Create and stage a 1MiB image.
        image1 = self.create_image(name='first',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image1['id'],
                                           io.BytesIO(file_content))

        # Create and stage a second 1MiB image. This succeeds, but
        # after completion, we are over quota.
        image2 = self.create_image(name='second',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.image_client.stage_image_file(image2['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to stage a third 1MiB image. This should fail to
        # stage (but not create) because we are over quota.
        image3 = self.create_image(name='third',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file,
                          image3['id'], io.BytesIO(file_content))

        # Make sure that even though we are over our stage quota, we
        # can still create and upload an image the regular way.
        image_upload = self.create_image(name='uploaded',
                                         container_format='bare',
                                         disk_format='raw',
                                         visibility='private')
        self.image_client.store_image_file(image_upload['id'],
                                           io.BytesIO(file_content))

        # Increase our stage quota to two MiB.
        self._update_limit('image_stage_total', 2)

        # Now the upload of the already-created image is allowed, but
        # after completion, we are over quota again.
        self.image_client.stage_image_file(image3['id'],
                                           io.BytesIO(file_content))

        # Create and attempt to stage a fourth 1MiB image. This should
        # fail to stage (but not create) because we are over quota.
        image4 = self.create_image(name='fourth',
                                   container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
        self.assertRaises(lib_exc.OverLimit,
                          self.image_client.stage_image_file,
                          image4['id'], io.BytesIO(file_content))

        # Finish our import of image1 to make space in our stage quota.
        self.image_client.image_import(image1['id'], method='glance-direct')
        waiters.wait_for_image_imported_to_stores(self.image_client,
                                                  image1['id'])

        # Now the upload of the already-created image is allowed.
        self.image_client.stage_image_file(image4['id'],
                                           io.BytesIO(file_content))

        # Delete all the images we created before the next test runs,
        # so that it starts with full quota.
        self._cleanup_images()
