Init: mediaserver

This commit is contained in:
2023-02-08 12:13:28 +01:00
parent 848bc9739c
commit f7c23d4ba9
31914 changed files with 6175775 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: account_info
short_description: Get information about the Vultr account
description:
- Get infos about account balance, charges and payments.
version_added: "1.0.0"
author: "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr account infos
vultr.cloud.account_info:
register: result
- name: Print the infos
ansible.builtin.debug:
var: result.vultr_account_info
"""
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_account_info:
description: Response from Vultr API.
returned: success
type: dict
contains:
balance:
description: Your account balance.
returned: success
type: float
sample: -214.69
pending_charges:
description: Charges pending.
returned: success
type: float
sample: 57.03
last_payment_date:
description: Date of the last payment.
returned: success
type: str
sample: "2021-11-07T05:57:59-05:00"
last_payment_amount:
description: The amount of the last payment transaction.
returned: success
type: float
sample: -250.0
"""
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_account_info",
resource_path="/account",
ressource_result_key_singular="account",
)
vultr.get_result(vultr.query_by_id(resource_id=""))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,271 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: block_storage
short_description: Manages block storage volumes on Vultr
description:
- Manage block storage volumes.
version_added: "1.0.0"
author:
- "René Moser (@resmo)"
- "Yanis Guenane (@Spredzy)"
options:
label:
description:
- Name of the block storage volume.
required: true
aliases: [ name ]
type: str
size_gb:
description:
- Size of the block storage volume in GB.
- Required if I(state) is present.
- If it is larger than the volume's current size, the volume will be resized.
aliases: [ size ]
type: int
block_type:
description:
- The type of block storage volume that will be created.
default: high_perf
choices: [ high_perf, storage_opt ]
type: str
version_added: "1.2.0"
region:
description:
- Region the block storage volume is deployed into.
- Required if I(state) is present.
type: str
state:
description:
- State of the block storage volume.
default: present
choices: [ present, absent]
type: str
attached_to_instance:
description:
- The ID of the server instance the volume is attached to.
type: str
live:
description:
- Whether the volume should be attached/detached without restarting the instance.
type: bool
default: false
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
---
- name: Ensure a block storage volume is present
vultr.cloud.block_storage:
name: myvolume
size_gb: 10
block_type: storage_opt
region: ams
- name: Ensure a block storage volume is absent
vultr.cloud.block_storage:
name: myvolume
state: absent
- name: Ensure a block storage volume exists and is attached a server instance
vultr.cloud.block_storage:
name: myvolume
attached_to_instance: cb676a46-66fd-4dfb-b839-443f2e6c0b60
size_gb: 50
block_type: high_perf
- name: Ensure a block storage volume exists but is not attached to any server instance
vultr.cloud.block_storage:
name: myvolume
attached_to_instance: ""
size_gb: 50
block_type: high_perf
"""
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:
attached_to_instance:
description: The ID of the server instance the volume is attached to.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
cost:
description: Cost per month for the volume.
returned: success
type: float
sample: 1.00
date_created:
description: Date when the volume was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
id:
description: ID of the block storage volume.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
label:
description: Label of the volume.
returned: success
type: str
sample: my volume
region:
description: Region the volume was deployed into.
returned: success
type: str
sample: ews
size_gb:
description: Information about the volume size in GB.
returned: success
type: int
sample: 50
block_type:
description: HDD or NVMe (storage_opt or high_perf)
returned: success
type: str
sample: high_perf
status:
description: Status about the deployment of the volume.
returned: success
type: str
sample: active
mount_id:
description: Mount ID of the volume.
returned: success
type: str
sample: ewr-2f5d7a314fe44f
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrBlockStorage(AnsibleVultr):
def update(self, resource):
current_size = resource["size_gb"]
desired_size = self.module.params["size_gb"]
if desired_size < current_size:
self.module.params["size_gb"] = current_size
self.module.warn("Shrinking is not supported: current size %s, desired size %s" % (current_size, desired_size))
return super(AnsibleVultrBlockStorage, self).update(resource=resource)
def present(self):
resource = self.create_or_update() or dict()
instance_to_attach = self.module.params.get("attached_to_instance")
if instance_to_attach is None:
# exit and show result if no attach/detach needed.
self.get_result(resource)
instance_attached = resource.get("attached_to_instance", "")
if instance_attached != instance_to_attach:
self.result["changed"] = True
mode = "detach" if not instance_to_attach else "attach"
self.result["diff"]["after"].update({"attached_to_instance": instance_to_attach})
data = {
"instance_id": instance_to_attach if instance_to_attach else None,
"live": self.module.params.get("live"),
}
if not self.module.check_mode:
self.api_query(
path="%s/%s/%s" % (self.resource_path, resource[self.resource_key_id], mode),
method="POST",
data=data,
)
resource = self.query_by_id(resource_id=resource[self.resource_key_id])
self.get_result(resource)
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
label=dict(type="str", required=True, aliases=["name"]),
size_gb=dict(type="int", aliases=["size"]),
block_type=dict(type="str", choices=["high_perf", "storage_opt"], default="high_perf"),
region=dict(type="str"),
state=dict(type="str", choices=["present", "absent"], default="present"),
attached_to_instance=dict(type="str"),
live=dict(type="bool", default=False),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[
["state", "present", ["size_gb", "region"]],
],
)
vultr = AnsibleVultrBlockStorage(
module=module,
namespace="vultr_block_storage",
resource_path="/blocks",
ressource_result_key_singular="block",
resource_create_param_keys=["label", "size_gb", "region", "block_type"],
resource_update_param_keys=["size_gb"],
resource_key_name="label",
# Query details information about block type
resource_get_details=True,
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,139 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: block_storage_info
short_description: Get information about the Vultr block storage
version_added: "1.0.0"
description:
- Get infos about block storages available.
author:
- "René Moser (@resmo)"
- "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr block_storage infos
vultr.cloud.block_storage_info:
register: result
- name: Print the infos
ansible.builtin.debug:
var: result.vultr_block_storage_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_block_storage_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
attached_to_instance:
description: The ID of the server instance the volume is attached to.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
cost:
description: Cost per month for the volume.
returned: success
type: float
sample: 1.00
date_created:
description: Date when the volume was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
id:
description: ID of the block storage volume.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
label:
description: Label of the volume.
returned: success
type: str
sample: my volume
region:
description: Region the volume was deployed into.
returned: success
type: str
sample: ews
size_gb:
description: Information about the volume size in GB.
returned: success
type: int
sample: 50
status:
description: Status about the deployment of the volume.
returned: success
type: str
sample: active
mount_id:
description: Mount ID of the volume.
returned: success
type: str
sample: ewr-2f5d7a314fe44f
"""
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_block_storage_info",
resource_path="/blocks",
ressource_result_key_singular="block",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,155 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: dns_domain
short_description: Manages DNS domains on Vultr
description:
- Create and remove DNS domains.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
domain:
description:
- The domain name.
required: true
aliases: [ name ]
type: str
ip:
description:
- The default server IP.
- Use M(vultr.cloud.dns_record) to change it once the domain is created.
- Required if C(state=present).
type: str
aliases: [ server_ip ]
dns_sec:
description:
- Ensure DNSSEC is enabled or disabled.
type: str
choices: [ enabled, disabled ]
default: disabled
state:
description:
- State of the DNS domain.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure a domain exists with DNSSEC
vultr.cloud.dns_domain:
name: example.com
dns_sec: enabled
server_ip: 10.10.10.10
- name: Ensure a domain is absent
vultr.cloud.dns_domain:
name: example.com
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_dns_domain:
description: Response from Vultr API.
returned: success
type: dict
contains:
name:
description: Name of the DNS Domain.
returned: success
type: str
sample: example.com
dns_sec:
description: Whether DNSSEC is enabled or disabled.
returned: success
type: str
sample: disabled
date_created:
description: Date the DNS domain was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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(
domain=dict(type="str", required=True, aliases=["name"]),
ip=dict(type="str", aliases=["server_ip"]),
dns_sec=dict(type="str", choices=["enabled", "disabled"], default="disabled"),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
("state", "present", ["ip"]),
],
supports_check_mode=True,
)
vultr = AnsibleVultr(
module=module,
namespace="vultr_dns_domain",
resource_path="/domains",
ressource_result_key_singular="domain",
resource_create_param_keys=["domain", "dns_sec", "ip"],
resource_update_param_keys=["domain", "dns_sec"],
resource_key_name="domain",
resource_key_id="domain",
resource_update_method="PUT",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,109 @@
#!/usr/bin/python
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: dns_domain_info
short_description: Gather information about the Vultr DNS domains
description:
- Gather information about DNS domains available.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr DNS domains information
vultr.cloud.dns_domains_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_dns_domain_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_dns_domain_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
domain:
description: Name of the DNS Domain.
returned: success
type: str
sample: example.com
dns_sec:
description: Whether DNSSEC is enabled or disabled.
returned: success
type: str
sample: disabled
date_created:
description: Date the DNS domain was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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_dns_domain_info",
resource_path="/domains",
ressource_result_key_singular="domain",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,267 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: dns_record
short_description: Manages DNS records on Vultr
description:
- Create, update and remove DNS records.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
name:
description:
- The record name.
type: str
default: ""
domain:
description:
- The domain the record is related to.
type: str
required: true
type:
description:
- Type of the record.
default: A
choices:
- A
- AAAA
- CNAME
- NS
- MX
- SRV
- TXT
- CAA
- SSHFP
aliases: [ record_type ]
type: str
data:
description:
- Data of the record.
- Required if C(state=present).
type: str
ttl:
description:
- TTL of the record.
default: 300
type: int
priority:
description:
- Priority of the record.
type: int
multiple:
description:
- Whether to use more than one record with similar I(name) including no name and I(type).
- Only allowed for a few record types, e.g. C(type=A), C(type=NS) or C(type=MX).
- I(data) will not be updated, instead it is used as a key to find existing records.
default: no
type: bool
state:
description:
- State of the DNS record.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure an A record exists
vultr.cloud.dns_record:
name: www
domain: example.com
data: 10.10.10.10
ttl: 3600
- name: Ensure a second A record exists for round robin LB
vultr.cloud.dns_record:
name: www
domain: example.com
data: 10.10.10.11
ttl: 60
multiple: true
- name: Ensure a CNAME record exists
vultr.cloud.dns_record:
name: web
type: CNAME
domain: example.com
data: www.example.com
- name: Ensure MX record exists
vultr.cloud.dns_record:
type: MX
domain: example.com
data: "{{ item.data }}"
priority: "{{ item.priority }}"
multiple: true
with_items:
- { data: mx1.example.com, priority: 10 }
- { data: mx2.example.com, priority: 10 }
- { data: mx3.example.com, priority: 20 }
- name: Ensure a record is absent
vultr.cloud.dns_record:
name: www
domain: example.com
state: absent
- name: Ensure one MX record is absent if multiple exists
vultr.cloud.dns_record:
record_type: MX
domain: example.com
data: mx1.example.com
multiple: true
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"
dns_record:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: The ID of the DNS record.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
name:
description: The name of the DNS record.
returned: success
type: str
sample: web
type:
description: The name of the DNS record.
returned: success
type: str
sample: A
data:
description: Data of the DNS record.
returned: success
type: str
sample: 10.10.10.10
priority:
description: Priority of the DNS record.
returned: success
type: int
sample: 10
ttl:
description: Time to live of the DNS record.
returned: success
type: int
sample: 300
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
RECORD_TYPES = ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV", "CAA", "SSHFP"]
class AnsibleVultrDnsRecord(AnsibleVultr):
def query(self):
multiple = self.module.params.get("multiple")
name = self.module.params.get("name")
data = self.module.params.get("data")
record_type = self.module.params.get("type")
result = dict()
for resource in self.query_list():
if resource.get("type") != record_type:
continue
if resource.get("name") == name:
if not multiple:
if result:
self.module.fail_json(
msg="More than one record with record_type=%s and name=%s params. "
"Use multiple=yes for more than one record." % (record_type, name)
)
else:
result = resource
elif resource.get("data") == data:
return resource
return result
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
domain=dict(type="str", required=True),
name=dict(type="str", default=""),
state=dict(type="str", choices=["present", "absent"], default="present"),
ttl=dict(type="int", default=300),
type=dict(type="str", choices=RECORD_TYPES, default="A", aliases=["record_type"]),
multiple=dict(type="bool", default=False),
priority=dict(type="int"),
data=dict(type="str"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
("state", "present", ["data"]),
("multiple", True, ["data"]),
],
supports_check_mode=True,
)
vultr = AnsibleVultrDnsRecord(
module=module,
namespace="vultr_dns_record",
resource_path="/domains/%s/records" % module.params.get("domain"), # type: ignore
ressource_result_key_singular="record",
resource_create_param_keys=["name", "ttl", "data", "priority", "type"],
resource_update_param_keys=["name", "ttl", "data", "priority"],
resource_key_name="name",
) # type: ignore
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,138 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: firewall_group
short_description: Manages firewall groups on Vultr
description:
- Create and remove firewall groups.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
description:
description:
- Description of the firewall group.
required: true
aliases: [ name ]
type: str
state:
description:
- State of the firewall group.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: ensure a firewall group is present
vultr.cloud.firewall_group:
description: my http firewall.
- name: ensure a firewall group is absent
vultr.cloud.firewall_group:
description: my http firewall.
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_firewall_group:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the firewall group.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
description:
description: Description (name) of the firewall group
returned: success
type: str
sample: my firewall group
date_created:
description: Date the firewall group was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
date_modified:
description: Date the firewall group was modified.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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"]),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr = AnsibleVultr(
module=module,
namespace="vultr_firewall_group",
resource_path="/firewalls",
ressource_result_key_singular="firewall_group",
resource_create_param_keys=["description"],
resource_update_param_keys=["description"],
resource_key_name="description",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,114 @@
#!/usr/bin/python
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: firewall_group_info
short_description: Gather information about the Vultr firewall groups
description:
- Gather information about firewall groups available.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr firewall groups information
vultr.cloud.firewall_group_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_firewall_group_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_firewall_group_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the firewall group.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
description:
description: Name of the firewall group.
returned: success
type: str
sample: my firewall group
date_created:
description: Date the firewall group was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
date_modified:
description: Date the firewall group was modified.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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_firewall_group_info",
resource_path="/firewalls",
ressource_result_key_singular="firewall_group",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,297 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: firewall_rule
short_description: Manages firewall rules on Vultr
description:
- Create and remove firewall rules.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
group:
description:
- Name of the firewall group.
required: true
type: str
ip_type:
description:
- IP address version
choices: [ v4, v6 ]
type: str
default: v4
protocol:
description:
- Protocol of the firewall rule.
choices: [ icmp, tcp, udp, gre, esp, ah ]
type: str
default: tcp
subnet:
description:
- The network or IP, e.g. 192.0.2.123 or 0.0.0.0.
- Mutally exclusive with I(source).
type: str
subnet_size:
description:
- The number of bits for the netmask in CIDR notation, e.g. C(32).
type: int
port:
description:
- Single port or port range, e.g. C(80) or C(8000:8080).
- Required if I(protocol) is tcp or udp and I(state=present).
aliases: [ port_range ]
type: str
source:
description:
- Possible values are C(cloudflare) or a loadbalancer label.
- Mutally exclusive with I(subnet).
type: str
notes:
description:
- Notes of the firewall rule.
type: str
state:
description:
- State of the firewall rule.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure a firewall rule is present
vultr.cloud.firewall_rule:
group: web
port: 80
protocol: tcp
ip_type: v4
subnet: "0.0.0.0"
subnet_size: 0
notes: "open HTTP to the world"
- name: Ensure a firewall rule with port range is present
vultr.cloud.firewall_rule:
group: apps
port: "8000:8999"
protocol: tcp
ip_type: v4
subnet: "10.10.10.0"
subnet_size: 24
- name: Ensure a firewall rule is absent
vultr.cloud.firewall_rule:
group: apps
port: "443"
protocol: tcp
ip_type: v6
subnet: "::"
subnet_size: 0
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_firewall_rule:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the firewall rule.
returned: success
type: int
sample: 1
action:
description: Action of the firewall rule.
returned: success
type: str
sample: accept
protocol:
description: Protocol of the firewall rule.
returned: success
type: str
sample: tcp
port:
description: Port or port range of the firewall rule.
returned: success
type: str
sample: "80"
source:
description: Source string of the firewall rule.
returned: success
type: str
sample: cloudflare
notes:
description: Supplied description of the firewall rule.
returned: success
type: str
sample: my rule
subnet:
description: Subnet of the firewall rule.
returned: success
type: str
sample: 0.0.0.0
subnet_size:
description: Size of the subnet of the firewall rule.
returned: success
type: int
sample: 0
ip_type:
description: IP type of the firewall rule.
returned: success
type: str
sample: v4
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrFirewallRule(AnsibleVultr):
def get_firewall_group(self):
return self.query_filter_list_by_name(
key_name="description",
param_key="group",
path="/firewalls",
result_key="firewall_groups",
fail_not_found=True,
)
def get_load_balancer(self):
return self.query_filter_list_by_name(
key_name="label",
param_key="source",
path="/load-balancers",
result_key="load_balancers",
fail_not_found=True,
)
def configure(self):
# Set firewall group id to resource path, ensures firewall group exists
self.resource_path = self.resource_path % self.get_firewall_group()["id"]
# Set loadbalancer ID for source
source = self.module.params.get("source")
if source is not None and source != "cloudflare":
self.module.params["source"] = self.get_load_balancer()["id"]
def query(self):
result = dict()
for resource in self.query_list():
for key in (
"ip_type",
"protocol",
"port",
"source",
"subnet",
"subnet_size",
):
param = self.module.params.get(key)
if param is None:
continue
if resource.get(key) != param:
break
else:
result = resource
if result:
break
return result
def update(self, resource):
return resource
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
notes=dict(type="str"),
group=dict(type="str", required=True),
port=dict(type="str", aliases=["port_range"]),
subnet=dict(type="str"),
subnet_size=dict(type="int"),
source=dict(type="str"),
protocol=dict(
type="str",
choices=["icmp", "tcp", "udp", "gre", "esp", "ah"],
default="tcp",
),
ip_type=dict(type="str", choices=["v4", "v6"], default="v4"),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_one_of=(("source", "subnet"),),
mutually_exclusive=(("source", "subnet"),),
required_together=(("subnet", "subnet_size"),),
supports_check_mode=True,
)
vultr = AnsibleVultrFirewallRule(
module=module,
namespace="vultr_firewall_rule",
resource_path="/firewalls/%s/rules",
ressource_result_key_singular="firewall_rule",
resource_key_name="##unused##",
resource_create_param_keys=[
"notes",
"port",
"subnet",
"subnet_size",
"source",
"protocol",
"ip_type",
],
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,162 @@
#!/usr/bin/python
#
# Copyright (c) 2022, 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: firewall_rule_info
short_description: Gather information about the Vultr firewall rules
description:
- Gather information about firewall rules available.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
group:
description:
- Name of the firewall group.
required: true
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr firewall rule information
vultr.cloud.firewall_rule_info:
group: my group
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_firewall_rule_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_firewall_rule_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the firewall rule.
returned: success
type: int
sample: 1
action:
description: Action of the firewall rule.
returned: success
type: str
sample: accept
protocol:
description: Protocol of the firewall rule.
returned: success
type: str
sample: tcp
port:
description: Port or port range of the firewall rule.
returned: success
type: str
sample: "80"
source:
description: Source string of the firewall rule.
returned: success
type: str
sample: cloudflare
notes:
description: Supplied description of the firewall rule.
returned: success
type: str
sample: my rule
subnet:
description: Subnet of the firewall rule.
returned: success
type: str
sample: 0.0.0.0
subnet_size:
description: Size of the subnet of the firewall rule.
returned: success
type: int
sample: 0
ip_type:
description: IP type of the firewall rule.
returned: success
type: str
sample: v4
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrFirewallRuleInfo(AnsibleVultr):
def get_firewall_group(self):
return self.query_filter_list_by_name(
key_name="description",
param_key="group",
path="/firewalls",
result_key="firewall_groups",
fail_not_found=True,
)
def configure(self):
# Set firewall group id to resource path, ensures firewall group exists
self.resource_path = self.resource_path % self.get_firewall_group()["id"]
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
group=dict(type="str", required=True),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr = AnsibleVultrFirewallRuleInfo(
module=module,
namespace="vultr_firewall_rule_info",
resource_path="/firewalls/%s/rules",
ressource_result_key_singular="firewall_rule",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,712 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: instance
short_description: Manages server instances on Vultr.
description:
- Manage server instances on Vultr.
version_added: "1.1.0"
author:
- "René Moser (@resmo)"
options:
label:
description:
- Name of the instance.
required: true
aliases: [ name ]
type: str
hostname:
description:
- The hostname to assign to this instance.
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
firewall_group:
description:
- The firewall group description to assign this instance to.
type: str
plan:
description:
- The plan name to use for the instance.
- Required if the instance does not yet exist.
type: str
activation_email:
description:
- Whether to send an activation email when the instance is ready or not.
- Only considered on creation.
type: bool
default: false
backups:
description:
- Whether to enable automatic backups or not.
type: bool
ddos_protection:
description:
- Whether to enable ddos_protection or not.
type: bool
enable_ipv6:
description:
- Whether to enable IPv6 or not.
type: bool
tags:
description:
- Tags for the instance.
type: list
elements: str
user_data:
description:
- User data to be passed to the instance.
type: str
startup_script:
description:
- Name or ID of the startup script to execute on boot.
- Only considered while creating the instance.
type: str
ssh_keys:
description:
- List of SSH key names passed to the instance on creation.
type: list
elements: str
snapshot:
description:
- Description or ID of the snapshot.
- Only considered while creating the instance.
type: str
version_added: "1.7.0"
reserved_ipv4:
description:
- IP address of the floating IP to use as the main IP of this instance.
- Only considered on creation.
type: str
region:
description:
- Region the instance is deployed into.
type: str
required: true
vpcs:
description:
- A list of VPCs identified by their description to be assigned to the instance.
type: list
elements: str
version_added: "1.5.0"
state:
description:
- State of the instance.
default: present
choices: [ present, absent, started, stopped, restarted ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
---
- name: Create an instance using OS
vultr.cloud.instance:
label: my web server
hostname: my-hostname
user_data: |
#cloud-config
packages:
- nginx
firewall_group: my firewall group
plan: vc2-1c-2gb
ddos_protection: true
backups: true
enable_ipv6: true
ssh_keys:
- my ssh key
vpcs:
- my vpc description
tags:
- web
- project-genesis
region: ams
os: Debian 11 x64 (bullseye)
- name: Deploy an instance of a marketplace app
vultr.cloud.instance:
label: git-server
hostname: git
firewall_group: my firewall group
plan: vc2-1c-2gb
ddos_protection: true
backups: true
enable_ipv6: true
region: ams
image: Gitea on Ubuntu 20.04
- name: Stop an existing instance
vultr.cloud.instance:
label: my web server
region: ams
state: stopped
- name: Start an existing instance
vultr.cloud.instance:
label: my web server
region: ams
state: started
- name: Delete an instance
vultr.cloud.instance:
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_instance:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the instance.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
v6_main_ip:
description: IPv6 of the instance.
returned: success
type: str
sample: ""
v6_network:
description: IPv6 network of the instance.
returned: success
type: str
sample: ""
v6_network_size:
description: IPv6 network size of the instance.
returned: success
type: int
sample: 0
main_ip:
description: IPv4 of the instance.
returned: success
type: str
sample: 95.179.189.95
netmask_v4:
description: Netmask IPv4 of the instance.
returned: success
type: str
sample: 255.255.254.0
hostname:
description: Hostname of the instance.
returned: success
type: str
sample: vultr.guest
internal_ip:
description: Internal IP of the instance.
returned: success
type: str
sample: ""
gateway_v4:
description: Gateway IPv4.
returned: success
type: str
sample: 95.179.188.1
kvm:
description: KVM of the instance.
returned: success
type: str
sample: "https://my.vultr.com/subs/vps/novnc/api.php?data=..."
disk:
description: Disk size of the instance.
returned: success
type: int
sample: 25
allowed_bandwidth:
description: Allowed bandwidth of the instance.
returned: success
type: int
sample: 1000
vcpu_count:
description: vCPUs of the instance.
returned: success
type: int
sample: 1
firewall_group_id:
description: Firewall group ID of the instance.
returned: success
type: str
sample: ""
plan:
description: Plan of the instance.
returned: success
type: str
sample: vc2-1c-1gb
image_id:
description: Image ID of the instance.
returned: success
type: str
sample: ""
os_id:
description: OS ID of the instance.
returned: success
type: int
sample: 186
app_id:
description: App ID of the instance.
returned: success
type: int
sample: 37
date_created:
description: Date when the instance was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
label:
description: Label of the instance.
returned: success
type: str
sample: my instance
region:
description: Region the instance was deployed into.
returned: success
type: str
sample: ews
status:
description: Status about the deployment of the instance.
returned: success
type: str
sample: active
server_status:
description: Server status of the instance.
returned: success
type: str
sample: installingbooting
power_status:
description: Power status of the instance.
returned: success
type: str
sample: running
ram:
description: RAM in MB of the instance.
returned: success
type: int
sample: 1024
os:
description: OS of the instance.
returned: success
type: str
sample: Application
tags:
description: Tags of the instance.
returned: success
type: list
sample: [ my-tag ]
features:
description: Features of the instance.
returned: success
type: list
sample: [ ddos_protection, ipv6, auto_backups ]
user_data:
description: Base64 encoded user data (cloud init) of the instance.
returned: success
type: str
sample: I2Nsb3VkLWNvbmZpZwpwYWNrYWdlczoKICAtIGh0b3AK
backups:
description: Whether backups are enabled or disabled.
returned: success
type: str
sample: enabled
version_added: "1.3.0"
ddos_protection:
description: Whether DDOS protections is enabled or not.
returned: success
type: bool
sample: true
version_added: "1.3.0"
enable_ipv6:
description: Whether IPv6 is enabled or not.
returned: success
type: bool
sample: true
version_added: "1.3.0"
vpcs:
description: List of VPCs attached.
returned: success
type: list
version_added: "1.5.0"
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
ip_address:
description: IP assigned from the VPC.
returned: success
type: str
sample: "192.168.23.3"
mac_address:
description: MAC address of the network interface.
returned: success
type: str
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"
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()
def handle_power_status(self, resource, state, action, power_status, force=False):
if state == self.module.params["state"] and (resource["power_status"] != power_status or force):
self.result["changed"] = True
if not self.module.check_mode:
self.api_query(
path="%s/%s/%s" % (self.resource_path, resource[self.resource_key_id], action),
method="POST",
)
resource = self.wait_for_state(resource=resource, key="power_status", state=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", state="active")
resource = self.wait_for_state(resource=resource, key="server_status", state="locked", cmp="!=")
# Hanlde power status
resource = self.handle_power_status(resource=resource, state="stopped", action="halt", power_status="stopped")
resource = self.handle_power_status(resource=resource, state="started", action="start", power_status="running")
resource = self.handle_power_status(resource=resource, state="restarted", action="reboot", power_status="running", force=True)
return resource
def transform_result(self, resource):
if resource:
resource["user_data"] = self.get_user_data(resource=resource)
return resource
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),
ddos_protection=dict(type="bool"),
backups=dict(type="bool"),
enable_ipv6=dict(type="bool"),
tags=dict(type="list", elements="str"),
vpcs=dict(type="list", elements="str"),
reserved_ipv4=dict(type="str"),
firewall_group=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",
"started",
"stopped",
"restarted",
],
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 = AnsibleVultrInstance(
module=module,
namespace="vultr_instance",
resource_path="/instances",
ressource_result_key_singular="instance",
resource_create_param_keys=[
"label",
"hostname",
"plan",
"app_id",
"os_id",
"iso_id",
"image_id",
"snapshot_id",
"script_id",
"region",
"enable_ipv6",
"reserved_ipv4",
"firewall_group_id",
"user_data",
"tags",
"activation_email",
"ddos_protection",
"sshkey_id",
"backups",
"attach_vpc",
],
resource_update_param_keys=[
"plan",
"tags",
"firewall_group_id",
"enable_ipv6",
"ddos_protection",
"backups",
"user_data",
"attach_vpc",
"detach_vpc",
],
resource_key_name="label",
)
state = module.params.get("state") # type: ignore
if state == "absent":
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,271 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: instance_info
short_description: Get information about the Vultr instances
description:
- Get infos about available instances.
version_added: "1.5.0"
author:
- "René Moser (@resmo)"
options:
label:
description:
- Name of the instance.
aliases: [ name ]
type: str
region:
description:
- Filter instances by region.
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr instance infos of region ams
vultr.cloud.instances_info:
region: ams
- name: Get Vultr instance infos of a single host
vultr.cloud.instances_info:
label: myhost
- name: Get all Vultr instance infos
vultr.cloud.instances_info:
register: results
- name: Print the gathered infos
ansible.builtin.debug:
var: results.vultr_instance_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_instance_info:
description: Response from Vultr API as list.
returned: available
type: list
contains:
id:
description: ID of the instance.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
v6_main_ip:
description: IPv6 of the instance.
returned: success
type: str
sample: ""
v6_network:
description: IPv6 network of the instance.
returned: success
type: str
sample: ""
v6_network_size:
description: IPv6 network size of the instance.
returned: success
type: int
sample: 0
main_ip:
description: IPv4 of the instance.
returned: success
type: str
sample: 95.179.189.95
netmask_v4:
description: Netmask IPv4 of the instance.
returned: success
type: str
sample: 255.255.254.0
hostname:
description: Hostname of the instance.
returned: success
type: str
sample: vultr.guest
internal_ip:
description: Internal IP of the instance.
returned: success
type: str
sample: ""
gateway_v4:
description: Gateway IPv4.
returned: success
type: str
sample: 95.179.188.1
kvm:
description: KVM of the instance.
returned: success
type: str
sample: "https://my.vultr.com/subs/vps/novnc/api.php?data=..."
disk:
description: Disk size of the instance.
returned: success
type: int
sample: 25
allowed_bandwidth:
description: Allowed bandwidth of the instance.
returned: success
type: int
sample: 1000
vcpu_count:
description: vCPUs of the instance.
returned: success
type: int
sample: 1
firewall_group_id:
description: Firewall group ID of the instance.
returned: success
type: str
sample: ""
plan:
description: Plan of the instance.
returned: success
type: str
sample: vc2-1c-1gb
image_id:
description: Image ID of the instance.
returned: success
type: str
sample: ""
os_id:
description: OS ID of the instance.
returned: success
type: int
sample: 186
app_id:
description: App ID of the instance.
returned: success
type: int
sample: 37
date_created:
description: Date when the instance was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
label:
description: Label of the instance.
returned: success
type: str
sample: my instance
region:
description: Region the instance was deployed into.
returned: success
type: str
sample: ews
status:
description: Status about the deployment of the instance.
returned: success
type: str
sample: active
server_status:
description: Server status of the instance.
returned: success
type: str
sample: installingbooting
power_status:
description: Power status of the instance.
returned: success
type: str
sample: running
ram:
description: RAM in MB of the instance.
returned: success
type: int
sample: 1024
os:
description: OS of the instance.
returned: success
type: str
sample: Application
tags:
description: Tags of the instance.
returned: success
type: list
sample: [ my-tag ]
features:
description: Features of the instance.
returned: success
type: list
sample: [ ddos_protection, ipv6, auto_backups ]
user_data:
description: Base64 encoded user data (cloud init) of the instance.
returned: success
type: str
sample: I2Nsb3VkLWNvbmZpZwpwYWNrYWdlczoKICAtIGh0b3AK
"""
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(
region=dict(type="str", aliases=["name"]),
label=dict(type="str"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr = AnsibleVultr(
module=module,
namespace="vultr_instance_info",
resource_path="/instances",
ressource_result_key_singular="instance",
ressource_result_key_plural="instances",
)
query_params = dict()
if module.params["region"] is not None: # type: ignore
query_params.update({"region": module.params["region"]}) # type: ignore
if module.params["label"] is not None: # type: ignore
query_params.update({"label": module.params["label"]}) # type: ignore
vultr.get_result(vultr.query_list(query_params=query_params))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,115 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: os_info
short_description: Get information about the Vultr operation systems
description:
- Get infos about operating systems available to boot servers.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr OSes infos
vultr.cloud.os_info:
register: results
- name: Print the gathered infos
ansible.builtin.debug:
var: results.vultr_os_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_os_info:
description: Response from Vultr API as list.
returned: available
type: list
contains:
arch:
description: OS Architecture.
returned: success
type: str
sample: x64
family:
description: OS family.
returned: success
type: str
sample: openbsd
name:
description: OS name.
returned: success
type: str
sample: OpenBSD 6 x64
windows:
description: OS is a MS Windows.
returned: success
type: bool
"""
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_os_info",
resource_path="/os",
ressource_result_key_singular="os",
ressource_result_key_plural="os",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,140 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: plan_info
short_description: Gather information about the Vultr plans
description:
- Gather information about plans available to boot servers.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr plans information
vultr.cloud.plan_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_plan_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_plan_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the plan.
returned: success
type: str
sample: vhf-8c-32gb
vcpu_count:
description: Amount of CPUs.
returned: success
type: int
sample: 8
ram:
description: Amount of RAM in MB.
returned: success
type: int
sample: 32768
disk:
description: Disk size in GB.
returned: success
type: int
sample: 512
disk_count:
description: Amount of disks.
returned: success
type: int
sample: 1
bandwidth:
description: Bandwidth in MB.
returned: success
type: int
sample: 6144
monthly_cost:
description: Monthly cost in $.
returned: success
type: int
sample: 192
type:
description: Type of plan.
returned: success
type: str
sample: vhf
locations:
description: List of locations the plan is available in.
returned: success
type: list
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_plan_info",
resource_path="/plans",
ressource_result_key_singular="plan",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,153 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019, Nate River <vitikc@gmail.com>
# Copyright (c) 2020, Simon Baerlocher <s.baerlocher@sbaerlocher.ch>
# Copyright (c) 2021, 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: plan_metal_info
short_description: Gather information about the Vultr bare metal plans
description:
- Gather information about plans available to boot servers.
version_added: "1.0.0"
author:
- "Nate River (@vitikc)"
- "Simon Baerlocher (@sbaerlocher)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr bare metal plans information
vultr.cloud.plan_metal_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_plan_metal_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_plan_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the plan.
returned: success
type: str
sample: vbm-4c-32gb
cpu_count:
description: Amount of CPUs.
returned: success
type: int
sample: 4
cpu_threads:
description: Amount of CPU threads.
returned: success
type: int
sample: 8
cpu_model:
description: CPU model.
returned: success
type: str
sample: E3-1270v6
ram:
description: Amount of RAM in MB.
returned: success
type: int
sample: 32768
disk:
description: Disk size in GB.
returned: success
type: int
sample: 240
disk_count:
description: Amount of disks.
returned: success
type: int
sample: 2
bandwidth:
description: Bandwidth in MB.
returned: success
type: int
sample: 5120
monthly_cost:
description: Monthly cost in $.
returned: success
type: int
sample: 300
type:
description: Type of plan.
returned: success
type: str
sample: SSD
locations:
description: List of locations the plan is available in.
returned: success
type: list
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_plan_metal_info",
resource_path="/plans-metal",
ressource_result_key_singular="plan_metal",
ressource_result_key_plural="plans_metal",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,106 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: region_info
short_description: Gather information about the Vultr regions
description:
- Gather information about regions available to boot servers.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr regions information
vultr.cloud.region_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_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_endpoint:
description: Endpoint used for the API requests.
returned: success
type: str
sample: "https://api.vultr.com/v2"
vultr_region_info:
description: Response from Vultr API.
returned: success
type: list
sample: [
{
"block_storage": false,
"continent": "Europe",
"country": "GB",
"ddos_protection": true,
"id": 8,
"name": "London",
"regioncode": "LHR",
"state": ""
}
]
"""
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_region_info",
resource_path="/regions",
ressource_result_key_singular="region",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,290 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: reserved_ip
short_description: Manages reserved IPs on Vultr
description:
- Create, attach, detach and remove reserved IPs.
version_added: "1.0.0"
author:
- "René Moser (@resmo)"
options:
label:
description:
- Label of the reserved IP.
required: true
aliases: [ name ]
type: str
instance_name:
description:
- Name of the Instance the reserved IP should be attached to.
- Mutually exclusive with I(instance_id).
type: str
instance_id:
description:
- ID of the Instance the reserved IP should be attached to.
- Mutually exclusive with I(instance_name).
type: str
region:
description:
- Region of the reserved IP will be related to.
type: str
required: true
ip_type:
description:
- Type of the IP.
type: str
choices: [ v4, v6 ]
required: true
state:
description:
- State of the reserved IP.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure a reserved IP present and attached to an instance
vultr.cloud.reserved_ip:
label: my attached IP
region: ewr
ip_type: v4
instance_name: web-01
- name: Ensure a reserved IP is detached
vultr.cloud.reserved_ip:
label: my reserved IP
region: ewr
ip_type: v4
instance_id: ""
- name: Ensure a reserved IP is absent
vultr.cloud.reserved_ip:
label: my attached IP
region: ewr
ip_type: v4
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_reserved_ip:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the reserved IP.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
label:
description: Name of the reserved IP.
returned: success
type: str
sample: example.com
region:
description: Region of the reserved IP is related to.
returned: success
type: str
sample: ewr
ip_type:
description: Type of the reserved IP.
returned: success
type: str
sample: v4
subnet:
description: Subnet of the reserved IP.
returned: success
type: str
sample: v4
subnet_size:
description: Size of the subnet of the reserved IP.
returned: success
type: int
sample: 32
instance_id:
description: ID of the Instance the reserved IP is attached to.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b
"""
import urllib
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrReservedIp(AnsibleVultr):
def configure(self):
self.instance_id = self.get_instance_id()
def get_instance_id(self):
instance_id = self.module.params["instance_id"]
if instance_id is not None:
return instance_id
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 ""
# URL encode label
try:
label = urllib.quote(instance_name) # type: ignore
except AttributeError:
label = urllib.parse.quote(instance_name) # type: ignore
# Filter instances by label
resources = self.api_query(path="/instances?label=%s" % label) or dict()
if not resources or not resources["instances"]:
self.module.fail_json(msg="No instance with name found: %s" % instance_name)
if len(resources["instances"]) > 1:
self.module.fail_json(msg="More then one instance with name found: %s" % instance_name)
return resources["instances"][0]["id"]
def query_list(self, path=None, result_key=None):
resources = self.api_query(path=self.resource_path) or dict()
resources_filtered = list()
for resource in resources[self.ressource_result_key_plural]:
# Skip IP with different type
if resource["ip_type"] != self.module.params["ip_type"]:
continue
# Skip IP in different region
if resource["region"] != self.module.params["region"]:
continue
resources_filtered.append(resource)
return resources_filtered
def create(self):
resource = super().create() or dict()
if resource and self.instance_id:
if not self.module.check_mode:
# Attach instance
self.api_query(
path="%s/%s/%s"
% (
self.resource_path,
resource[self.resource_key_id],
"attach",
),
method="POST",
data=dict(instance_id=self.instance_id),
)
# Refresh
resource = self.query_by_id(resource_id=resource[self.resource_key_id])
return resource
def update(self, resource):
if self.instance_id is None:
return resource
# Detach instance
elif resource["instance_id"] and not self.instance_id:
self.result["changed"] = True
if not self.module.check_mode:
self.api_query(
path="%s/%s/%s" % (self.resource_path, resource[self.resource_key_id], "detach"),
method="POST",
data=dict(instance_id=self.instance_id),
)
# Refresh
resource = self.query_by_id(resource_id=resource[self.resource_key_id])
# Attach instance or change attached instance
elif self.instance_id and resource["instance_id"] != self.instance_id:
self.result["changed"] = True
if not self.module.check_mode:
self.api_query(
path="%s/%s/%s" % (self.resource_path, resource[self.resource_key_id], "attach"),
method="POST",
data=dict(instance_id=self.instance_id),
)
# Refresh
resource = self.query_by_id(resource_id=resource[self.resource_key_id])
return resource
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
label=dict(type="str", required=True, aliases=["name"]),
instance_id=dict(type="str"),
instance_name=dict(type="str"),
ip_type=dict(type="str", required=True, choices=["v4", "v6"]),
region=dict(type="str", required=True),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
mutually_exclusive=(["instance_id", "instance_name"],),
supports_check_mode=True,
)
vultr = AnsibleVultrReservedIp(
module=module,
namespace="vultr_reserved_ip",
resource_path="/reserved-ips",
ressource_result_key_singular="reserved_ip",
resource_create_param_keys=["region", "ip_type", "label"],
resource_key_name="label",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,218 @@
#!/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: snapshot
short_description: Manages snapshots on Vultr
description:
- Create and remove snapshots.
version_added: "1.7.0"
author: "René Moser (@resmo)"
options:
description:
description:
- Description of the snapshot.
required: true
aliases: [ name ]
type: str
instance:
description:
- The description or ID of the instance from which to take the snapshot.
- Mutually exclusive with I(url).
- I(instance) or I(url) is required if I(state=present).
type: str
url:
description:
- The URL of the snapshot image (RAW) to be uploaded.
- Mutually exclusive with I(instance).
- I(instance) or I(url) is required if I(state=present).
type: str
state:
description:
- State of the snapshot.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure a snapshot is present
vultr.cloud.snapshot:
description: my snapshot of my instance
instance: my instance
- name: Ensure a snapshot is present
vultr.cloud.snapshot:
description: debian 11 generic
url: https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.raw
- name: Ensure a snapshot is absent
vultr.cloud.snapshot:
description: my snapshot of my instance
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_snapshot:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the snapshot.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
description:
description: Description of the snapshot.
returned: success
type: str
sample: my vpc
date_created:
description: Date the snapshot was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
size:
description: Size of the snapshot.
returned: success
type: int
sample: 42949672960
compressed_size:
description: Compressed size of the snapshot.
returned: success
type: int
sample: 949678560
status:
description: Status of the snapshot.
returned: success
type: str
sample: complete
os_id:
description: ID of the OS.
returned: success
type: int
sample: 215
app_id:
description: ID of the app.
returned: success
type: int
sample: 0
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrSnapshot(AnsibleVultr):
def get_instance(self):
return self.query_filter_list_by_name(
key_name="label",
param_key="instance",
path="/instances",
result_key="instances",
fail_not_found=True,
)
def create(self):
param_keys = ("url", "instance")
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))
if self.module.params.get("url") is not None:
self.resource_create_param_keys.append("url")
# Upload by URL has a different endpoint
self.resource_path = self.resource_path + "/create-from-url"
else:
self.module.params["instance_id"] = self.get_instance()["id"]
self.resource_create_param_keys.append("instance_id")
resource = super(AnsibleVultrSnapshot, self).create()
# Reset endpoint
self.resource_path = "/snapshots"
if resource:
resource = self.wait_for_state(resource=resource, key="status", state="complete")
return resource
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
description=dict(type="str", required=True, aliases=["name"]),
instance=dict(type="str"),
url=dict(type="str"),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
mutually_exclusive=(("instance", "url"),),
supports_check_mode=True,
)
vultr = AnsibleVultrSnapshot(
module=module,
namespace="vultr_snapshot",
resource_path="/snapshots",
ressource_result_key_singular="snapshot",
resource_create_param_keys=[
"description",
],
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()

View File

@@ -0,0 +1,132 @@
#!/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: snapshot_info
short_description: Gather information about the Vultr snapshots
description:
- Gather information about snapshots available.
version_added: "1.7.0"
author:
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr snapshots information
vultr.cloud.snapshot_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_snapshot_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_snapshot_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the snapshot.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
description:
description: Description of the snapshot.
returned: success
type: str
sample: my vpc
date_created:
description: Date the snapshot was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
size:
description: Size of the snapshot.
returned: success
type: int
sample: 42949672960
compressed_size:
description: Compressed size of the snapshot.
returned: success
type: int
sample: 949678560
status:
description: Status of the snapshot.
returned: success
type: str
sample: complete
os_id:
description: ID of the OS.
returned: success
type: int
sample: 215
app_id:
description: ID of the app.
returned: success
type: int
sample: 0
"""
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_snapshot_info",
resource_path="/snapshots",
ressource_result_key_singular="snapshot",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,148 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: ssh_key
short_description: Manages ssh keys on Vultr.
description:
- Create, update and remove ssh keys.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
name:
description:
- Name of the ssh key.
required: true
type: str
ssh_key:
description:
- SSH public key.
- Required if C(state=present).
type: str
state:
description:
- State of the ssh key.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: ensure an SSH key is present
vultr.cloud.ssh_key:
name: my ssh key
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: ensure an SSH key is absent
vultr.cloud.ssh_key:
name: my ssh key
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_ssh_key:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the ssh key.
returned: success
type: str
sample: cb676a46-66fd-4dfb-b839-443f2e6c0b60
name:
description: Name of the ssh key.
returned: success
type: str
sample: my ssh key
date_created:
description: Date the ssh key was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
ssh_key:
description: SSH public key.
returned: success
type: str
sample: ssh-rsa AA... someother@example.com
"""
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(
name=dict(type="str", required=True),
ssh_key=dict(type="str", no_log=False),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
("state", "present", ["ssh_key"]),
],
supports_check_mode=True,
)
vultr = AnsibleVultr(
module=module,
namespace="vultr_ssh_key",
resource_path="/ssh-keys",
ressource_result_key_singular="ssh_key",
resource_create_param_keys=["name", "ssh_key"],
resource_update_param_keys=["name", "ssh_key"],
resource_key_name="name",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,117 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: ssh_key_info
short_description: Get information about the Vultr SSH keys
description:
- Get infos about SSH keys available.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr SSH keys infos
vultr.cloud.ssh_key_info:
register: result
- name: Print the infos
ansible.builtin.debug:
var: result.vultr_ssh_key_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_ssh_key_info:
description: Response from Vultr API as list.
returned: success
type: list
contains:
id:
description: ID of the ssh key.
returned: success
type: str
sample: 7d726ffe-9be2-4f88-8cda-fa7eba1da2b5
name:
description: Name of the ssh key.
returned: success
type: str
sample: my ssh key
date_created:
description: Date the ssh key was created.
returned: success
type: str
sample: "2021-11-07T05:57:59-05:00"
ssh_key:
description: SSH public key.
returned: success
type: str
sample: "ssh-rsa AA... someother@example.com"
"""
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_ssh_key_info",
resource_path="/ssh-keys",
ressource_result_key_singular="ssh_key",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,196 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: startup_script
short_description: Manages startup scripts on Vultr
description:
- Create, update and remove startup scripts.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
name:
description:
- The script name.
required: true
type: str
type:
description:
- The script type, can not be changed once created.
default: boot
choices: [ boot, pxe ]
aliases: [ script_type ]
type: str
script:
description:
- The script source code.
- Required if I(state=present).
type: str
state:
description:
- State of the script.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: ensure a pxe script exists, source from a file
vultr.cloud.startup_script:
name: my_web_script
script_type: pxe
script: "{{ lookup('file', 'path/to/script') }}"
- name: ensure a boot script exists
vultr.cloud.startup_script:
name: vultr_startup_script
script: "#!/bin/bash\necho Hello World > /root/hello"
- name: ensure a script is absent
vultr.cloud.startup_script:
name: my_web_script
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_startup_script:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the startup script.
returned: success
type: str
sample: 7d726ffe-9be2-4f88-8cda-fa7eba1da2b5
name:
description: Name of the startup script.
returned: success
type: str
sample: my startup script
script:
description: The source code of the startup script.
returned: success
type: str
sample: "#!/bin/bash\necho Hello World > /root/hello"
type:
description: The type of the startup script.
returned: success
type: str
sample: pxe
date_created:
description: Date the startup script was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
date_modified:
description: Date the startup script was modified.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
import base64
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
class AnsibleVultrStartupScript(AnsibleVultr):
def configure(self):
if self.module.params["script"]:
self.module.params["script"] = base64.b64encode(self.module.params["script"].encode())
def update(self, resource):
resource["script"] = resource["script"].encode()
return super(AnsibleVultrStartupScript, self).update(resource=resource)
def transform_result(self, resource):
if resource:
resource["script"] = base64.b64decode(resource["script"]).decode()
return resource
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
name=dict(type="str", required=True),
script=dict(
type="str",
),
type=dict(
type="str",
default="boot",
choices=["boot", "pxe"],
aliases=["script_type"],
),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
("state", "present", ["script"]),
],
supports_check_mode=True,
)
vultr = AnsibleVultrStartupScript(
module=module,
namespace="vultr_startup_script",
resource_path="/startup-scripts",
ressource_result_key_singular="startup_script",
resource_get_details=True,
resource_create_param_keys=["name", "type", "script"],
resource_update_param_keys=["name", "script"],
resource_key_name="name",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,120 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: startup_script_info
short_description: Gather information about the Vultr startup scripts
description:
- Gather information about startup scripts available.
version_added: "1.0.0"
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr startup scripts information
vultr.cloud.startup_script_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_startup_script_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_startup_script_info:
description: Response from Vultr API.
returned: success
type: list
contains:
id:
description: ID of the startup script.
returned: success
type: str
sample: 56e5b8b5-120c-40b1-a087-3abc9cd8df57
name:
description: Name of the startup script.
returned: success
type: str
sample: my startup script
type:
description: The type of the startup script.
returned: success
type: str
sample: pxe
date_created:
description: Date the startup script was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
date_modified:
description: Date the startup script was modified.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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_startup_script_info",
resource_path="/startup-scripts",
ressource_result_key_singular="startup_script",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,229 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, 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: user
short_description: Manages users on Vultr
description:
- Create, update and remove users.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
name:
description:
- Name of the user
required: true
type: str
email:
description:
- Email of the user.
- Required if C(state=present).
type: str
password:
description:
- Password of the user.
- Only considered while creating a user or when C(force=yes).
type: str
force:
description:
- Password will only be changed with enforcement.
default: no
type: bool
api_enabled:
description:
- Whether the API is enabled or not.
default: yes
type: bool
acls:
description:
- List of ACLs this users should have.
- Required if C(state=present).
- One or more of the choices list, some depend on each other.
choices:
- manage_users
- subscriptions_view
- subscriptions
- provisioning
- billing
- support
- abuse
- dns
- upgrade
- objstore
- loadbalancer
aliases: [ acl ]
type: list
elements: str
state:
description:
- State of the user.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Ensure a user exists
vultr.cloud.user:
name: john
email: john.doe@example.com
password: s3cr3t
acls:
- manage_users
- subscriptions
- name: Remove a user
vultr.cloud.user:
name: john
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_user:
description: Response from Vultr API.
returned: success
type: dict
contains:
id:
description: ID of the user.
returned: success
type: str
sample: 7d726ffe-9be2-4f88-8cda-fa7eba1da2b5
api_key:
description: API key of the user.
returned: only after resource was created
type: str
sample: 567E6K567E6K567E6K567E6K567E6K
name:
description: Name of the user.
returned: success
type: str
sample: john
email:
description: Email of the user.
returned: success
type: str
sample: "john@example.com"
api_enabled:
description: Whether the API is enabled or not.
returned: success
type: bool
sample: true
acls:
description: List of ACLs of the user.
returned: success
type: list
sample: [manage_users, support, upgrade]
"""
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.vultr_v2 import AnsibleVultr, vultr_argument_spec
ACLS = [
"manage_users",
"subscriptions_view",
"subscriptions",
"provisioning",
"billing",
"support",
"abuse",
"dns",
"upgrade",
"objstore",
"loadbalancer",
]
class AnsibleVultrUser(AnsibleVultr):
def create(self):
# Password is required in create mode.
self.module.fail_on_missing_params(required_params=["password"])
return super(AnsibleVultrUser, self).create()
def update(self, resource):
# Password is never returned and we can not compare.
# That is why we update it only if forced
force = self.module.params.get("force")
if force:
self.resource_update_param_keys.append("password")
return super(AnsibleVultrUser, self).update(resource=resource)
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(
dict(
name=dict(type="str", required=True),
email=dict(type="str"),
password=dict(type="str", no_log=True),
force=dict(type="bool", default=False),
api_enabled=dict(type="bool", default=True),
acls=dict(type="list", elements="str", choices=ACLS, aliases=["acl"]),
state=dict(type="str", choices=["present", "absent"], default="present"),
) # type: ignore
)
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
("state", "present", ["email", "acls"]),
],
supports_check_mode=True,
)
vultr = AnsibleVultrUser(
module=module,
namespace="vultr_user",
resource_path="/users",
ressource_result_key_singular="user",
resource_create_param_keys=["name", "email", "password", "api_enabled", "acls"],
resource_update_param_keys=["name", "email", "api_enabled", "acls"],
resource_key_name="name",
)
if module.params.get("state") == "absent": # type: ignore
vultr.absent()
else:
vultr.present()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,125 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2021, 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: user_info
short_description: Get information about the Vultr users
version_added: "1.0.0"
description:
- Get infos about users available.
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Get Vultr user infos
vultr.cloud.user_info:
register: result
- name: Print the infos
ansible.builtin.debug:
var: result.vultr_user_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_user_info:
description: Response from Vultr API as list.
returned: available
type: list
contains:
id:
description: ID of the user.
returned: success
type: str
sample: 7d726ffe-9be2-4f88-8cda-fa7eba1da2b5
api_key:
description: API key of the user.
returned: only after resource was created
type: str
sample: 567E6K567E6K567E6K567E6K567E6K
name:
description: Name of the user.
returned: success
type: str
sample: john
email:
description: Email of the user.
returned: success
type: str
sample: "john@example.com"
api_enabled:
description: Whether the API is enabled or not.
returned: success
type: bool
sample: true
acls:
description: List of ACLs of the user.
returned: success
type: list
sample: [ manage_users, support, upgrade ]
"""
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_user_info",
resource_path="/users",
ressource_result_key_singular="user",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,182 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, 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: vpc
short_description: Manages VPCs on Vultr
description:
- Create and remove VPCs.
version_added: "1.0.0"
author: "René Moser (@resmo)"
options:
description:
description:
- Description of the VPC.
required: true
aliases: [ name ]
type: str
v4_subnet:
description:
- IPv4 subnet of the VPC.
- Required if I(state=present).
type: str
v4_subnet_mask:
description:
- IPv4 subnet mask of the VPC.
- 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.vpc:
description: my VPC.
subnet: 10.99.1.0
subnet_mask: 24
region: ewr
- name: Ensure a VPC is absent
vultr.cloud.vpc:
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_vpc:
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
v4_subnet:
description: Subnet of the VPC.
returned: success
type: str
sample: 10.99.1.0
v4_subnet_maks:
description: Subnet mask of the VPC.
returned: success
type: str
sample: 10.99.1.0
date_created:
description: Date the VPC was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
date_modified:
description: Date the VPC was modified.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
"""
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"]),
v4_subnet=dict(type="str"),
v4_subnet_mask=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",
("v4_subnet", "v4_subnet_mask", "region"),
),
),
supports_check_mode=True,
)
vultr = AnsibleVultr(
module=module,
namespace="vultr_vpc",
resource_path="/vpcs",
ressource_result_key_singular="vpc",
resource_create_param_keys=[
"description",
"v4_subnet",
"v4_subnet_mask",
"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()

View File

@@ -0,0 +1,122 @@
#!/usr/bin/python
#
# Copyright (c) 2022, 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: vpc_info
short_description: Gather information about the Vultr VPCs
description:
- Gather information about VPCs available.
version_added: "1.0.0"
author:
- "René Moser (@resmo)"
extends_documentation_fragment:
- vultr.cloud.vultr_v2
"""
EXAMPLES = """
- name: Gather Vultr VPCs information
vultr.cloud.vpc_info:
register: result
- name: Print the gathered information
ansible.builtin.debug:
var: result.vultr_vpc_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_vpc_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: myvpc
date_created:
description: Date when the VPC was created.
returned: success
type: str
sample: "2020-10-10T01:56:20+00:00"
region:
description: Region the VPC was deployed into.
returned: success
type: str
sample: ewr
v4_subnet:
description: IPv4 Network address
returned: success
type: str
sample: 192.168.42.0
v4_subnet_mask:
description: Ipv4 Network mask
returned: success
type: int
sample: 24
"""
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_vpc_info",
resource_path="/vpcs",
ressource_result_key_singular="vpc",
)
vultr.get_result(vultr.query_list())
if __name__ == "__main__":
main()