diff --git a/meta/runtime.yml b/meta/runtime.yml index 37b31cd..3c02f8f 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -6,6 +6,11 @@ action_groups: - bare_metal - block_storage - block_storage_info + - container_registry + - container_registry_info + - container_registry_region_info + - container_registry_repository + - container_registry_repository_info - dns_domain - dns_domain_info - dns_record @@ -19,6 +24,7 @@ action_groups: - object_storage_cluster_info - object_storage_info - os_info + - plan_container_registry_info - plan_info - plan_metal_info - region_info diff --git a/plugins/module_utils/vultr_v2.py b/plugins/module_utils/vultr_v2.py index cc284dc..cb5ac2f 100644 --- a/plugins/module_utils/vultr_v2.py +++ b/plugins/module_utils/vultr_v2.py @@ -80,6 +80,7 @@ def __init__( resource_create_param_keys=None, resource_update_param_keys=None, resource_update_method="PATCH", + response_in_list=True, ): self.module = module self.namespace = namespace @@ -96,7 +97,7 @@ def __init__( # The name key of the resource, usually 'name' self.resource_key_name = resource_key_name - # The name key of the resource, usually 'id' + # The id key of the resource, usually 'id' self.resource_key_id = resource_key_id # Some resources need an additional GET request to get all attributes @@ -111,6 +112,9 @@ def __init__( # Some resources have PUT, many have PATCH self.resource_update_method = resource_update_method + # Some resources return objects as the top level, not in an array + self.response_in_list = response_in_list + self.result = { "changed": False, namespace: dict(), @@ -237,8 +241,9 @@ def query_filter_list_by_name( get_details=False, fail_not_found=False, skip_transform=True, + param_value=None, ): - param_value = self.module.params.get(param_key or key_name) + param_value = param_value or self.module.params.get(param_key or key_name) found = dict() for resource in self.query_list(path=path, result_key=result_key, query_params=query_params): @@ -275,7 +280,7 @@ def query_filter_list_by_name( return dict() def query_filter_list(self): - # Returns a single dict representing the resource queryied by name + # Returns a single dict representing the resource queried by name return self.query_filter_list_by_name( key_name=self.resource_key_name, key_id=self.resource_key_id, @@ -295,10 +300,14 @@ def query_by_id(self, resource_id=None, path=None, result_key=None, skip_transfo ) if resource: - if skip_transform: - return resource[result_key] - else: + if self.response_in_list: + if skip_transform: + return resource[result_key] return self.transform_resource(resource[result_key]) + else: + if skip_transform: + return resource + return self.transform_resource(resource) return dict() @@ -316,6 +325,7 @@ def query_list(self, path=None, result_key=None, query_params=None): query_params=query_params, result_key=result_key, ) + return resources[result_key] if resources else [] def wait_for_state(self, resource, key, states, cmp="=", retries=60, skip_wait=False): @@ -370,7 +380,10 @@ def create(self): method="POST", data=data, ) - return resource.get(self.ressource_result_key_singular) if resource else dict() + + if self.response_in_list: + return resource.get(self.ressource_result_key_singular) if resource else dict() + return resource if resource else dict() def is_diff(self, param, resource): value = self.module.params.get(param) diff --git a/plugins/modules/container_registry.py b/plugins/modules/container_registry.py new file mode 100644 index 0000000..1bb7b46 --- /dev/null +++ b/plugins/modules/container_registry.py @@ -0,0 +1,439 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: container_registry +short_description: Manages container registries on Vultr +version_added: "1.15.0" +description: + - Manage container registries +author: + - "jasites (@jasites)" +options: + name: + description: + - Name of container registry + required: true + type: str + public: + description: + - If true, container images can be pulled from repositories in this registry without authentication + - Required for creation + - Can be updated + type: bool + region: + description: + - Region in which to deploy the container registry + - Required for creation + type: str + plan: + description: + - Name of the plan to use for the container registry + - Required for creation + - Can be updated + type: str + state: + description: + - State of the container registry + default: present + choices: [ present, absent ] + type: str +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Ensure a container registry is present + vultr.cloud.container_registry: + name: myregistry + plan: start_up + public: true + region: ewr + +- name: Ensure a container registry is absent + vultr.cloud.container_registry: + name: myregistry + state: absent +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_container_registry: + description: Response from Vultr API. + returned: success + type: dict + contains: + id: + description: UUID of the registry. + returned: success + type: str + sample: 36f91844-b6d2-4e80-8fe0-bca5015d27cf + name: + description: Name of registry + returned: success + type: str + sample: myregistry + urn: + description: URN (URL without connection scheme, i.e., 'https://') for this registry + returned: success + type: str + sample: sjc.vultrcr.com/my-registry + storage: + description: Used and allowed storage metrics for this registry + returned: success + type: dict + contains: + used: + description: Currently consumed storage capacity for this registry + returned: success + type: dict + contains: + updated_at: + description: Date at which storage usage was last updated + returned: success + type: str + sample: 2024-11-26 18:16:08 + bytes: + description: Capacity consumed by this registry expressed in bytes + returned: success + type: float + sample: 4194304 + mb: + description: Capacity consumed by this registry expressed in megabytes + returned: success + type: float + sample: 4 + gb: + description: Capacity consumed by this registry expressed in gigabytes + returned: success + type: float + sample: 0 + tb: + description: Capacity consumed by this registry expressed in terabytes + returned: success + type: float + sample: 0 + allowed: + description: Capacity allowed to be consumed by the current plan selected for this registry + returned: success + type: dict + contains: + bytes: + description: Capacity allowed to be consumed by this registry expressed in bytes + returned: success + type: float + sample: 10737418240 + mb: + description: Capacity allowed to be consumed by this registry expressed in megabytes + returned: success + type: float + sample: 10240 + gb: + description: Capacity allowed to be consumed by this registry expressed in gigabytes + returned: success + type: float + sample: 10 + tb: + description: Capacity allowed to be consumed by this registry expressed in terabytes + returned: success + type: float + sample: 0.01 + date_created: + description: Date on which this registry was created + returned: success + type: str + sample: 2024-11-26 13:16:07 + public: + description: True if this registry does not require authentication to pull from child repositories. + returned: success + type: bool + root_user: + description: Information concerning the root user of this registry + returned: success + type: dict + contains: + id: + description: Numeric ID of this user. + returned: success + type: int + sample: 48747 + username: + description: Globally unique username for the root user + returned: success + type: str + sample: d4518e8f-a495-40eb-86c7-95430522998d + password: + description: Password to be used by the root user to authenticate to this registry + returned: success + type: str + sample: 00example1122334455667788990011 + root: + description: True if this user cannot be deleted or renamed + returned: success + type: str + added_at: + description: Date on which this user was added to this registry + returned: success + type: str + sample: 2024-11-26 13:16:07 + updated_at: + description: Date on which this user was last updated + returned: success + type: str + sample: 2024-11-26 13:16:07 + metadata: + description: Information regarding the subscription associated with this registry + returned: success + type: dict + contains: + region: + description: Information regarding the region in which this registry was deployed + returned: success + type: dict + contains: + id: + description: ID of the region. + returned: success + type: int + sample: 3 + name: + description: Region name + returned: success + type: str + sample: sjc + urn: + description: Base URN (URL without connection scheme, i.e., 'https://') for this region + returned: success + type: str + sample: sjc.vultrcr.com + base_url: + description: Base URL for registries deployed to this region + returned: success + type: str + sample: https://sjc.vultrcr.com + public: + description: True if this region is generally available for new registries to be created + returned: success + type: bool + added_at: + description: Date of when this region was added + returned: success + type: str + sample: 2023-09-14 09:09:16 + updated_at: + description: Date of when this region was last updated + returned: success + type: str + sample: 2023-09-14 09:09:16 + data_center: + description: Additional details regarding this region + returned: success + type: dict + contains: + id: + description: ID of this data center + returned: success + type: int + sample: 12 + name: + description: Name of data center + returned: success + type: str + sample: Silicon Valley + site_code: + description: Code used to differentiate data centers within a region + returned: success + type: str + sample: SJC2 + region: + description: Geographical description of the placement of this data center within the region + returned: success + type: str + sample: West + country: + description: Two letter country code (ISO 3166-1 alpha-2) of country containing this data center + returned: success + type: str + sample: US + continent: + description: Continent containing this data center + returned: success + type: str + sample: North America + description: + description: Additional descriptive data for this data center + returned: success + type: str + sample: Silicon Valley, California + airport: + description: IATA airport code + returned: success + type: str + sample: SJC + subscription: + description: Information pertaining directly to the subscription itself + returned: success + type: dict + contains: + billing: + description: Billing information for this subscription + returned: success + type: dict + contains: + monthly_price: + description: Monthly price of this subscription + returned: success + type: float + pending_charges: + description: Pending charges for this subscription + returned: success + type: float +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.common.dict_transformations import dict_merge + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +class AnsibleVultrContainerRegistry(AnsibleVultr): + def transform_resource(self, resource): + resource["region"] = resource["metadata"]["region"]["name"] + resource["plan"] = self.get_plan_id_by_max_storage_mb( + resource["storage"]["allowed"]["mb"], + self.get_plan_list(), + ) + + return resource + + def query_list(self, path=None, result_key=None, query_params=None): + self.response_in_list = True + result = super(AnsibleVultrContainerRegistry, self).query_list( + path="/registries", + result_key=result_key, + query_params=query_params, + ) + + # reset property + self.response_in_list = False + return result + + def update(self, resource): + plans = self.get_plan_list() + current_plan = resource["plan"] + desired_plan = self.module.params["plan"] + if desired_plan != current_plan: + current_limit = self.get_plan_max_storage_mb_by_id(plan_id=current_plan, plans=plans) + desired_limit = self.get_plan_max_storage_mb_by_id(plan_id=desired_plan, plans=plans) + if desired_limit < current_limit: + self.module.params["plan"] = current_plan + self.module.warn( + "Shrinking plans is not supported: current plan %s, desired plan %s" + % (current_plan, desired_plan) + ) + + return super(AnsibleVultrContainerRegistry, self).update(resource=resource) + + def get_plan_list(self): + result = [] + plans = self.api_query(path="/registry/plan/list").get("plans", {}) + if plans: + for plan in plans.keys(): + result.append(dict_merge(dict(id=plan), plans.get(plan, {}))) + return result + + def get_plan_max_storage_mb_by_id(self, plan_id=None, plans=None): + for plan in plans: + if plan_id == plan.get("id", ""): + return plan.get("max_storage_mb", 0) + return 0 + + def get_plan_id_by_max_storage_mb(self, max_mb=None, plans=None): + for plan in plans: + if max_mb == plan.get("max_storage_mb", 0): + return plan.get("id", "") + return "" + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + name=dict(type="str", required=True), + public=dict(type="bool"), + region=dict(type="str"), + plan=dict(type="str"), + state=dict(type="str", choices=["present", "absent"], default="present"), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + required_if=[ + ("state", "present", ["public", "region", "plan"]), + ], + supports_check_mode=True, + ) + + vultr = AnsibleVultrContainerRegistry( + module=module, + namespace="vultr_container_registry", + resource_path="/registry", + resource_create_param_keys=["name", "public", "region", "plan"], + resource_key_name="name", + resource_update_method="PUT", + resource_update_param_keys=["public", "plan"], + ressource_result_key_singular="registry", + ressource_result_key_plural="registries", + response_in_list=False, + ) + + if module.params.get("state") == "absent": # type: ignore + vultr.absent() + else: + vultr.present() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/container_registry_info.py b/plugins/modules/container_registry_info.py new file mode 100644 index 0000000..326a3ce --- /dev/null +++ b/plugins/modules/container_registry_info.py @@ -0,0 +1,326 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: container_registry_info +short_description: Get information about the Vultr container registries +version_added: "1.15.0" +description: + - Gather information about container registries available +author: + - "jasites (@jasites)" +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Get Vultr container registry information + vultr.cloud.container_registry_info: + register: result + +- name: Print the infos + ansible.builtin.debug: + var: result.vultr_container_registry_info +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_container_registry_info: + description: Response from Vultr API as list. + returned: success + type: list + contains: + id: + description: UUID of the registry. + returned: success + type: str + sample: 36f91844-b6d2-4e80-8fe0-bca5015d27cf + name: + description: Name of registry + returned: success + type: str + sample: my-registry + urn: + description: URN (URL without connection scheme, i.e., 'https://') for this registry + returned: success + type: str + sample: sjc.vultrcr.com/my-registry + storage: + description: Used and allowed storage metrics for this registry + returned: success + type: dict + contains: + used: + description: Currently consumed storage capacity for this registry + returned: success + type: dict + contains: + updated_at: + description: Date at which storage usage was last updated + returned: success + type: str + sample: 2024-11-26 18:16:08 + bytes: + description: Capacity consumed by this registry expressed in bytes + returned: success + type: float + sample: 4194304 + mb: + description: Capacity consumed by this registry expressed in megabytes + returned: success + type: float + sample: 4 + gb: + description: Capacity consumed by this registry expressed in gigabytes + returned: success + type: float + sample: 0 + tb: + description: Capacity consumed by this registry expressed in terabytes + returned: success + type: float + sample: 0 + allowed: + description: Capacity allowed to be consumed by the current plan selected for this registry + returned: success + type: dict + contains: + bytes: + description: Capacity allowed to be consumed by this registry expressed in bytes + returned: success + type: float + sample: 10737418240 + mb: + description: Capacity allowed to be consumed by this registry expressed in megabytes + returned: success + type: float + sample: 10240 + gb: + description: Capacity allowed to be consumed by this registry expressed in gigabytes + returned: success + type: float + sample: 10 + tb: + description: Capacity allowed to be consumed by this registry expressed in terabytes + returned: success + type: float + sample: 0.01 + date_created: + description: Date on which this registry was created + returned: success + type: str + sample: 2024-11-26 13:16:07 + public: + description: True if this registry does not require authentication to pull from child repositories. + returned: success + type: bool + root_user: + description: Information concerning the root user of this registry + returned: success + type: dict + contains: + id: + description: Numeric ID of this user. + returned: success + type: int + sample: 48747 + username: + description: Globally unique username for the root user + returned: success + type: str + sample: d4518e8f-a495-40eb-86c7-95430522998d + password: + description: Password to be used by the root user to authenticate to this registry + returned: success + type: str + sample: 00example1122334455667788990011 + root: + description: True if this user cannot be deleted or renamed + returned: success + type: str + added_at: + description: Date on which this user was added to this registry + returned: success + type: str + sample: 2024-11-26 13:16:07 + updated_at: + description: Date on which this user was last updated + returned: success + type: str + sample: 2024-11-26 13:16:07 + metadata: + description: Information regarding the subscription associated with this registry + returned: success + type: dict + contains: + region: + description: Information regarding the region in which this registry was deployed + returned: success + type: dict + contains: + id: + description: ID of the region. + returned: success + type: int + sample: 3 + name: + description: Region name + returned: success + type: str + sample: sjc + urn: + description: Base URN (URL without connection scheme, i.e., 'https://') for this region + returned: success + type: str + sample: sjc.vultrcr.com + base_url: + description: Base URL for registries deployed to this region + returned: success + type: str + sample: https://sjc.vultrcr.com + public: + description: True if this region is generally available for new registries to be created + returned: success + type: bool + added_at: + description: Date of when this region was added + returned: success + type: str + sample: 2023-09-14 09:09:16 + updated_at: + description: Date of when this region was last updated + returned: success + type: str + sample: 2023-09-14 09:09:16 + data_center: + description: Additional details regarding this region + returned: success + type: dict + contains: + id: + description: ID of this data center + returned: success + type: int + sample: 12 + name: + description: Name of data center + returned: success + type: str + sample: Silicon Valley + site_code: + description: Code used to differentiate data centers within a region + returned: success + type: str + sample: SJC2 + region: + description: Geographical description of the placement of this data center within the region + returned: success + type: str + sample: West + country: + description: Two letter country code (ISO 3166-1 alpha-2) of country containing this data center + returned: success + type: str + sample: US + continent: + description: Continent containing this data center + returned: success + type: str + sample: North America + description: + description: Additional descriptive data for this data center + returned: success + type: str + sample: Silicon Valley, California + airport: + description: IATA airport code + returned: success + type: str + sample: SJC + subscription: + description: Information pertaining directly to the subscription itself + returned: success + type: dict + contains: + billing: + description: Billing information for this subscription + returned: success + type: dict + contains: + monthly_price: + description: Monthly price of this subscription + returned: success + type: float + pending_charges: + description: Pending charges for this subscription + returned: success + type: float +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +def main(): + argument_spec = vultr_argument_spec() + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultr( + module=module, + namespace="vultr_container_registry_info", + resource_path="/registries", + ressource_result_key_singular="registry", + ressource_result_key_plural="registries", + ) + + vultr.get_result(vultr.query_list()) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/container_registry_region_info.py b/plugins/modules/container_registry_region_info.py new file mode 100644 index 0000000..c1047a7 --- /dev/null +++ b/plugins/modules/container_registry_region_info.py @@ -0,0 +1,179 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: container_registry_region_info +short_description: Get information about the Vultr container registry regions +version_added: "1.15.0" +description: + - Gather information about container registry regions available +author: + - "jasites (@jasites)" +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Get Vultr container registry region information + vultr.cloud.container_registry_region_info: + register: result + +- name: Print the infos + ansible.builtin.debug: + var: result.vultr_container_registry_region_info +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_container_registry_region_info: + description: Response from Vultr API as list. + returned: success + type: list + contains: + id: + description: ID of the region. + returned: success + type: int + sample: 3 + name: + description: Region name + returned: success + type: str + sample: sjc + urn: + description: Base URN (URL without connection scheme, i.e., 'https://') for this region + returned: success + type: str + sample: sjc.vultrcr.com + base_url: + description: Base URL for registries deployed to this region + returned: success + type: str + sample: https://sjc.vultrcr.com + public: + description: True if this region is generally available for new registries to be created + returned: success + type: bool + added_at: + description: Date of when this region was added + returned: success + type: str + sample: 2023-09-14 09:09:16 + updated_at: + description: Date of when this region was last updated + returned: success + type: str + sample: 2023-09-14 09:09:16 + data_center: + description: Additional details regarding this region + returned: success + type: dict + contains: + id: + description: ID of this data center + returned: success + type: int + sample: 12 + name: + description: Name of data center + returned: success + type: str + sample: Silicon Valley + site_code: + description: Code used to differentiate data centers within a region + returned: success + type: str + sample: SJC2 + region: + description: Geographical description of the placement of this data center within the region + returned: success + type: str + sample: West + country: + description: Two letter country code (ISO 3166-1 alpha-2) of country containing this data center + returned: success + type: str + sample: US + continent: + description: Continent containing this data center + returned: success + type: str + sample: North America + description: + description: Additional descriptive data for this data center + returned: success + type: str + sample: Silicon Valley, California + airport: + description: IATA airport code + returned: success + type: str + sample: SJC +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +def main(): + argument_spec = vultr_argument_spec() + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultr( + module=module, + namespace="vultr_container_registry_region_info", + resource_path="/registry/region/list", + ressource_result_key_singular="region", + ) + + vultr.get_result(vultr.query_list()) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/container_registry_repository.py b/plugins/modules/container_registry_repository.py new file mode 100644 index 0000000..642172c --- /dev/null +++ b/plugins/modules/container_registry_repository.py @@ -0,0 +1,196 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: container_registry_repository +short_description: Read, update, and delete Vultr container registry repositories +version_added: "1.15.0" +description: + - Read, update, and delete container registry repositories stored within Vultr +author: + - "jasites (@jasites)" +options: + registry: + image: + description: +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Update Vultr container registry repository description + vultr.cloud.container_registry_repository: + registry: myregistry + image: my-container-image + description: Repository for my container image + +- name: Delete Vultr container registry repository (and all existing images) + vultr.cloud.container_registry_repository: + registry: myregistry + image: my-container-image + state: absent +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_container_registry: + description: Response from Vultr API as dictionary. + returned: success + type: dict + contains: + name: + description: Name of this container registry repository, with registry prepended + returned: success + type: str + sample: my-registry/my-container-image-name + image: + description: Name of the container image stored within this repository + returned: success + type: str + sample: my-container-image-name + description: + description: User defined description of the container image stored in this repository + returned: success + type: str + sample: My container registry repository description + added_at: + description: Date this repository was created + returned: success + type: str + sample: 2023-09-14 09:09:16 + updated_at: + description: Date this repository was last updated + returned: success + type: str + sample: 2023-09-14 09:09:16 + pull_count: + description: Number of artifact downloads for this repository + returned: success + type: int + artifact_count: + description: Number of artifacts contained in this repository + returned: success + type: int +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +class AnsibleVultrContainerRegistryRepository(AnsibleVultr): + def get_container_registry(self): + self.response_in_list = True + result = self.query_filter_list_by_name( + key_name="name", + param_key="registry", + path="/registries", + result_key="registries", + fail_not_found=True, + ) + + # reset property + self.response_in_list = False + return result + + def query_filter_list(self): + self.response_in_list = True + result = self.query_filter_list_by_name( + path="/registry/%s/repositories" % self.get_container_registry()["id"], + key_name=self.resource_key_name, + result_key=self.ressource_result_key_plural, + param_value="%s%s" % ( + self.module.params.get("registry"), + "/" + self.module.params.get("image"), + ), + key_id=self.resource_key_id, + get_details=self.resource_get_details, + skip_transform=False, + ) + + self.response_in_list = False + return result + + def configure(self): + # Set registry id to resource path to ensure registry exists + self.resource_path = self.resource_path % self.get_container_registry()["id"] + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + registry=dict(type="str", required=True), + image=dict(type="str", required=True), + description=dict(type="str"), + state=dict(type="str", choices=["present", "absent"], default="present"), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultrContainerRegistryRepository( + module=module, + namespace="vultr_container_registry_repository", + resource_key_id="image", + resource_key_name="name", + resource_path="/registry/%s/repository", + resource_update_method="PUT", + resource_update_param_keys=["description"], + ressource_result_key_singular="repository", + ressource_result_key_plural="repositories", + response_in_list=False, + ) + + if module.params.get("state") == "absent": # type: ignore + vultr.absent() + else: + vultr.present() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/container_registry_repository_info.py b/plugins/modules/container_registry_repository_info.py new file mode 100644 index 0000000..7c24b35 --- /dev/null +++ b/plugins/modules/container_registry_repository_info.py @@ -0,0 +1,154 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: container_registry_repository_info +short_description: Get information about a Vultr container registry's repositories +version_added: "1.15.0" +description: + - Gather information about a container registry's repositories +author: + - "jasites (@jasites)" +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Get Vultr container registry information + vultr.cloud.container_registry_repository_info: + register: result + +- name: Print the infos + ansible.builtin.debug: + var: result.vultr_container_registry_repository_info +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_container_registry_repository_info: + description: Response from Vultr API as list. + returned: success + type: list + contains: + name: + description: Name of this container registry repository, with registry prepended + returned: success + type: str + sample: my-registry/my-container-image-name + image: + description: Name of the container image stored within this repository + returned: success + type: str + sample: my-container-image-name + description: + description: User defined description of the container image stored in this repository + returned: success + type: str + sample: My container registry repository description + added_at: + description: Date this repository was created + returned: success + type: str + sample: 2023-09-14 09:09:16 + updated_at: + description: Date this repository was last updated + returned: success + type: str + sample: 2023-09-14 09:09:16 + pull_count: + description: Number of artifact downloads for this repository + returned: success + type: int + artifact_count: + description: Number of artifacts contained in this repository + returned: success + type: int +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +class AnsibleVultrContainerRegistryRepositoryInfo(AnsibleVultr): + def get_container_registry(self): + return self.query_filter_list_by_name( + key_name="name", + param_key="registry", + path="/registries", + result_key="registries", + fail_not_found=True, + ) + + def configure(self): + # Set registry id to resource path to ensure registry exists + self.resource_path = self.resource_path % self.get_container_registry()["id"] + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + registry=dict(type="str", required=True), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultrContainerRegistryRepositoryInfo( + module=module, + namespace="vultr_container_registry_repository_info", + resource_path="/registry/%s/repositories", + ressource_result_key_singular="repository", + ressource_result_key_plural="repositories", + ) + + vultr.get_result(vultr.query_list()) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/instance_info.py b/plugins/modules/instance_info.py index 30d59a2..ee3f82f 100644 --- a/plugins/modules/instance_info.py +++ b/plugins/modules/instance_info.py @@ -191,7 +191,7 @@ description: Region the instance was deployed into. returned: success type: str - sample: ews + sample: ewr status: description: Status about the deployment of the instance. returned: success diff --git a/plugins/modules/plan_container_registry_info.py b/plugins/modules/plan_container_registry_info.py new file mode 100644 index 0000000..7ebc94b --- /dev/null +++ b/plugins/modules/plan_container_registry_info.py @@ -0,0 +1,129 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) jasites +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: plan_container_registry_info +short_description: Get information about the Vultr container registry plans +version_added: "1.15.0" +description: + - Gather information about container registry plans available +author: + - "jasites (@jasites)" +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Get Vultr container registry plan information + vultr.cloud.plan_container_registry_info: + register: result + +- name: Print the infos + ansible.builtin.debug: + var: result.vultr_plan_container_registry_info +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_timeout: + description: Timeout used for the API requests. + returned: success + type: int + sample: 60 + api_retries: + description: Amount of max retries for the API requests. + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + api_results_per_page: + description: Number of results returned per call to API. + returned: success + type: int + sample: 100 + api_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_plan_container_registry_info: + description: Response from Vultr API as list. + returned: success + type: list + contains: + id: + description: ID of the plan. + returned: success + type: str + sample: start_up + vanity_name: + description: Stylized plan name + returned: success + type: str + sample: Start Up + max_storage_mb: + description: Total allocated storage allowed by plan + returned: success + type: int + sample: 10240 + monthly_price: + description: Monthly price for this plan + returned: success + type: str +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.common.dict_transformations import dict_merge + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +class AnsibleVultrPlanContainerRegistryInfo(AnsibleVultr): + def transform_result(self, resource): + result = [] + if resource: + for plan in resource.get("plans", {}).keys(): + result.append(dict_merge(dict(id=plan), resource.get("plans", {}).get(plan, {}))) + return result + + +def main(): + argument_spec = vultr_argument_spec() + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultrPlanContainerRegistryInfo( + module=module, + namespace="vultr_plan_container_registry_info", + resource_path="/registry/plan/list", + ressource_result_key_singular="plan", + ) + + vultr.get_result(vultr.api_query(vultr.resource_path)) + + +if __name__ == "__main__": + main() diff --git a/tests/integration/inventory b/tests/integration/inventory new file mode 100644 index 0000000..bc685d5 --- /dev/null +++ b/tests/integration/inventory @@ -0,0 +1,2 @@ +[testgroup] +testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/Library/Developer/CommandLineTools/usr/bin/python3" diff --git a/tests/integration/targets/cleanup/tasks/cleanup_all.yml b/tests/integration/targets/cleanup/tasks/cleanup_all.yml index b3e84c6..6468291 100644 --- a/tests/integration/targets/cleanup/tasks/cleanup_all.yml +++ b/tests/integration/targets/cleanup/tasks/cleanup_all.yml @@ -17,3 +17,4 @@ - ansible.builtin.import_tasks: cleanup_startup_script.yml - ansible.builtin.import_tasks: cleanup_reserved_ip.yml - ansible.builtin.import_tasks: cleanup_network.yml +- ansible.builtin.import_tasks: cleanup_container_registry.yml \ No newline at end of file diff --git a/tests/integration/targets/cleanup/tasks/cleanup_container_registry.yml b/tests/integration/targets/cleanup/tasks/cleanup_container_registry.yml new file mode 100644 index 0000000..8955844 --- /dev/null +++ b/tests/integration/targets/cleanup/tasks/cleanup_container_registry.yml @@ -0,0 +1,26 @@ +--- +- name: cleanup + when: vultr_api_key + block: + - name: List container registries + ansible.builtin.uri: + url: "{{ vultr_api_url }}/registries" + headers: + Authorization: Bearer {{ vultr_api_key }} + status_code: 200 + register: res + no_log: true + + - name: Remove all container registries created by this test run + ansible.builtin.uri: + url: "{{ vultr_api_url }}/registry/{{ item.id }}" + method: "DELETE" + headers: + Authorization: Bearer {{ vultr_api_key }} + status_code: 204 + timeout: 60 + when: ( vultr_resource_prefix | replace('-', '') ) in item.name + with_items: "{{ res.json.registries }}" + loop_control: + label: "{{ item.name }}" + no_log: true \ No newline at end of file diff --git a/tests/integration/targets/container_registry/aliases b/tests/integration/targets/container_registry/aliases new file mode 100644 index 0000000..c749ce7 --- /dev/null +++ b/tests/integration/targets/container_registry/aliases @@ -0,0 +1,3 @@ +cloud/vultr +needs/target/common +needs/target/cleanup diff --git a/tests/integration/targets/container_registry/defaults/main.yml b/tests/integration/targets/container_registry/defaults/main.yml new file mode 100644 index 0000000..546226a --- /dev/null +++ b/tests/integration/targets/container_registry/defaults/main.yml @@ -0,0 +1,7 @@ +--- +vultr_container_registry_name: "{{ vultr_resource_prefix | replace('-', '') }}containerregistry" +vultr_container_registry_plan: start_up +vultr_container_registry_plan2: premium +vultr_container_registry_plan3: business +vultr_container_registry_public: false +vultr_container_registry_region: sjc \ No newline at end of file diff --git a/tests/integration/targets/container_registry/meta/main.yml b/tests/integration/targets/container_registry/meta/main.yml new file mode 100644 index 0000000..2083f0e --- /dev/null +++ b/tests/integration/targets/container_registry/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - common diff --git a/tests/integration/targets/container_registry/tasks/failures.yml b/tests/integration/targets/container_registry/tasks/failures.yml new file mode 100644 index 0000000..2459e17 --- /dev/null +++ b/tests/integration/targets/container_registry/tasks/failures.yml @@ -0,0 +1,21 @@ +--- +- name: test fail if missing required + vultr.cloud.container_registry: + register: result + ignore_errors: true +- name: verify test fail if missing required + ansible.builtin.assert: + that: + - result is failed + - 'result.msg == "missing required arguments: name"' + +- name: test fail if missing required and state=present + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + register: result + ignore_errors: true +- name: verify test fail if missing required and state=present + ansible.builtin.assert: + that: + - result is failed + - 'result.msg == "state is present but all of the following are missing: public, region, plan"' diff --git a/tests/integration/targets/container_registry/tasks/main.yml b/tests/integration/targets/container_registry/tasks/main.yml new file mode 100644 index 0000000..4249714 --- /dev/null +++ b/tests/integration/targets/container_registry/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- block: + - ansible.builtin.import_tasks: failures.yml + - ansible.builtin.import_tasks: tests.yml + always: + - ansible.builtin.import_role: + name: cleanup + tasks_from: cleanup_container_registry.yml diff --git a/tests/integration/targets/container_registry/tasks/tests.yml b/tests/integration/targets/container_registry/tasks/tests.yml new file mode 100644 index 0000000..c4091ee --- /dev/null +++ b/tests/integration/targets/container_registry/tasks/tests.yml @@ -0,0 +1,136 @@ +--- +- name: test create container registry in check mode + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan }}" + public: "{{ vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result + check_mode: true +- name: verify test create container registry in check mode + ansible.builtin.assert: + that: + - result is changed + +- name: test create container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan }}" + public: "{{ vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result +- name: verify test create container registry + ansible.builtin.assert: + that: + - result is changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public == vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test create container registry idempotence + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan }}" + public: "{{ vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result +- name: verify test create container registry idempotence + ansible.builtin.assert: + that: + - result is not changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public == vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test update container registry in check mode + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan2 }}" + public: "{{ not vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result + check_mode: true +- name: verify test update container registry in check mode + ansible.builtin.assert: + that: + - result is changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public == vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test update container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan2 }}" + public: "{{ not vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result +- name: verify test update container registry + ansible.builtin.assert: + that: + - result is changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public != vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test update container registry idempotence + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan2 }}" + public: "{{ not vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result +- name: verify test update container registry idempotence + ansible.builtin.assert: + that: + - result is not changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public != vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test update container registry not updated if new plan has smaller allowed storage capacity + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan3 }}" + public: "{{ not vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: result + ignore_errors: true +- name: verify test update container registry not updated if new plan has smaller allowed storage capacity + ansible.builtin.assert: + that: + - result is not changed + - result.vultr_container_registry.name == vultr_container_registry_name + - result.vultr_container_registry.public != vultr_container_registry_public + - result.vultr_container_registry.metadata.region.name == vultr_container_registry_region + +- name: test delete container registry in check mode + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + state: absent + check_mode: true + register: result +- name: verify test delete container registry in check mode + ansible.builtin.assert: + that: + - result is changed + +- name: test delete container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + state: absent + register: result +- name: verify test delete container registry + ansible.builtin.assert: + that: + - result is changed + +- name: test delete container registry idempotence + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + state: absent + register: result +- name: verify test delete container registry idempotence + ansible.builtin.assert: + that: + - result is not changed diff --git a/tests/integration/targets/container_registry_info/aliases b/tests/integration/targets/container_registry_info/aliases new file mode 100644 index 0000000..c749ce7 --- /dev/null +++ b/tests/integration/targets/container_registry_info/aliases @@ -0,0 +1,3 @@ +cloud/vultr +needs/target/common +needs/target/cleanup diff --git a/tests/integration/targets/container_registry_info/defaults/main.yml b/tests/integration/targets/container_registry_info/defaults/main.yml new file mode 100644 index 0000000..5e0f205 --- /dev/null +++ b/tests/integration/targets/container_registry_info/defaults/main.yml @@ -0,0 +1,2 @@ +--- +vultr_container_registry_name: "{{ vultr_resource_prefix | replace('-', '') }}infocontainerregistry" diff --git a/tests/integration/targets/container_registry_info/meta/main.yml b/tests/integration/targets/container_registry_info/meta/main.yml new file mode 100644 index 0000000..2083f0e --- /dev/null +++ b/tests/integration/targets/container_registry_info/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - common diff --git a/tests/integration/targets/container_registry_info/tasks/main.yml b/tests/integration/targets/container_registry_info/tasks/main.yml new file mode 100644 index 0000000..20d807f --- /dev/null +++ b/tests/integration/targets/container_registry_info/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- block: + - ansible.builtin.import_tasks: tests.yml + always: + - ansible.builtin.import_role: + name: cleanup + tasks_from: cleanup_container_registry diff --git a/tests/integration/targets/container_registry_info/tasks/tests.yml b/tests/integration/targets/container_registry_info/tasks/tests.yml new file mode 100644 index 0000000..ca89f97 --- /dev/null +++ b/tests/integration/targets/container_registry_info/tasks/tests.yml @@ -0,0 +1,24 @@ +--- +- name: create the container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + public: false + plan: start_up + region: sjc + +- name: test gather vultr container registry info in check mode + vultr.cloud.container_registry_info: + check_mode: true + register: result +- name: verify test gather vultr container registry info in check mode + ansible.builtin.assert: + that: + - result.vultr_container_registry_info | selectattr('name', 'equalto', vultr_container_registry_name | replace('-', '') ) | list | count == 1 + +- name: test gather vultr container registry info + vultr.cloud.container_registry_info: + register: result +- name: verify test gather vultr container registry info + ansible.builtin.assert: + that: + - result.vultr_container_registry_info | selectattr('name', 'equalto', vultr_container_registry_name | replace('-', '') ) | list | count == 1 \ No newline at end of file diff --git a/tests/integration/targets/container_registry_region_info/aliases b/tests/integration/targets/container_registry_region_info/aliases new file mode 100644 index 0000000..64e637b --- /dev/null +++ b/tests/integration/targets/container_registry_region_info/aliases @@ -0,0 +1 @@ +cloud/vultr \ No newline at end of file diff --git a/tests/integration/targets/container_registry_region_info/tasks/main.yml b/tests/integration/targets/container_registry_region_info/tasks/main.yml new file mode 100644 index 0000000..e7041c3 --- /dev/null +++ b/tests/integration/targets/container_registry_region_info/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: test gather vultr container registry region info in check mode + vultr.cloud.container_registry_region_info: + check_mode: true + register: result + +- name: verify test gather vultr container registry region info in check mode + ansible.builtin.assert: + that: + - result.vultr_container_registry_region_info | selectattr('urn', 'equalto', 'sjc.vultrcr.com') | list | count == 1 + +- name: test gather vultr container registry region info + vultr.cloud.container_registry_region_info: + register: result + +- name: verify test gather vultr container registry region info + ansible.builtin.assert: + that: + - result.vultr_container_registry_region_info | selectattr('urn', 'equalto', 'sjc.vultrcr.com') | list | count == 1 \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository/aliases b/tests/integration/targets/container_registry_repository/aliases new file mode 100644 index 0000000..c749ce7 --- /dev/null +++ b/tests/integration/targets/container_registry_repository/aliases @@ -0,0 +1,3 @@ +cloud/vultr +needs/target/common +needs/target/cleanup diff --git a/tests/integration/targets/container_registry_repository/defaults/main.yml b/tests/integration/targets/container_registry_repository/defaults/main.yml new file mode 100644 index 0000000..914c001 --- /dev/null +++ b/tests/integration/targets/container_registry_repository/defaults/main.yml @@ -0,0 +1,9 @@ +--- +vultr_container_registry_name: "{{ vultr_resource_prefix | replace('-', '') }}containerregistryrepository" +vultr_container_registry_plan: start_up +vultr_container_registry_public: false +vultr_container_registry_region: ewr + +vultr_container_image_name: "{{ vultr_resource_prefix }}" + +vultr_container_registry_repository_description: "{{ vultr_resource_prefix }}" \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository/meta/main.yml b/tests/integration/targets/container_registry_repository/meta/main.yml new file mode 100644 index 0000000..9b56fc7 --- /dev/null +++ b/tests/integration/targets/container_registry_repository/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - common \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository/tasks/failures.yml b/tests/integration/targets/container_registry_repository/tasks/failures.yml new file mode 100644 index 0000000..ad3d72d --- /dev/null +++ b/tests/integration/targets/container_registry_repository/tasks/failures.yml @@ -0,0 +1,22 @@ +--- +- name: test fail if missing required - registry + vultr.cloud.container_registry_repository: + register: result + ignore_errors: true +- name: verify test fail if missing required - registry + ansible.builtin.assert: + that: + - result is failed + - 'result.msg == "missing required arguments: image, registry"' + +- name: test fail if missing required - image + vultr.cloud.container_registry_repository: + registry: "{{ vultr_container_registry_name }}" + state: absent + register: result + ignore_errors: true +- name: verify test fail if missing required - image + ansible.builtin.assert: + that: + - result is failed + - 'result.msg == "missing required arguments: image"' \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository/tasks/main.yml b/tests/integration/targets/container_registry_repository/tasks/main.yml new file mode 100644 index 0000000..e712424 --- /dev/null +++ b/tests/integration/targets/container_registry_repository/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- block: + - ansible.builtin.import_tasks: failures.yml + - ansible.builtin.import_tasks: tests.yml + always: + - ansible.builtin.import_role: + name: cleanup + tasks_from: cleanup_container_registry.yml \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository/tasks/tests.yml b/tests/integration/targets/container_registry_repository/tasks/tests.yml new file mode 100644 index 0000000..6cccc02 --- /dev/null +++ b/tests/integration/targets/container_registry_repository/tasks/tests.yml @@ -0,0 +1,110 @@ +--- +- name: setup container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan }}" + public: "{{ vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: create_result + +# Before the remaining tests can be enabled, it will be necessary to determine how to get a container image +# built (either before invoking the test, or by adding the appropriate parameters here), as well as +# ensuring the containers.podman or community.docker collections are installed without making them +# dependencies unnecessarily +#- name: push container image to vultr container registry repository +# containers.podman.podman_image: +# name: "{{ create_result.vultr_container_registry.urn ~ '/' ~ vultr_container_image_name }}" +# username: "{{ create_result.vultr_container_registry.root_user.username }}" +# password: "{{ create_result.vultr_container_registry.root_user.password }}" +# push: true +# tag: latest +# push_args: +# dest: "{{ create_result.vultr_container_registry.urn }}" + +#- name: test repository was created by container push +# vultr.cloud.container_registry_repository_info: +# registry: "{{ vultr_container_registry_name }}" +# register: result +#- name: verify test repository was created by container push +# ansible.builtin.assert: +# that: +# - result.vultr_container_registry_repository_info | selectattr('name', 'equalto', vultr_container_registry_name ~ '/' ~ vultr_container_image_name) | list | count == 1 +# - result.vultr_container_registry_repository_info | selectattr('name', 'equalto', vultr_container_registry_name ~ '/' ~ vultr_container_image_name) | selectattr('description', 'equalto', '') | list | count == 1 + +#- name: test update container registry repository update description check mode +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# description: "{{ vultr_resource_prefix }}" +# register: result +# check_mode: true +#- name: verify test update container registry repository update description check mode +# ansible.builtin.assert: +# that: +# - result is changed +# - result.vultr_container_registry_repository.description == '' + +#- name: test update container registry repository update description +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# description: "{{ vultr_resource_prefix }}" +# register: result +#- name: verify test update container registry repository update description +# ansible.builtin.assert: +# that: +# - result is changed +# - result.vultr_container_registry_repository.description == vultr_resource_prefix + +#- name: test update container registry repository update description idempotence +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# description: "{{ vultr_resource_prefix }}" +# register: result +#- name: verify test update container registry repository update description idempotence +# ansible.builtin.assert: +# that: +# - result is not changed +# - result.vultr_container_registry_repository.description == vultr_resource_prefix + +#- name: test delete container registry repository check mode +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# state: absent +# register: result +# check_mode: true +#- name: verify test delete container registry repository check mode +# ansible.builtin.assert: +# that: +# - result is changed +# - result.vultr_container_registry_repository.description == vultr_resource_prefix + +#- name: test delete container registry repository +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# state: absent +# register: result +#- name: verify test delete container registry repository +# ansible.builtin.assert: +# that: +# - result is changed +# - result.vultr_container_registry_repository.description == vultr_resource_prefix + +#- name: test delete container registry repository idempotence +# vultr.cloud.container_registry_repository: +# registry: "{{ vultr_container_registry_name }}" +# image: "{{ vultr_container_image_name }}" +# state: absent +# register: result +#- name: verify test delete container registry repository idempotence +# ansible.builtin.assert: +# that: +# - result is not changed + +- name: delete container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + state: absent diff --git a/tests/integration/targets/container_registry_repository_info/aliases b/tests/integration/targets/container_registry_repository_info/aliases new file mode 100644 index 0000000..c749ce7 --- /dev/null +++ b/tests/integration/targets/container_registry_repository_info/aliases @@ -0,0 +1,3 @@ +cloud/vultr +needs/target/common +needs/target/cleanup diff --git a/tests/integration/targets/container_registry_repository_info/defaults/main.yml b/tests/integration/targets/container_registry_repository_info/defaults/main.yml new file mode 100644 index 0000000..85fdbc3 --- /dev/null +++ b/tests/integration/targets/container_registry_repository_info/defaults/main.yml @@ -0,0 +1,7 @@ +--- +vultr_container_registry_name: "{{ vultr_resource_prefix | replace('-', '') }}infocontainerregistryrepository" +vultr_container_registry_plan: start_up +vultr_container_registry_public: false +vultr_container_registry_region: ewr + +vultr_container_image_name: "{{ vultr_resource_prefix }}" diff --git a/tests/integration/targets/container_registry_repository_info/meta/main.yml b/tests/integration/targets/container_registry_repository_info/meta/main.yml new file mode 100644 index 0000000..9b56fc7 --- /dev/null +++ b/tests/integration/targets/container_registry_repository_info/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - common \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository_info/tasks/main.yml b/tests/integration/targets/container_registry_repository_info/tasks/main.yml new file mode 100644 index 0000000..299ef3f --- /dev/null +++ b/tests/integration/targets/container_registry_repository_info/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- block: + - ansible.builtin.import_tasks: tests.yml + always: + - ansible.builtin.import_role: + name: cleanup + tasks_from: cleanup_container_registry.yml \ No newline at end of file diff --git a/tests/integration/targets/container_registry_repository_info/tasks/tests.yml b/tests/integration/targets/container_registry_repository_info/tasks/tests.yml new file mode 100644 index 0000000..49b2872 --- /dev/null +++ b/tests/integration/targets/container_registry_repository_info/tasks/tests.yml @@ -0,0 +1,50 @@ +--- +- name: create container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + plan: "{{ vultr_container_registry_plan }}" + public: "{{ vultr_container_registry_public }}" + region: "{{ vultr_container_registry_region }}" + register: create_result + +- name: test gather vultr container registry repository info - empty resources + vultr.cloud.container_registry_repository_info: + registry: "{{ vultr_container_registry_name }}" + +# Before the remaining tests can be enabled, it will be necessary to determine how to get a container image +# built (either before invoking the test, or by adding the appropriate parameters here), as well as +# ensuring the containers.podman or community.docker collections are installed without making them +# dependencies unnecessarily +#- name: push container image to vultr container registry repository +# containers.podman.podman_image: +# name: "{{ create_result.vultr_container_registry.urn ~ '/' ~ vultr_container_image_name }}" +# username: "{{ create_result.vultr_container_registry.root_user.username }}" +# password: "{{ create_result.vultr_container_registry.root_user.password }}" +# push: true +# tag: latest +# push_args: +# dest: "{{ create_result.vultr_container_registry.urn }}" + +#- name: test gather vultr container registry repository in check mode +# vultr.cloud.container_registry_repository_info: +# registry: "{{ vultr_container_registry_name }}" +# check_mode: true +# register: result +#- name: verify test gather vultr container registry repository in check mode +# ansible.builtin.assert: +# that: +# - result.vultr_container_registry_repository_info | selectattr('name', 'equalto', vultr_container_registry_name ~ '/' ~ vultr_container_image_name) | list | count == 1 + +#- name: test gather vultr container registry repository +# vultr.cloud.container_registry_repository_info: +# registry: "{{ vultr_container_registry_name }}" +# register: result +#- name: verify test gather vultr container registry repository +# ansible.builtin.assert: +# that: +# - result.vultr_container_registry_repository_info | selectattr('name', 'equalto', vultr_container_registry_name ~ '/' ~ vultr_container_image_name) | list | count == 1 + +- name: delete container registry + vultr.cloud.container_registry: + name: "{{ vultr_container_registry_name }}" + state: absent \ No newline at end of file diff --git a/tests/integration/targets/plan_container_registry_info/aliases b/tests/integration/targets/plan_container_registry_info/aliases new file mode 100644 index 0000000..64e637b --- /dev/null +++ b/tests/integration/targets/plan_container_registry_info/aliases @@ -0,0 +1 @@ +cloud/vultr \ No newline at end of file diff --git a/tests/integration/targets/plan_container_registry_info/tasks/main.yml b/tests/integration/targets/plan_container_registry_info/tasks/main.yml new file mode 100644 index 0000000..f4b2a1e --- /dev/null +++ b/tests/integration/targets/plan_container_registry_info/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: test gather vultr container registry plan info in check mode + vultr.cloud.plan_container_registry_info: + check_mode: true + register: result + +- name: verify test gather vultr container registry plan info in check mode + ansible.builtin.assert: + that: + - result.vultr_plan_container_registry_info | selectattr('id', 'equalto', 'start_up') | list | count == 1 + +- name: test gather vultr container registry plan info + vultr.cloud.plan_container_registry_info: + register: result + +- name: verify test gather vultr container registry plan info + ansible.builtin.assert: + that: + - result.vultr_plan_container_registry_info | selectattr('id', 'equalto', 'start_up') | list | count == 1 \ No newline at end of file diff --git a/tests/integration/targets/user_info/tasks/tests.yml b/tests/integration/targets/user_info/tasks/tests.yml index 023cd3b..e83586f 100644 --- a/tests/integration/targets/user_info/tasks/tests.yml +++ b/tests/integration/targets/user_info/tasks/tests.yml @@ -17,7 +17,7 @@ - name: verify test get vultr user info in check mode ansible.builtin.assert: that: - - result.vultr_user_info|selectattr('name','equalto','{{ user_name }}') | list | count == 1 + - result.vultr_user_info|selectattr('name','equalto',user_name) | list | count == 1 - name: test get vultr user info vultr.cloud.user_info: @@ -26,7 +26,7 @@ - name: verify test get vultr user info ansible.builtin.assert: that: - - result.vultr_user_info|selectattr('name','equalto','{{ user_name }}') | list | count == 1 + - result.vultr_user_info|selectattr('name','equalto',user_name) | list | count == 1 - name: Delete the user vultr.cloud.user: