From a5c6dc09774dca6470e829bc62405ed8292cff38 Mon Sep 17 00:00:00 2001 From: Chandan Kumar Date: Wed, 16 May 2018 09:08:30 +0000 Subject: [PATCH] Allow non admin users to upload image to glance * Currently only users having admin related permission, has the ability to upload image to glance which later used to set Image/ image_alt ref in tempest.conf. In order to make easier for non-admin user, this changes allow the same and if the user does not have permission to do the same, it will log an exception with the proper message as non-admin user can upload the image from CLI. * Fixed set_default_tempest_options method for image as it is giving AttributeError: 'ImageService' object has no attribute 'image_path because image_path is set in set_image_preferences which is called after service_class in main.py which leads to the above error. * Removed additional overrides image.http_image from roles Change-Id: I3ab32b6c5628281f55193291cd367dcdb76a5571 --- config_tempest/main.py | 8 ++-- config_tempest/services/image.py | 38 +++++++++---------- config_tempest/tests/services/test_image.py | 6 +-- ...in-user-upload-image-f2274cdec154a76b.yaml | 8 ++++ .../tasks/main.yaml | 2 +- .../tasks/generate-tempestconf.sh.j2 | 2 +- .../tasks/test-demo-user.yaml | 19 ---------- 7 files changed, 34 insertions(+), 49 deletions(-) create mode 100644 releasenotes/notes/allow-non-admin-user-upload-image-f2274cdec154a76b.yaml diff --git a/config_tempest/main.py b/config_tempest/main.py index a406fbe6..eb5e6c37 100755 --- a/config_tempest/main.py +++ b/config_tempest/main.py @@ -387,10 +387,10 @@ def config_tempest(**kwargs): flavors.create_tempest_flavors() image = services.get_service('image') - image.set_image_preferences(kwargs.get('create', False), - kwargs.get('image_path', C.DEFAULT_IMAGE), - kwargs.get('image_disk_format', - C.DEFAULT_IMAGE_FORMAT)) + conf.set('image', 'http_image', kwargs.get('image_path', C.DEFAULT_IMAGE)) + image.set_image_preferences(kwargs.get('image_disk_format', + C.DEFAULT_IMAGE_FORMAT), + kwargs.get('non_admin', False)) image.create_tempest_images(conf) has_neutron = services.is_service("network") diff --git a/config_tempest/services/image.py b/config_tempest/services/image.py index d9bdf10a..e1007514 100644 --- a/config_tempest/services/image.py +++ b/config_tempest/services/image.py @@ -29,26 +29,22 @@ class ImageService(VersionedService): super(ImageService, self).__init__(name, service_url, token, disable_ssl_validation, client) - self.allow_creation = False - self.image_path = "" - self.disk_format = "" - def set_image_preferences(self, allow_creation, image_path, disk_format): + def set_image_preferences(self, disk_format, non_admin): """Sets image prefferences. - :type allow_creation: boolean - :type image_path: string :type disk_format: string + :type non_admin: bool """ - self.allow_creation = allow_creation - self.image_path = image_path self.disk_format = disk_format + self.non_admin = non_admin def set_default_tempest_options(self, conf): # When cirros is the image, set validation.image_ssh_user to cirros. # The option is heavily used in CI and it's also usefull for refstack, # because we don't have to specify overrides. - if 'cirros' in self.image_path.rsplit('/')[-1]: + if 'cirros' in conf.get_defaulted('image', + 'http_image').rsplit('/')[-1]: conf.set('validation', 'image_ssh_user', 'cirros') def set_versions(self): @@ -63,9 +59,10 @@ class ImageService(VersionedService): :type conf: TempestConf object """ img_dir = os.path.join(conf.get("scenario", "img_dir")) + image_path = conf.get_defaulted('image', 'http_image') img_path = os.path.join(img_dir, - os.path.basename(self.image_path)) - name = self.image_path[self.image_path.rfind('/') + 1:] + os.path.basename(image_path)) + name = image_path[image_path.rfind('/') + 1:] if not os.path.exists(img_dir): try: os.makedirs(img_dir) @@ -77,13 +74,13 @@ class ImageService(VersionedService): if conf.has_option('compute', 'image_ref'): image_id = conf.get('compute', 'image_ref') image_id = self.find_or_upload_image(image_id, name, - image_source=self.image_path, + image_source=image_path, image_dest=img_path) alt_image_id = None if conf.has_option('compute', 'image_ref_alt'): alt_image_id = conf.get('compute', 'image_ref_alt') alt_image_id = self.find_or_upload_image(alt_image_id, alt_name, - image_source=self.image_path, + image_source=image_path, image_dest=img_path) conf.set('compute', 'image_ref', image_id) @@ -99,10 +96,6 @@ class ImageService(VersionedService): :type image_dest: string """ image = self._find_image(image_id, image_name) - if not image and not self.allow_creation: - raise Exception("Image '%s' not found, but resource creation" - " isn't allowed. Either use '--create' or provide" - " an existing image_ref" % image_name) if image: LOG.info("(no change) Found image '%s'", image['name']) @@ -143,15 +136,20 @@ class ImageService(VersionedService): :type name: string :type path: string """ - LOG.info("Uploading image '%s' from '%s'", name, os.path.abspath(path)) + LOG.info("Uploading image '%s' from '%s'", + name, os.path.abspath(path)) + if self.non_admin: + visibility = 'community' + else: + visibility = 'public' with open(path) as data: image = self.client.create_image(name=name, disk_format=self.disk_format, container_format='bare', - visibility="public") + visibility=visibility) self.client.store_image_file(image['id'], data) - return image + return image def _download_image(self, id, path): """Download image from glance. diff --git a/config_tempest/tests/services/test_image.py b/config_tempest/tests/services/test_image.py index f98bac26..7041b6a5 100644 --- a/config_tempest/tests/services/test_image.py +++ b/config_tempest/tests/services/test_image.py @@ -36,14 +36,14 @@ class TestImageService(BaseServiceTest): self.FAKE_URL, self.FAKE_TOKEN, disable_ssl_validation=False) - self.Service.allow_creation = False - self.Service.image_path = "my_path/my_image.qcow2" self.Service.disk_format = ".format" + self.Service.non_admin = False self.Service.client = self.FakeServiceClient() self.dir = "/img/" self.conf = TempestConf() self.conf.set("scenario", "img_dir", self.dir) + self.conf.set("image", "http_image", "my_image.qcow2") @mock.patch('config_tempest.services.image.ImageService' '.find_or_upload_image') @@ -68,7 +68,6 @@ class TestImageService(BaseServiceTest): image_source = format + "://any_random_url" image_dest = "my_dest" image_name = "my_image" - self.Service.allow_creation = True image_id = self.Service.find_or_upload_image( image_id=None, image_dest=image_dest, image_name=image_name, image_source=image_source) @@ -143,7 +142,6 @@ class TestImageService(BaseServiceTest): image_source = "ftp://any_random_url" image_dest = "place_on_disk" image_name = "my_image" - self.Service.allow_creation = True image_id = self.Service.find_or_upload_image( image_id=None, image_name=image_name, image_source=image_source, image_dest=image_dest) diff --git a/releasenotes/notes/allow-non-admin-user-upload-image-f2274cdec154a76b.yaml b/releasenotes/notes/allow-non-admin-user-upload-image-f2274cdec154a76b.yaml new file mode 100644 index 00000000..280e8652 --- /dev/null +++ b/releasenotes/notes/allow-non-admin-user-upload-image-f2274cdec154a76b.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Allow all users irrespective of Admin and non-admin to upload images to + glance and generate image_ref and image_ref_alt for compute. + - | + image.http_image name is set based on the image name passed or if not + passed is taken from the default one. diff --git a/roles/generate-tempestconf-file-cloud/tasks/main.yaml b/roles/generate-tempestconf-file-cloud/tasks/main.yaml index ed75bc68..4a218401 100644 --- a/roles/generate-tempestconf-file-cloud/tasks/main.yaml +++ b/roles/generate-tempestconf-file-cloud/tasks/main.yaml @@ -36,7 +36,7 @@ --create \ --os-cloud {{ cloud_user }} \ auth.tempest_roles Member \ - service_available.swift False \ + service_available.swift False args: chdir: "{{ tempestconf_src_relative_path }}" executable: /bin/bash diff --git a/roles/generate-tempestconf-file/tasks/generate-tempestconf.sh.j2 b/roles/generate-tempestconf-file/tasks/generate-tempestconf.sh.j2 index 54b1c655..2ed1284b 100644 --- a/roles/generate-tempestconf-file/tasks/generate-tempestconf.sh.j2 +++ b/roles/generate-tempestconf-file/tasks/generate-tempestconf.sh.j2 @@ -18,4 +18,4 @@ discover-tempest-config \ identity.uri $OS_AUTH_URL \ identity.admin_password $OS_PASSWORD \ service_available.swift False \ -{{ aditional_tempestconf_params }} \ +{{ aditional_tempestconf_params }} diff --git a/roles/generate-tempestconf-file/tasks/test-demo-user.yaml b/roles/generate-tempestconf-file/tasks/test-demo-user.yaml index c2d452a8..7bd1b9a7 100644 --- a/roles/generate-tempestconf-file/tasks/test-demo-user.yaml +++ b/roles/generate-tempestconf-file/tasks/test-demo-user.yaml @@ -19,22 +19,3 @@ with_items: - { name: "m1.nano", ram: 64 } - { name: "m1.micro", ram: 128 } - - - name: Download cirros image - get_url: - url: "{{ url_cirros_image }}" - dest: "{{ tempestconf_src_relative_path }}/etc/" - mode: 0660 - - - name: Create image and image alt for demo user - shell: | - set -x - openstack image create --os-cloud {{ cloud_admin }} \ - --disk-format qcow2 \ - --public \ - --file {{ tempestconf_src_relative_path }}/etc/{{ url_cirros_image | basename }} \ - {{ item }} - with_items: - - "{{ url_cirros_image | basename }}" - - '{{ url_cirros_image | basename }}_alt' -