diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:35 +0000 |
commit | 7fec0b69a082aaeec72fee0612766aa42f6b1b4d (patch) | |
tree | efb569b86ca4da888717f5433e757145fa322e08 /ansible_collections/vultr/cloud/plugins/modules | |
parent | Releasing progress-linux version 7.7.0+dfsg-3~progress7.99u1. (diff) | |
download | ansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.tar.xz ansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.zip |
Merging upstream version 9.4.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/vultr/cloud/plugins/modules')
8 files changed, 997 insertions, 193 deletions
diff --git a/ansible_collections/vultr/cloud/plugins/modules/bare_metal.py b/ansible_collections/vultr/cloud/plugins/modules/bare_metal.py new file mode 100644 index 000000000..d2ffe09ef --- /dev/null +++ b/ansible_collections/vultr/cloud/plugins/modules/bare_metal.py @@ -0,0 +1,440 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023, René Moser <mail@renemoser.net> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: bare_metal +short_description: Manages bare metal machines on Vultr. +description: + - Manage bare metal machines on Vultr. +version_added: "1.9.0" +author: + - "René Moser (@resmo)" +options: + label: + description: + - Name of the bare metal machine. + required: true + aliases: [ name ] + type: str + hostname: + description: + - The hostname to assign to this bare metal machine. + type: str + os: + description: + - The operating system name. + - Mutually exclusive with I(image) and I(app). + type: str + app: + description: + - The app deploy name of Vultr OneClick apps. + - Mutually exclusive with I(image) and I(os). + type: str + image: + description: + - The image deploy name of Vultr Marketplace apps. + - Mutually exclusive with I(os) and I(app). + type: str + plan: + description: + - The plan name to use for the bare metal machine. + - Required if the bare metal machine does not yet exist. + type: str + activation_email: + description: + - Whether to send an activation email when the bare metal machine is ready or not. + - Only considered on creation. + type: bool + default: false + persistent_pxe: + description: + - Whether to enable persistent PXE or not. + type: bool + enable_ipv6: + description: + - Whether to enable IPv6 or not. + type: bool + tags: + description: + - Tags for the bare metal machine. + type: list + elements: str + user_data: + description: + - User data to be passed to the bare metal machine. + type: str + startup_script: + description: + - Name or ID of the startup script to execute on boot. + - Only considered while creating the bare metal machine. + type: str + ssh_keys: + description: + - List of SSH key names passed to the bare metal machine on creation. + type: list + elements: str + snapshot: + description: + - Description or ID of the snapshot. + - Only considered while creating the bare metal machine. + type: str + reserved_ipv4: + description: + - IP address of the floating IP to use as the main IP of this bare metal machine. + - Only considered on creation. + type: str + region: + description: + - Region the bare metal machine is deployed into. + type: str + required: true + vpc2s: + description: + - A list of VPCs (VPC 2.0) identified by their description to be assigned to the bare metal machine. + type: list + elements: str + state: + description: + - State of the bare metal machine. + default: present + choices: [ present, absent ] + type: str +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +--- +- name: Create an bare metal machine using OS + vultr.cloud.bare_metal: + label: my web server + hostname: my-hostname + user_data: | + #cloud-config + packages: + - nginx + plan: vbm-4c-32gb + enable_ipv6: true + ssh_keys: + - my ssh key + vpc2s: + - my vpc description + tags: + - web + - project-genesis + region: ams + os: Debian 12 x64 (bookworm) + +- name: Deploy an bare metal machine of a marketplace app + vultr.cloud.bare_metal: + label: git-server + hostname: git + plan: vbm-4c-32gb + enable_ipv6: true + region: ams + image: Gitea on Ubuntu 20.04 + +- name: Delete an bare metal machine + vultr.cloud.bare_metal: + label: my web server + region: ams + 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_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_bare_metal: + description: Response from Vultr API. + returned: success + type: dict + contains: + id: + description: ID of the bare metal machine. + returned: success + type: str + sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60 + v6_main_ip: + description: IPv6 of the bare metal machine. + returned: success + type: str + sample: "" + v6_network: + description: IPv6 network of the bare metal machine. + returned: success + type: str + sample: "" + v6_network_size: + description: IPv6 network size of the bare metal machine. + returned: success + type: int + sample: 0 + mac_address: + description: MAC address of the bare metal machine. + returned: success + type: int + sample: 2199756823533 + main_ip: + description: IPv4 of the bare metal machine. + returned: success + type: str + sample: 95.179.189.95 + netmask_v4: + description: Netmask IPv4 of the bare metal machine. + returned: success + type: str + sample: 255.255.254.0 + gateway_v4: + description: Gateway IPv4. + returned: success + type: str + sample: 95.179.188.1 + disk: + description: Disk info of the bare metal machine. + returned: success + type: str + sample: "2x 240GB SSD" + cpu_count: + description: CPU count of the bare metal machine. + returned: success + type: int + sample: 1 + plan: + description: Plan of the bare metal machine. + returned: success + type: str + sample: vbm-4c-32gb + image_id: + description: Image ID of the bare metal machine. + returned: success + type: str + sample: "" + os_id: + description: OS ID of the bare metal machine. + returned: success + type: int + sample: 186 + app_id: + description: App ID of the bare metal machine. + returned: success + type: int + sample: 37 + date_created: + description: Date when the bare metal machine was created. + returned: success + type: str + sample: "2020-10-10T01:56:20+00:00" + label: + description: Label of the bare metal machine. + returned: success + type: str + sample: my bare metal machine + region: + description: Region the bare metal machine was deployed into. + returned: success + type: str + sample: ews + status: + description: Status about the deployment of the bare metal machine. + returned: success + type: str + sample: active + default_password: + description: The default password assigned at deployment. Only available for ten minutes after deployment. + returned: success + type: str + sample: "examplePassword" + power_status: + description: Power status of the bare metal machine. + returned: success + type: str + sample: running + ram: + description: RAM info of the bare metal machine. + returned: success + type: str + sample: "32768 MB" + os: + description: OS of the bare metal machine. + returned: success + type: str + sample: Application + tags: + description: Tags of the bare metal machine. + returned: success + type: list + sample: [ my-tag ] + features: + description: Features of the bare metal machine. + returned: success + type: list + sample: [ ddos_protection, ipv6, auto_backups ] + user_data: + description: Base64 encoded user data (cloud init) of the bare metal machine. + returned: success + type: str + sample: I2Nsb3VkLWNvbmZpZwpwYWNrYWdlczoKICAtIGh0b3AK + enable_ipv6: + description: Whether IPv6 is enabled or not. + returned: success + type: bool + sample: true + vpc2s: + description: List of VPCs (VPC 2.0) attached. + returned: success + type: list + contains: + id: + description: ID of the VPC. + returned: success + type: str + sample: 5536d2a4-66fd-4dfb-b839-7672fd5bc116 + description: + description: Description of the VPC. + returned: success + type: str + sample: my vpc + region: + description: Region the VPC is assigned to. + returned: success + type: str + sample: ews + date_created: + description: Date when the VPC was created. + returned: success + type: str + sample: "2020-10-10T01:56:20+00:00" + ip_block: + description: IP block assigned to the VPC. + returned: success + type: str + sample: "10.99.0.0" + prefix_length: + description: The number of bits for the netmask in CIDR notation. + returned: success + type: int + sample: 24 +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.common_instance import AnsibleVultrCommonInstance +from ..module_utils.vultr_v2 import vultr_argument_spec + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + label=dict(type="str", required=True, aliases=["name"]), + hostname=dict(type="str"), + app=dict(type="str"), + image=dict(type="str"), + snapshot=dict(type="str"), + os=dict(type="str"), + plan=dict(type="str"), + activation_email=dict(type="bool", default=False), + enable_ipv6=dict(type="bool"), + persistent_pxe=dict(type="bool"), + tags=dict(type="list", elements="str"), + vpc2s=dict(type="list", elements="str"), + reserved_ipv4=dict(type="str"), + startup_script=dict(type="str"), + user_data=dict(type="str"), + ssh_keys=dict(type="list", elements="str", no_log=False), + region=dict(type="str", required=True), + state=dict( + choices=[ + "present", + "absent", + ], + default="present", + ), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + required_if=(("state", "present", ("plan",)),), + mutually_exclusive=(("os", "app", "image", "snapshot"),), + supports_check_mode=True, + ) + + vultr = AnsibleVultrCommonInstance( + module=module, + namespace="vultr_bare_metal", + resource_path="/bare-metals", + ressource_result_key_singular="bare_metal", + resource_create_param_keys=[ + "label", + "hostname", + "plan", + "app_id", + "os_id", + "iso_id", + "image_id", + "snapshot_id", + "script_id", + "region", + "enable_ipv6", + "reserved_ipv4", + "user_data", + "tags", + "activation_email", + "sshkey_id", + "persistent_pxe", + "attach_vpc2", + ], + resource_update_param_keys=[ + "plan", + "tags", + "enable_ipv6", + "user_data", + "attach_vpc2", + "detach_vpc2", + ], + resource_key_name="label", + ) + + state = module.params.get("state") # type: ignore + if state == "absent": + vultr.absent() + else: + vultr.present() + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/vultr/cloud/plugins/modules/firewall_rule.py b/ansible_collections/vultr/cloud/plugins/modules/firewall_rule.py index 474372d08..67dd85f4d 100644 --- a/ansible_collections/vultr/cloud/plugins/modules/firewall_rule.py +++ b/ansible_collections/vultr/cloud/plugins/modules/firewall_rule.py @@ -212,6 +212,21 @@ class AnsibleVultrFirewallRule(AnsibleVultr): if source is not None and source != "cloudflare": self.module.params["source"] = self.get_load_balancer()["id"] + # Warn about port only affects TCP and UDP protocol + if ( + self.module.params.get("protocol") + not in ( + "tcp", + "udp", + ) + and self.module.params.get("port") is not None + ): + self.module.warn( + "Setting a port (%s) only affects protocols TCP/UDP, but protocol is: %s. Ignoring." + % (self.module.params.get("port"), self.module.params.get("protocol")) + ) + self.module.params["port"] = None + def query(self): result = dict() for resource in self.query_list(): diff --git a/ansible_collections/vultr/cloud/plugins/modules/instance.py b/ansible_collections/vultr/cloud/plugins/modules/instance.py index 73099164d..7eca359b4 100644 --- a/ansible_collections/vultr/cloud/plugins/modules/instance.py +++ b/ansible_collections/vultr/cloud/plugins/modules/instance.py @@ -80,6 +80,14 @@ options: description: - User data to be passed to the instance. type: str + user_scheme: + description: + - The user scheme used as login user (Linux-only). + - By default, the I(root) user is configured. + - Only considered while creating the instance. + type: str + choices: [ root, limited ] + version_added: "1.11.0" startup_script: description: - Name or ID of the startup script to execute on boot. @@ -146,7 +154,7 @@ EXAMPLES = """ - web - project-genesis region: ams - os: Debian 11 x64 (bullseye) + os: Debian 12 x64 (bookworm) - name: Deploy an instance of a marketplace app vultr.cloud.instance: @@ -362,6 +370,12 @@ vultr_instance: returned: success type: str sample: I2Nsb3VkLWNvbmZpZwpwYWNrYWdlczoKICAtIGh0b3AK + user_scheme: + description: The user scheme to login into this instance + returned: success + type: str + sample: root + version_added: "1.11.0" backups: description: Whether backups are enabled or disabled. returned: success @@ -408,173 +422,14 @@ vultr_instance: sample: "5a:01:04:3d:5e:72" """ -import base64 from ansible.module_utils.basic import AnsibleModule -from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec - - -class AnsibleVultrInstance(AnsibleVultr): - def get_ssh_key_ids(self): - ssh_key_names = list(self.module.params["ssh_keys"]) - ssh_keys = self.query_list(path="/ssh-keys", result_key="ssh_keys") - - ssh_key_ids = list() - for ssh_key in ssh_keys: - if ssh_key["name"] in ssh_key_names: - ssh_key_ids.append(ssh_key["id"]) - ssh_key_names.remove(ssh_key["name"]) - - if ssh_key_names: - self.module.fail_json(msg="SSH key names not found: %s" % ", ".join(ssh_key_names)) - - return ssh_key_ids - - def get_vpc_ids(self): - vpc_names = list(self.module.params["vpcs"]) - vpcs = self.query_list(path="/vpcs", result_key="vpcs") - - vpc_ids = list() - for vpc in vpcs: - if vpc["description"] in vpc_names: - vpc_ids.append(vpc["id"]) - vpc_names.remove(vpc["description"]) - - if vpc_names: - self.module.fail_json(msg="VPCs not found: %s" % ", ".join(vpc_names)) - - return vpc_ids - - def get_instance_vpcs(self, resource): - path = "/instances/%s/vpcs" % resource["id"] - vpcs = self.query_list(path=path, result_key="vpcs") - - # Workaround to get the description field into the list - result = list() - for vpc in vpcs: - vpc_detail = self.query_by_id(resource_id=vpc["id"], path="/vpcs", result_key="vpc") - vpc["description"] = vpc_detail["description"] - result.append(vpc) - return result - - def get_firewall_group(self): - return self.query_filter_list_by_name( - key_name="description", - param_key="firewall_group", - path="/firewalls", - result_key="firewall_groups", - fail_not_found=True, - ) - - def get_snapshot(self): - return self.query_filter_list_by_name( - key_name="description", - param_key="snapshot", - path="/snapshots", - result_key="snapshots", - fail_not_found=True, - ) - - def get_startup_script(self): - return self.query_filter_list_by_name( - key_name="name", - param_key="startup_script", - path="/startup-scripts", - result_key="startup_scripts", - fail_not_found=True, - ) - - def get_os(self): - return self.query_filter_list_by_name( - key_name="name", - param_key="os", - path="/os", - result_key="os", - fail_not_found=True, - ) - - def get_app(self): - return self.query_filter_list_by_name( - key_name="deploy_name", - param_key="app", - path="/applications", - result_key="applications", - fail_not_found=True, - query_params={"type": "one-click"}, - ) - - def get_image(self): - return self.query_filter_list_by_name( - key_name="deploy_name", - param_key="image", - path="/applications", - result_key="applications", - fail_not_found=True, - query_params={"type": "marketplace"}, - ) - - def get_user_data(self, resource): - res = self.api_query( - path="%s/%s/%s" % (self.resource_path, resource[self.resource_key_id], "user-data"), - ) - if res: - return str(res.get("user_data", dict()).get("data")) - return "" - - def transform_resource(self, resource): - if not resource: - return resource - - features = resource.get("features", list()) - resource["backups"] = "enabled" if "auto_backups" in features else "disabled" - resource["enable_ipv6"] = "ipv6" in features - resource["ddos_protection"] = "ddos_protection" in features - resource["vpcs"] = self.get_instance_vpcs(resource=resource) - - return resource - - def get_detach_vpcs_ids(self, resource): - detach_vpc_ids = [] - for vpc in resource.get("vpcs", list()): - if vpc["id"] not in list(self.module.params["attach_vpc"]): - detach_vpc_ids.append(vpc["id"]) - return detach_vpc_ids - - def configure(self): - if self.module.params["state"] != "absent": - if self.module.params["startup_script"] is not None: - self.module.params["script_id"] = self.get_startup_script()["id"] - - if self.module.params["snapshot"] is not None: - self.module.params["snapshot_id"] = self.get_snapshot()["id"] - - if self.module.params["firewall_group"] is not None: - self.module.params["firewall_group_id"] = self.get_firewall_group()["id"] - - if self.module.params["os"] is not None: - self.module.params["os_id"] = self.get_os()["id"] - - if self.module.params["app"] is not None: - self.module.params["app_id"] = self.get_app()["id"] - - if self.module.params["image"] is not None: - self.module.params["image_id"] = self.get_image()["image_id"] - - if self.module.params["user_data"] is not None: - self.module.params["user_data"] = base64.b64encode(self.module.params["user_data"].encode()) - - if self.module.params["ssh_keys"] is not None: - # sshkey_id ist a list of ids - self.module.params["sshkey_id"] = self.get_ssh_key_ids() - - if self.module.params["backups"] is not None: - self.module.params["backups"] = "enabled" if self.module.params["backups"] else "disabled" +from ..module_utils.common_instance import AnsibleVultrCommonInstance +from ..module_utils.vultr_v2 import vultr_argument_spec - if self.module.params["vpcs"] is not None: - # attach_vpc is a list of ids used while creating - self.module.params["attach_vpc"] = self.get_vpc_ids() +class AnsibleVultrInstance(AnsibleVultrCommonInstance): def handle_power_status(self, resource, state, action, power_status, force=False, wait_for_state=True): if state == self.module.params["state"] and (resource["power_status"] != power_status or force): self.result["changed"] = True @@ -588,31 +443,9 @@ class AnsibleVultrInstance(AnsibleVultr): resource = self.wait_for_state(resource=resource, key="power_status", states=[power_status]) return resource - def create(self): - param_keys = ("os", "image", "app", "snapshot") - if not any(self.module.params.get(x) is not None for x in param_keys): - self.module.fail_json(msg="missing required arguements, one of the following required: %s" % ", ".join(param_keys)) - return super(AnsibleVultrInstance, self).create() - - def update(self, resource): - user_data = self.get_user_data(resource=resource) - resource["user_data"] = user_data.encode() - - if self.module.params["vpcs"] is not None: - resource["attach_vpc"] = list() - for vpc in list(resource["vpcs"]): - resource["attach_vpc"].append(vpc["id"]) - - # detach_vpc is a list of ids to be detached - resource["detach_vpc"] = list() - self.module.params["detach_vpc"] = self.get_detach_vpcs_ids(resource=resource) - - return super(AnsibleVultrInstance, self).update(resource=resource) - def create_or_update(self): resource = super(AnsibleVultrInstance, self).create_or_update() if resource: - resource = self.wait_for_state(resource=resource, key="status", states=["active"]) resource = self.wait_for_state(resource=resource, key="server_status", states=["none", "locked"], cmp="!=") # Hanlde power status @@ -630,10 +463,15 @@ class AnsibleVultrInstance(AnsibleVultr): return resource - def transform_result(self, resource): - if resource: - resource["user_data"] = self.get_user_data(resource=resource) - return resource + def configure(self): + super(AnsibleVultrInstance, self).configure() + + if self.module.params["state"] != "absent": + if self.module.params.get("firewall_group") is not None: + self.module.params["firewall_group_id"] = self.get_firewall_group()["id"] + + if self.module.params.get("backups") is not None: + self.module.params["backups"] = "enabled" if self.module.params["backups"] else "disabled" def absent(self): resource = self.query() @@ -666,6 +504,7 @@ def main(): user_data=dict(type="str"), ssh_keys=dict(type="list", elements="str", no_log=False), region=dict(type="str", required=True), + user_scheme=dict(type="str", choices=["root", "limited"]), state=dict( choices=[ "present", @@ -713,6 +552,7 @@ def main(): "sshkey_id", "backups", "attach_vpc", + "user_scheme", ], resource_update_param_keys=[ "plan", diff --git a/ansible_collections/vultr/cloud/plugins/modules/instance_info.py b/ansible_collections/vultr/cloud/plugins/modules/instance_info.py index 2a5c311bb..d473eae20 100644 --- a/ansible_collections/vultr/cloud/plugins/modules/instance_info.py +++ b/ansible_collections/vultr/cloud/plugins/modules/instance_info.py @@ -239,8 +239,8 @@ def main(): argument_spec = vultr_argument_spec() argument_spec.update( dict( - region=dict(type="str", aliases=["name"]), - label=dict(type="str"), + region=dict(type="str"), + label=dict(type="str", aliases=["name"]), ) # type: ignore ) diff --git a/ansible_collections/vultr/cloud/plugins/modules/object_storage.py b/ansible_collections/vultr/cloud/plugins/modules/object_storage.py new file mode 100644 index 000000000..32ad4f70a --- /dev/null +++ b/ansible_collections/vultr/cloud/plugins/modules/object_storage.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2024, René Moser <mail@renemoser.net> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: object_storage +short_description: Manages object storages on Vultr +description: + - Manage object storages. +version_added: "1.12.0" +author: + - "René Moser (@resmo)" +options: + label: + description: + - Name of the object storage. + required: true + aliases: [ name ] + type: str + cluster: + description: + - Cluster hostname where the object storage will be created. + required: true + type: str + state: + description: + - State of the object storage. + default: present + choices: [ present, absent] + type: str +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +--- +- name: Ensure an object storage is present + vultr.cloud.object_storage: + label: my object storage + cluster: ewr1.vultrobjects.com + +- name: Ensure an object storage is absent + vultr.cloud.object_storage: + label: my object storage + cluster: ewr1.vultrobjects.com + state: absent +""" + +RETURN = """ +--- +vultr_api: + description: Response from Vultr API with a few additions/modification. + returned: success + type: dict + contains: + api_account: + description: Account used in the ini file to select the key. + returned: success + type: str + sample: default + 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_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_block_storage: + description: Response from Vultr API. + returned: success + type: dict + contains: + date_created: + description: Date the object storage was created. + returned: success + type: str + sample: "2020-10-10T01:56:20+00:00" + id: + description: A unique ID for the object storage. + returned: success + type: str + sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60 + label: + description: The user-supplied label for this object storage. + returned: success + type: str + sample: my object storage + region: + description: The region for this object storage. + returned: success + type: str + sample: ews + status: + description: The status of this object storage. + returned: success + type: str + sample: active + s3_hostname: + description: The Cluster hostname for this object storage. + returned: success + type: str + sample: ewr1.vultrobjects.com + s3_access_key: + description: The object storage access key. + returned: success + type: str + sample: 00example11223344 + s3_secret_key: + description: The object storage secret key. + returned: success + type: str + sample: 00example1122334455667788990011 +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +class AnsibleVultrObjectStorage(AnsibleVultr): + def configure(self): + super(AnsibleVultrObjectStorage, self).configure() + cluster = self.get_cluster() + self.module.params["cluster_id"] = cluster["id"] + # Use region to distinguish labels between regions + self.module.params["region"] = cluster["region"] + + def get_cluster(self): + return self.query_filter_list_by_name( + key_name="hostname", + param_key="cluster", + path="/object-storage/clusters", + result_key="clusters", + fail_not_found=True, + ) + + def create_or_update(self): + resource = super(AnsibleVultrObjectStorage, self).create_or_update() + if resource: + resource = self.wait_for_state(resource=resource, key="status", states=["active"]) + return resource + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + label=dict(type="str", required=True, aliases=["name"]), + cluster=dict(type="str", required=True), + state=dict(type="str", choices=["present", "absent"], default="present"), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + vultr = AnsibleVultrObjectStorage( + module=module, + namespace="vultr_object_storage", + resource_path="/object-storage", + ressource_result_key_singular="object_storage", + resource_create_param_keys=["label", "cluster_id"], + resource_update_param_keys=["label"], + resource_key_name="label", + ) + + if module.params.get("state") == "absent": # type: ignore + vultr.absent() + else: + vultr.present() + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/vultr/cloud/plugins/modules/reserved_ip.py b/ansible_collections/vultr/cloud/plugins/modules/reserved_ip.py index 9bc2e254b..4bf1c66ae 100644 --- a/ansible_collections/vultr/cloud/plugins/modules/reserved_ip.py +++ b/ansible_collections/vultr/cloud/plugins/modules/reserved_ip.py @@ -166,7 +166,6 @@ class AnsibleVultrReservedIp(AnsibleVultr): instance_name = self.module.params["instance_name"] if instance_name is not None: - # Empty string ID means detach instance if len(instance_name) == 0: return "" @@ -187,7 +186,7 @@ class AnsibleVultrReservedIp(AnsibleVultr): return resources["instances"][0]["id"] - def query_list(self, path=None, result_key=None): + def query_list(self, path=None, result_key=None, query_params=None): resources = self.api_query(path=self.resource_path) or dict() resources_filtered = list() diff --git a/ansible_collections/vultr/cloud/plugins/modules/vpc2.py b/ansible_collections/vultr/cloud/plugins/modules/vpc2.py new file mode 100644 index 000000000..c2caa1784 --- /dev/null +++ b/ansible_collections/vultr/cloud/plugins/modules/vpc2.py @@ -0,0 +1,191 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023, René Moser <mail@renemoser.net> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: vpc2 +short_description: Manages VPCs 2.0 on Vultr +description: + - Create and remove VPCs 2.0. +version_added: "1.9.0" +author: "René Moser (@resmo)" +options: + description: + description: + - Description of the VPC. + required: true + aliases: [ name ] + type: str + ip_type: + description: + - Type of the IP version. + - Required if I(state=present). + default: v4 + choices: [ v4 ] + type: str + ip_block: + description: + - The subnet of the VPC. + - Required if I(state=present). + type: str + prefix_length: + description: + - The number of bits for the netmask in CIDR notation, e.g. 24. + - Required if I(state=present). + type: int + region: + description: + - Region the VPC will be related to. + - Required if I(state=present). + type: str + state: + description: + - State of the VPC. + default: present + choices: [ present, absent ] + type: str +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Ensure a VPC is present + vultr.cloud.vpc2: + description: my VPC. + ip_block: 10.99.1.0 + prefix_length: 24 + region: ewr + +- name: Ensure a VPC is absent + vultr.cloud.vpc2: + description: my VPC. + 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_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_vpc2: + description: Response from Vultr API. + returned: success + type: dict + contains: + id: + description: ID of the VPC. + returned: success + type: str + sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60 + description: + description: Description of the VPC. + returned: success + type: str + sample: my vpc + ip_block: + description: Subnet of the VPC. + returned: success + type: str + sample: 10.99.1.0 + prefix_length: + description: The number of bits for the netmask in CIDR notation. + returned: success + type: int + sample: 24 + date_created: + description: Date the VPC was created. + returned: success + type: str + sample: "2023-08-20T19:39:20+00:00" + region: + description: The region the VPC is located in. + returned: success + type: str + sample: ewr +""" + +from ansible.module_utils.basic import AnsibleModule + +from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec + + +def main(): + argument_spec = vultr_argument_spec() + argument_spec.update( + dict( + description=dict(type="str", required=True, aliases=["name"]), + ip_type=dict(type="str", choices=["v4"], default="v4"), + ip_block=dict(type="str"), + prefix_length=dict(type="int"), + region=dict(type="str"), + state=dict(type="str", choices=["present", "absent"], default="present"), + ) # type: ignore + ) + + module = AnsibleModule( + argument_spec=argument_spec, + required_if=( + ( + "state", + "present", + ("ip_type", "ip_block", "prefix_length", "region"), + ), + ), + supports_check_mode=True, + ) + + vultr = AnsibleVultr( + module=module, + namespace="vultr_vpc2", + resource_path="/vpc2", + ressource_result_key_singular="vpc", + resource_create_param_keys=[ + "description", + "ip_type", + "ip_block", + "prefix_length", + "region", + ], + resource_update_param_keys=["description"], + resource_key_name="description", + resource_update_method="PUT", + ) + + if module.params.get("state") == "absent": # type: ignore + vultr.absent() + else: + vultr.present() + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/vultr/cloud/plugins/modules/vpc2_info.py b/ansible_collections/vultr/cloud/plugins/modules/vpc2_info.py new file mode 100644 index 000000000..c71c25d14 --- /dev/null +++ b/ansible_collections/vultr/cloud/plugins/modules/vpc2_info.py @@ -0,0 +1,122 @@ +#!/usr/bin/python +# +# Copyright (c) 2023, René Moser <mail@renemoser.net> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = """ +--- +module: vpc2_info +short_description: Gather information about the Vultr VPCs 2.0 +description: + - Gather information about VPCs 2.0 available. +version_added: "1.9.0" +author: + - "René Moser (@resmo)" +extends_documentation_fragment: + - vultr.cloud.vultr_v2 +""" + +EXAMPLES = """ +- name: Gather Vultr VPCs 2.0 information + vultr.cloud.vpc2_info: + register: result + +- name: Print the gathered information + ansible.builtin.debug: + var: result.vultr_vpc2_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_endpoint: + description: Endpoint used for the API requests. + returned: success + type: str + sample: "https://api.vultr.com/v2" +vultr_vpc2_info: + description: Response from Vultr API as list. + returned: success + type: list + contains: + id: + description: ID of the VPC. + returned: success + type: str + sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60 + description: + description: Description of the VPC. + returned: success + type: str + sample: my vpc + ip_block: + description: Subnet of the VPC. + returned: success + type: str + sample: 10.99.1.0 + prefix_length: + description: The number of bits for the netmask in CIDR notation. + returned: success + type: int + sample: 24 + date_created: + description: Date the VPC was created. + returned: success + type: str + sample: "2023-08-20T19:39:20+00:00" + region: + description: The region the VPC is located in. + returned: success + type: str + sample: ewr +""" + +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_vpc2_info", + resource_path="/vpc2", + ressource_result_key_singular="vpc", + ) + + vultr.get_result(vultr.query_list()) + + +if __name__ == "__main__": + main() |