diff --git a/ci/roles/image/tasks/main.yml b/ci/roles/image/tasks/main.yml index 2158b1fb..243f3944 100644 --- a/ci/roles/image/tasks/main.yml +++ b/ci/roles/image/tasks/main.yml @@ -25,8 +25,8 @@ - name: Verify image info assert: that: - - "image_info_result.openstack_image.name == image_name" - - "image_info_result.openstack_image.tags | sort == image_tags | sort" + - "image_info_result.openstack_images[0].name == image_name" + - "image_info_result.openstack_images[0].tags | sort == image_tags | sort" - name: Delete raw image (defaults) openstack.cloud.image: @@ -71,4 +71,4 @@ - name: Verify image is deleted assert: that: - - not deleted_image_info_result.openstack_image \ No newline at end of file + - not deleted_image_info_result.openstack_images diff --git a/ci/roles/image_info/defaults/main.yml b/ci/roles/image_info/defaults/main.yml new file mode 100644 index 00000000..639b60cb --- /dev/null +++ b/ci/roles/image_info/defaults/main.yml @@ -0,0 +1,23 @@ +expected_fields: + - checksum + - container_format + - created_at + - direct_url + - disk_format + - file + - id + - locations + - metadata + - min_disk + - min_ram + - name + - os_hidden + - owner + - properties + - schema + - size + - status + - tags + - updated_at + - virtual_size + - visibility diff --git a/ci/roles/image_info/tasks/main.yml b/ci/roles/image_info/tasks/main.yml new file mode 100644 index 00000000..415572c4 --- /dev/null +++ b/ci/roles/image_info/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: List all images # This will list at least the default cirros image of devstack + openstack.cloud.image_info: + cloud: "{{ cloud }}" + register: image_list_result + +- name: Assert fields + assert: + that: + - item in image_list_result.openstack_images.0.keys() + loop: "{{ expected_fields }}" diff --git a/ci/run-collection.yml b/ci/run-collection.yml index d5ba8ba0..6579eeb3 100644 --- a/ci/run-collection.yml +++ b/ci/run-collection.yml @@ -22,6 +22,7 @@ - { role: identity_role, tags: identity_role } - { role: identity_role_info, tags: identity_role_info } - { role: image, tags: image } + - { role: image_info, tags: image_info } - { role: keypair, tags: keypair } - { role: keystone_domain, tags: keystone_domain } - role: keystone_mapping diff --git a/plugins/modules/image_info.py b/plugins/modules/image_info.py index 08f9f201..f02079c0 100644 --- a/plugins/modules/image_info.py +++ b/plugins/modules/image_info.py @@ -4,6 +4,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) DOCUMENTATION = ''' +--- module: image_info short_description: Retrieve information about an image within OpenStack. author: OpenStack Ansible SIG @@ -17,11 +18,12 @@ options: - Name or ID of the image required: false type: str - properties: + filters: description: - Dict of properties of the images used for query type: dict required: false + aliases: ['properties'] requirements: - "python >= 3.6" - "openstacksdk" @@ -43,7 +45,7 @@ EXAMPLES = ''' - name: Show openstack information debug: - msg: "{{ result.openstack_image }}" + msg: "{{ result.image }}" # Show all available Openstack images - name: Retrieve all available Openstack images @@ -52,22 +54,22 @@ EXAMPLES = ''' - name: Show images debug: - msg: "{{ result.openstack_image }}" + msg: "{{ result.image }}" # Show images matching requested properties - name: Retrieve images having properties with desired values openstack.cloud.image_facts: - properties: + filters: some_property: some_value OtherProp: OtherVal - name: Show images debug: - msg: "{{ result.openstack_image }}" + msg: "{{ result.image }}" ''' RETURN = ''' -openstack_image: +openstack_images: description: has all the openstack information about the image returned: always, but can be null type: complex @@ -92,6 +94,10 @@ openstack_image: description: Container format of the image. returned: success type: str + direct_url: + description: URL to access the image file kept in external store. + returned: success + type: str min_ram: description: Min amount of RAM required for this image. returned: success @@ -100,19 +106,39 @@ openstack_image: description: Disk format of the image. returned: success type: str + file: + description: The URL for the virtual machine image file. + returned: success + type: str + os_hidden: + description: Controls whether an image is displayed in the default image-list response + returned: success + type: bool + locations: + description: A list of URLs to access the image file in external store. + returned: success + type: str + metadata: + description: The location metadata. + returned: success + type: str + schema: + description: URL for the schema describing a virtual machine image. + returned: success + type: str updated_at: description: Image updated at timestamp. returned: success type: str - properties: - description: Additional properties associated with the image. + virtual_size: + description: The virtual size of the image. returned: success - type: dict + type: str min_disk: description: Min amount of disk space required for this image. returned: success type: int - protected: + is_protected: description: Image protected flag. returned: success type: bool @@ -124,10 +150,10 @@ openstack_image: description: Owner for the image. returned: success type: str - is_public: - description: Is public flag of the image. + visibility: + description: Indicates who has access to the image. returned: success - type: bool + type: str size: description: Size of the image. returned: success @@ -137,7 +163,6 @@ openstack_image: returned: success type: list ''' - from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule @@ -147,20 +172,27 @@ class ImageInfoModule(OpenStackModule): argument_spec = dict( image=dict(type='str', required=False), - properties=dict(type='dict', required=False), + filters=dict(type='dict', required=False, aliases=['properties']), ) module_kwargs = dict( supports_check_mode=True ) def run(self): + args = { + 'name_or_id': self.params['image'], + 'filters': self.params['filters'], + } + args = {k: v for k, v in args.items() if v is not None} + images = self.conn.search_images(**args) - if self.params['image']: - image = self.conn.get_image(self.params['image']) - self.exit(changed=False, openstack_image=image) + # for backward compatibility + if 'name_or_id' in args: + image = images[0] if images else None else: - images = self.conn.search_images(filters=self.params['properties']) - self.exit(changed=False, openstack_image=images) + image = images + + self.exit(changed=False, openstack_images=images, image=image) def main():