1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

vultr migrated to dedicated collection ngine_io.vultr (#172)

* vultr migrated to dedicated collection ngine_io.vultr

* remove leftover dead symlink
This commit is contained in:
René Moser 2020-04-13 20:35:34 +02:00 committed by GitHub
parent b0b376fce2
commit 6ccf3682ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
155 changed files with 0 additions and 10690 deletions

42
.github/BOTMETA.yml vendored
View file

@ -160,9 +160,6 @@ files:
maintainers: $team_mysql
labels: database mysql proxysql
keywords: mariadb proxysql
$doc_fragments/vultr.py:
maintainers: $team_vultr
labels: cloud vultr
$doc_fragments/xenserver.py:
maintainers: bvitnik
labels: xenserver
@ -200,9 +197,6 @@ files:
maintainers: $team_scaleway
labels: cloud scaleway
$inventories/virtualbox.py:
$inventories/vultr.py:
maintainers: $team_vultr
labels: cloud vultr
$lookups/:
labels: lookups
$lookups/conjur_variable.py:
@ -386,9 +380,6 @@ files:
maintainers: $team_e_spirit
labels: utm_utils
$module_utils/vexata.py:
$module_utils/vultr.py:
maintainers: $team_vultr
labels: cloud vultr
$module_utils/xenserver.py:
maintainers: bvitnik
labels: xenserver
@ -919,38 +910,6 @@ files:
authors: talzur
$modules/cloud/univention/:
authors: keachi
$modules/cloud/vultr/:
authors: Spredzy
maintainers: resmo
$modules/cloud/vultr/vultr_account_info.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_block_storage_info.py:
authors: Spredzy resmo
$modules/cloud/vultr/vultr_dns_domain.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_firewall_rule.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_os_info.py:
authors: Spredzy resmo
$modules/cloud/vultr/vultr_server.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_ssh_key.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_ssh_key_info.py:
authors: Spredzy resmo
$modules/cloud/vultr/vultr_startup_script.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_user.py:
authors: resmo
maintainers: Spredzy
$modules/cloud/vultr/vultr_user_info.py:
authors: Spredzy resmo
$modules/cloud/webfaction/:
authors: quentinsf
$modules/cloud/xenserver/:
@ -2254,4 +2213,3 @@ macros:
team_solaris: bcoca danowar2k fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
team_suse: commel dcermak evrardjp lrupp toabctl
team_virt: joshainglis karmab
team_vultr: Spredzy resmo

View file

@ -1,2 +0,0 @@
minor_changes:
- vultr_server_info, vultr_server - Improved handling of discontinued plans (https://github.com/ansible/ansible/issues/66707).

View file

@ -1,2 +0,0 @@
bugfixes:
- vultr - Fixed the issue retry max delay param was ignored.

View file

@ -512,90 +512,6 @@ plugin_routing:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_account_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_dns_domain:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_dns_record:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_firewall_group:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_firewall_rule:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_server:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_ssh_key:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_startup_script:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vr_user:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_account_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_block_storage_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_dns_domain_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_firewall_group_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_network_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_os_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_plan_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_region_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_server_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_ssh_key_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_startup_script_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
vultr_user_facts:
deprecation:
removal_date: TBD
warning_text: see plugin documentation for details
xenserver_guest_facts:
deprecation:
removal_date: TBD

View file

@ -1,56 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
class ModuleDocFragment(object):
# Standard documentation fragment
DOCUMENTATION = r'''
options:
api_key:
description:
- API key of the Vultr API.
- The ENV variable C(VULTR_API_KEY) is used as default, when defined.
type: str
api_timeout:
description:
- HTTP timeout to Vultr API.
- The ENV variable C(VULTR_API_TIMEOUT) is used as default, when defined.
- Fallback value is 60 seconds if not specified.
type: int
api_retries:
description:
- Amount of retries in case of the Vultr API retuns an HTTP 503 code.
- The ENV variable C(VULTR_API_RETRIES) is used as default, when defined.
- Fallback value is 5 retries if not specified.
type: int
api_retry_max_delay:
description:
- Retry backoff delay in seconds is exponential up to this max. value, in seconds.
- The ENV variable C(VULTR_API_RETRY_MAX_DELAY) is used as default, when defined.
- Fallback value is 12 seconds.
type: int
api_account:
description:
- Name of the ini section in the C(vultr.ini) file.
- The ENV variable C(VULTR_API_ACCOUNT) is used as default, when defined.
type: str
default: default
api_endpoint:
description:
- URL to API endpint (without trailing slash).
- The ENV variable C(VULTR_API_ENDPOINT) is used as default, when defined.
- Fallback value is U(https://api.vultr.com) if not specified.
type: str
validate_certs:
description:
- Validate SSL certs of the Vultr API.
type: bool
default: yes
requirements:
- python >= 2.6
notes:
- Also see the API documentation on https://www.vultr.com/api/.
'''

View file

@ -1,201 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2019, 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 = r'''
name: vultr
plugin_type: inventory
author:
- Yanis Guenane (@Spredzy)
- René Moser (@resmo)
short_description: Vultr inventory source
extends_documentation_fragment:
- constructed
description:
- Get inventory hosts from Vultr public cloud.
- Uses an YAML configuration file ending with either I(vultr.yml) or I(vultr.yaml) to set parameter values (also see examples).
- Uses I(api_config), I(~/.vultr.ini), I(./vultr.ini) or C(VULTR_API_CONFIG) pointing to a Vultr credentials INI file
(see U(https://docs.ansible.com/ansible/latest/scenario_guides/guide_vultr.html)).
options:
plugin:
description: Token that ensures this is a source file for the 'vultr' plugin.
type: string
required: True
choices: [ vultr ]
api_account:
description: Specify the account to be used.
type: string
default: default
api_config:
description: Path to the vultr configuration file. If not specified will be taken from regular Vultr configuration.
type: path
env:
- name: VULTR_API_CONFIG
api_key:
description: Vultr API key. If not specified will be taken from regular Vultr configuration.
type: string
env:
- name: VULTR_API_KEY
hostname:
description: Field to match the hostname. Note v4_main_ip corresponds to the main_ip field returned from the API and name to label.
type: string
default: v4_main_ip
choices:
- v4_main_ip
- v6_main_ip
- name
filter_by_tag:
description: Only return servers filtered by this tag
type: string
'''
EXAMPLES = r'''
# inventory_vultr.yml file in YAML format
# Example command line: ansible-inventory --list -i inventory_vultr.yml
# Group by a region as lower case and with prefix e.g. "vultr_region_amsterdam" and by OS without prefix e.g. "CentOS_7_x64"
plugin: vultr
keyed_groups:
- prefix: vultr_region
key: region | lower
- separator: ""
key: os
# Pass a tag filter to the API
plugin: vultr
filter_by_tag: Cache
'''
import json
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.module_utils.six.moves import configparser
from ansible.module_utils.urls import open_url
from ansible.module_utils._text import to_native
from ansible_collections.community.general.plugins.module_utils.vultr import Vultr, VULTR_API_ENDPOINT, VULTR_USER_AGENT
from ansible.module_utils.six.moves.urllib.parse import quote
SCHEMA = {
'SUBID': dict(key='id'),
'label': dict(key='name'),
'date_created': dict(),
'allowed_bandwidth_gb': dict(convert_to='int'),
'auto_backups': dict(key='auto_backup_enabled', convert_to='bool'),
'current_bandwidth_gb': dict(),
'kvm_url': dict(),
'default_password': dict(),
'internal_ip': dict(),
'disk': dict(),
'cost_per_month': dict(convert_to='float'),
'location': dict(key='region'),
'main_ip': dict(key='v4_main_ip'),
'network_v4': dict(key='v4_network'),
'gateway_v4': dict(key='v4_gateway'),
'os': dict(),
'pending_charges': dict(convert_to='float'),
'power_status': dict(),
'ram': dict(),
'plan': dict(),
'server_state': dict(),
'status': dict(),
'firewall_group': dict(),
'tag': dict(),
'v6_main_ip': dict(),
'v6_network': dict(),
'v6_network_size': dict(),
'v6_networks': dict(),
'vcpu_count': dict(convert_to='int'),
}
def _load_conf(path, account):
if path:
conf = configparser.ConfigParser()
conf.read(path)
if not conf._sections.get(account):
return None
return dict(conf.items(account))
else:
return Vultr.read_ini_config(account)
def _retrieve_servers(api_key, tag_filter=None):
api_url = '%s/v1/server/list' % VULTR_API_ENDPOINT
if tag_filter is not None:
api_url = api_url + '?tag=%s' % quote(tag_filter)
try:
response = open_url(
api_url, headers={'API-Key': api_key, 'Content-type': 'application/json'},
http_agent=VULTR_USER_AGENT,
)
servers_list = json.loads(response.read())
return servers_list.values() if servers_list else []
except ValueError:
raise AnsibleError("Incorrect JSON payload")
except Exception as e:
raise AnsibleError("Error while fetching %s: %s" % (api_url, to_native(e)))
class InventoryModule(BaseInventoryPlugin, Constructable):
NAME = 'community.general.vultr'
def verify_file(self, path):
valid = False
if super(InventoryModule, self).verify_file(path):
if path.endswith(('vultr.yaml', 'vultr.yml')):
valid = True
return valid
def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(inventory, loader, path)
self._read_config_data(path=path)
conf = _load_conf(self.get_option('api_config'), self.get_option('api_account'))
try:
api_key = self.get_option('api_key') or conf.get('key')
except Exception:
raise AnsibleError('Could not find an API key. Check inventory file and Vultr configuration files.')
hostname_preference = self.get_option('hostname')
# Add a top group 'vultr'
self.inventory.add_group(group='vultr')
# Filter by tag is supported by the api with a query
filter_by_tag = self.get_option('filter_by_tag')
for server in _retrieve_servers(api_key, filter_by_tag):
server = Vultr.normalize_result(server, SCHEMA)
self.inventory.add_host(host=server['name'], group='vultr')
for attribute, value in server.items():
self.inventory.set_variable(server['name'], attribute, value)
if hostname_preference != 'name':
self.inventory.set_variable(server['name'], 'ansible_host', server[hostname_preference])
# Use constructed if applicable
strict = self.get_option('strict')
# Composed variables
self._set_composite_vars(self.get_option('compose'), server, server['name'], strict=strict)
# Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
self._add_host_to_composed_groups(self.get_option('groups'), server, server['name'], strict=strict)
# Create groups based on variable values and add the corresponding hosts to it
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), server, server['name'], strict=strict)

View file

@ -1,333 +0,0 @@
# -*- coding: utf-8 -*-
# (c) 2017, René Moser <mail@renemoser.net>
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import os
import time
import random
import urllib
from ansible.module_utils.six.moves import configparser
from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.urls import fetch_url
VULTR_API_ENDPOINT = "https://api.vultr.com"
VULTR_USER_AGENT = 'Ansible Vultr'
def vultr_argument_spec():
return dict(
api_key=dict(type='str', default=os.environ.get('VULTR_API_KEY'), no_log=True),
api_timeout=dict(type='int', default=os.environ.get('VULTR_API_TIMEOUT')),
api_retries=dict(type='int', default=os.environ.get('VULTR_API_RETRIES')),
api_retry_max_delay=dict(type='int', default=os.environ.get('VULTR_API_RETRY_MAX_DELAY')),
api_account=dict(type='str', default=os.environ.get('VULTR_API_ACCOUNT') or 'default'),
api_endpoint=dict(type='str', default=os.environ.get('VULTR_API_ENDPOINT')),
validate_certs=dict(type='bool', default=True),
)
class Vultr:
def __init__(self, module, namespace):
if module._name.startswith('vr_'):
module.deprecate("The Vultr modules were renamed. The prefix of the modules changed from vr_ to vultr_", version='2.11')
self.module = module
# Namespace use for returns
self.namespace = namespace
self.result = {
'changed': False,
namespace: dict(),
'diff': dict(before=dict(), after=dict())
}
# For caching HTTP API responses
self.api_cache = dict()
try:
config = self.read_env_variables()
config.update(Vultr.read_ini_config(self.module.params.get('api_account')))
except KeyError:
config = {}
try:
self.api_config = {
'api_key': self.module.params.get('api_key') or config.get('key'),
'api_timeout': self.module.params.get('api_timeout') or int(config.get('timeout') or 60),
'api_retries': self.module.params.get('api_retries') or int(config.get('retries') or 5),
'api_retry_max_delay': self.module.params.get('api_retry_max_delay') or int(config.get('retry_max_delay') or 12),
'api_endpoint': self.module.params.get('api_endpoint') or config.get('endpoint') or VULTR_API_ENDPOINT,
}
except ValueError as e:
self.fail_json(msg="One of the following settings, "
"in section '%s' in the ini config file has not an int value: timeout, retries. "
"Error was %s" % (self.module.params.get('api_account'), to_native(e)))
if not self.api_config.get('api_key'):
self.module.fail_json(msg="The API key is not speicied. Please refer to the documentation.")
# Common vultr returns
self.result['vultr_api'] = {
'api_account': self.module.params.get('api_account'),
'api_timeout': self.api_config['api_timeout'],
'api_retries': self.api_config['api_retries'],
'api_retry_max_delay': self.api_config['api_retry_max_delay'],
'api_endpoint': self.api_config['api_endpoint'],
}
# Headers to be passed to the API
self.headers = {
'API-Key': "%s" % self.api_config['api_key'],
'User-Agent': VULTR_USER_AGENT,
'Accept': 'application/json',
}
def read_env_variables(self):
keys = ['key', 'timeout', 'retries', 'retry_max_delay', 'endpoint']
env_conf = {}
for key in keys:
if 'VULTR_API_%s' % key.upper() not in os.environ:
continue
env_conf[key] = os.environ['VULTR_API_%s' % key.upper()]
return env_conf
@staticmethod
def read_ini_config(ini_group):
paths = (
os.path.join(os.path.expanduser('~'), '.vultr.ini'),
os.path.join(os.getcwd(), 'vultr.ini'),
)
if 'VULTR_API_CONFIG' in os.environ:
paths += (os.path.expanduser(os.environ['VULTR_API_CONFIG']),)
conf = configparser.ConfigParser()
conf.read(paths)
if not conf._sections.get(ini_group):
return dict()
return dict(conf.items(ini_group))
def fail_json(self, **kwargs):
self.result.update(kwargs)
self.module.fail_json(**self.result)
def get_yes_or_no(self, key):
if self.module.params.get(key) is not None:
return 'yes' if self.module.params.get(key) is True else 'no'
def switch_enable_disable(self, resource, param_key, resource_key=None):
if resource_key is None:
resource_key = param_key
param = self.module.params.get(param_key)
if param is None:
return
r_value = resource.get(resource_key)
if r_value in ['yes', 'no']:
if param and r_value != 'yes':
return "enable"
elif not param and r_value != 'no':
return "disable"
else:
if param and not r_value:
return "enable"
elif not param and r_value:
return "disable"
def api_query(self, path="/", method="GET", data=None):
url = self.api_config['api_endpoint'] + path
if data:
data_encoded = dict()
data_list = ""
for k, v in data.items():
if isinstance(v, list):
for s in v:
try:
data_list += '&%s[]=%s' % (k, urllib.quote(s))
except AttributeError:
data_list += '&%s[]=%s' % (k, urllib.parse.quote(s))
elif v is not None:
data_encoded[k] = v
try:
data = urllib.urlencode(data_encoded) + data_list
except AttributeError:
data = urllib.parse.urlencode(data_encoded) + data_list
retry_max_delay = self.api_config['api_retry_max_delay']
randomness = random.randint(0, 1000) / 1000.0
for retry in range(0, self.api_config['api_retries']):
response, info = fetch_url(
module=self.module,
url=url,
data=data,
method=method,
headers=self.headers,
timeout=self.api_config['api_timeout'],
)
if info.get('status') == 200:
break
# Vultr has a rate limiting requests per second, try to be polite
# Use exponential backoff plus a little bit of randomness
delay = 2 ** retry + randomness
if delay > retry_max_delay:
delay = retry_max_delay + randomness
time.sleep(delay)
else:
self.fail_json(msg="Reached API retries limit %s for URL %s, method %s with data %s. Returned %s, with body: %s %s" % (
self.api_config['api_retries'],
url,
method,
data,
info['status'],
info['msg'],
info.get('body')
))
if info.get('status') != 200:
self.fail_json(msg="URL %s, method %s with data %s. Returned %s, with body: %s %s" % (
url,
method,
data,
info['status'],
info['msg'],
info.get('body')
))
res = response.read()
if not res:
return {}
try:
return self.module.from_json(to_native(res)) or {}
except ValueError as e:
self.module.fail_json(msg="Could not process response into json: %s" % e)
def query_resource_by_key(self, key, value, resource='regions', query_by='list', params=None, use_cache=False, id_key=None, optional=False):
if not value:
return {}
r_list = None
if use_cache:
r_list = self.api_cache.get(resource)
if not r_list:
r_list = self.api_query(path="/v1/%s/%s" % (resource, query_by), data=params)
if use_cache:
self.api_cache.update({
resource: r_list
})
if not r_list:
return {}
elif isinstance(r_list, list):
for r_data in r_list:
if str(r_data[key]) == str(value):
return r_data
if id_key is not None and to_text(r_data[id_key]) == to_text(value):
return r_data
elif isinstance(r_list, dict):
for r_id, r_data in r_list.items():
if str(r_data[key]) == str(value):
return r_data
if id_key is not None and to_text(r_data[id_key]) == to_text(value):
return r_data
if not optional:
if id_key:
msg = "Could not find %s with ID or %s: %s" % (resource, key, value)
else:
msg = "Could not find %s with %s: %s" % (resource, key, value)
self.module.fail_json(msg=msg)
return {}
@staticmethod
def normalize_result(resource, schema, remove_missing_keys=True):
if remove_missing_keys:
fields_to_remove = set(resource.keys()) - set(schema.keys())
for field in fields_to_remove:
resource.pop(field)
for search_key, config in schema.items():
if search_key in resource:
if 'convert_to' in config:
if config['convert_to'] == 'int':
resource[search_key] = int(resource[search_key])
elif config['convert_to'] == 'float':
resource[search_key] = float(resource[search_key])
elif config['convert_to'] == 'bool':
resource[search_key] = True if resource[search_key] == 'yes' else False
if 'transform' in config:
resource[search_key] = config['transform'](resource[search_key])
if 'key' in config:
resource[config['key']] = resource[search_key]
del resource[search_key]
return resource
def get_result(self, resource):
if resource:
if isinstance(resource, list):
self.result[self.namespace] = [Vultr.normalize_result(item, self.returns) for item in resource]
else:
self.result[self.namespace] = Vultr.normalize_result(resource, self.returns)
return self.result
def get_plan(self, plan=None, key='name', optional=False):
value = plan or self.module.params.get('plan')
return self.query_resource_by_key(
key=key,
value=value,
resource='plans',
use_cache=True,
id_key='VPSPLANID',
optional=optional,
)
def get_firewallgroup(self, firewallgroup=None, key='description'):
value = firewallgroup or self.module.params.get('firewallgroup')
return self.query_resource_by_key(
key=key,
value=value,
resource='firewall',
query_by='group_list',
use_cache=True
)
def get_application(self, application=None, key='name'):
value = application or self.module.params.get('application')
return self.query_resource_by_key(
key=key,
value=value,
resource='app',
use_cache=True
)
def get_region(self, region=None, key='name'):
value = region or self.module.params.get('region')
return self.query_resource_by_key(
key=key,
value=value,
resource='regions',
use_cache=True
)

View file

@ -1 +0,0 @@
./cloud/vultr/_vultr_account_facts.py

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_account_facts
short_description: Gather facts about the Vultr account.
description:
- Gather facts about account balance, charges and payments.
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_account_info) instead.
author: "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr account facts
local_action:
module: vultr_account_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_account_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_account_facts:
description: Response from Vultr API
returned: success
type: complex
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: "2017-08-26 12:47:48"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrAccountFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrAccountFacts, self).__init__(module, "vultr_account_facts")
self.returns = {
'balance': dict(convert_to='float'),
'pending_charges': dict(convert_to='float'),
'last_payment_date': dict(),
'last_payment_amount': dict(convert_to='float'),
}
def get_account_info(self):
return self.api_query(path="/v1/account/info")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
account_facts = AnsibleVultrAccountFacts(module)
result = account_facts.get_result(account_facts.get_account_info())
ansible_facts = {
'vultr_account_facts': result['vultr_account_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1 +0,0 @@
_vultr_account_facts.py

View file

@ -1 +0,0 @@
vultr_dns_domain.py

View file

@ -1 +0,0 @@
vultr_dns_record.py

View file

@ -1 +0,0 @@
vultr_firewall_group.py

View file

@ -1 +0,0 @@
vultr_firewall_rule.py

View file

@ -1 +0,0 @@
vultr_server.py

View file

@ -1 +0,0 @@
vultr_ssh_key.py

View file

@ -1 +0,0 @@
vultr_startup_script.py

View file

@ -1 +0,0 @@
vultr_user.py

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_account_facts
short_description: Gather facts about the Vultr account.
description:
- Gather facts about account balance, charges and payments.
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_account_info) instead.
author: "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr account facts
local_action:
module: vultr_account_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_account_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_account_facts:
description: Response from Vultr API
returned: success
type: complex
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: "2017-08-26 12:47:48"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrAccountFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrAccountFacts, self).__init__(module, "vultr_account_facts")
self.returns = {
'balance': dict(convert_to='float'),
'pending_charges': dict(convert_to='float'),
'last_payment_date': dict(),
'last_payment_amount': dict(convert_to='float'),
}
def get_account_info(self):
return self.api_query(path="/v1/account/info")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
account_facts = AnsibleVultrAccountFacts(module)
result = account_facts.get_result(account_facts.get_account_info())
ansible_facts = {
'vultr_account_facts': result['vultr_account_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,132 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_account_info
short_description: Get information about the Vultr account.
description:
- Get infos about account balance, charges and payments.
author: "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Get Vultr account infos
vultr_account_info:
register: result
- name: Print the infos
debug:
var: result.vultr_account_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_account_info:
description: Response from Vultr API
returned: success
type: complex
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: "2017-08-26 12:47:48"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrAccountInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrAccountInfo, self).__init__(module, "vultr_account_info")
self.returns = {
'balance': dict(convert_to='float'),
'pending_charges': dict(convert_to='float'),
'last_payment_date': dict(),
'last_payment_amount': dict(convert_to='float'),
}
def get_account_info(self):
return self.api_query(path="/v1/account/info")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
account_info = AnsibleVultrAccountInfo(module)
result = account_info.get_result(account_info.get_account_info())
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,246 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_block_storage
short_description: Manages block storage volumes on Vultr.
description:
- Manage block storage volumes on Vultr.
author: "Yanis Guenane (@Spredzy)"
options:
name:
description:
- Name of the block storage volume.
required: true
aliases: [ description, label ]
size:
description:
- Size of the block storage volume in GB.
required: true
region:
description:
- Region the block storage volume is deployed into.
required: true
state:
description:
- State of the block storage volume.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: Ensure a block storage volume is present
local_action:
module: vultr_block_storage
name: myvolume
size: 10
region: Amsterdam
- name: Ensure a block storage volume is absent
local_action:
module: vultr_block_storage
name: myvolume
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_block_storage:
description: Response from Vultr API
returned: success
type: complex
contains:
attached_to_id:
description: The ID of the server the volume is attached to
returned: success
type: str
sample: "10194376"
cost_per_month:
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: "2017-08-26 12:47:48"
id:
description: ID of the block storage volume
returned: success
type: str
sample: "1234abcd"
name:
description: Name of the volume
returned: success
type: str
sample: "ansible-test-volume"
region:
description: Region the volume was deployed into
returned: success
type: str
sample: "New Jersey"
size:
description: Information about the volume size in GB
returned: success
type: int
sample: 10
status:
description: Status about the deployment of the volume
returned: success
type: str
sample: "active"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrBlockStorage(Vultr):
def __init__(self, module):
super(AnsibleVultrBlockStorage, self).__init__(module, "vultr_block_storage")
self.returns = {
'SUBID': dict(key='id'),
'label': dict(key='name'),
'DCID': dict(key='region', transform=self._get_region_name),
'attached_to_SUBID': dict(key='attached_to_id'),
'cost_per_month': dict(convert_to='float'),
'date_created': dict(),
'size_gb': dict(key='size', convert_to='int'),
'status': dict()
}
def _get_region_name(self, region):
return self.get_region(region, 'DCID').get('name')
def get_block_storage_volumes(self):
volumes = self.api_query(path="/v1/block/list")
if volumes:
for volume in volumes:
if volume.get('label') == self.module.params.get('name'):
return volume
return {}
def present_block_storage_volume(self):
volume = self.get_block_storage_volumes()
if not volume:
volume = self._create_block_storage_volume(volume)
return volume
def _create_block_storage_volume(self, volume):
self.result['changed'] = True
data = {
'label': self.module.params.get('name'),
'DCID': self.get_region().get('DCID'),
'size_gb': self.module.params.get('size')
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/block/create",
method="POST",
data=data
)
volume = self.get_block_storage_volumes()
return volume
def absent_block_storage_volume(self):
volume = self.get_block_storage_volumes()
if volume:
self.result['changed'] = True
data = {
'SUBID': volume['SUBID'],
}
self.result['diff']['before'] = volume
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/block/delete",
method="POST",
data=data
)
return volume
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(required=True, aliases=['description', 'label']),
size=dict(type='int'),
region=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[['state', 'present', ['size', 'region']]]
)
vultr_block_storage = AnsibleVultrBlockStorage(module)
if module.params.get('state') == "absent":
volume = vultr_block_storage.absent_block_storage_volume()
else:
volume = vultr_block_storage.present_block_storage_volume()
result = vultr_block_storage.get_result(volume)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,137 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_block_storage_facts
short_description: Gather facts about the Vultr block storage volumes available.
description:
- Gather facts about block storage volumes available in Vultr.
author: "Yanis Guenane (@Spredzy)"
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_block_storage_info) instead.
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr block storage volumes facts
local_action:
module: vultr_block_storage_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_block_storage_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_block_storage_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_block_storage_facts": [
{
"attached_to_id": null,
"cost_per_month": 1.0,
"date_created": "2018-07-24 12:59:59",
"id": 17332323,
"name": "ansible-test-volume",
"region": "New Jersey",
"size": 10,
"status": "active"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrBlockStorageFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrBlockStorageFacts, self).__init__(module, "vultr_block_storage_facts")
self.returns = {
'attached_to_SUBID': dict(key='attached_to_id'),
'cost_per_month': dict(convert_to='float'),
'date_created': dict(),
'SUBID': dict(key='id'),
'label': dict(key='name'),
'DCID': dict(key='region', transform=self._get_region_name),
'size_gb': dict(key='size', convert_to='int'),
'status': dict()
}
def _get_region_name(self, region):
return self.get_region(region, 'DCID').get('name')
def get_block_storage_volumes(self):
return self.api_query(path="/v1/block/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
volume_facts = AnsibleVultrBlockStorageFacts(module)
result = volume_facts.get_result(volume_facts.get_block_storage_volumes())
ansible_facts = {
'vultr_block_storage_facts': result['vultr_block_storage_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,162 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2019, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_block_storage_info
short_description: Get information about the Vultr block storage volumes available.
description:
- Get infos about block storage volumes available in Vultr.
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Get Vultr block storage infos
vultr_block_storage_info:
register: result
- name: Print the infos
debug:
var: result.vultr_block_storage_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_block_storage_info:
description: Response from Vultr API as list
returned: success
type: complex
contains:
id:
description: ID of the block storage.
returned: success
type: int
sample: 17332323
size:
description: Size in GB of the block storage.
returned: success
type: int
sample: 10
region:
description: Region the block storage is located in.
returned: success
type: str
sample: New Jersey
name:
description: Name of the block storage.
returned: success
type: str
sample: my volume
cost_per_month:
description: Cost per month of the block storage.
returned: success
type: float
sample: 1.0
date_created:
description: Date created of the block storage.
returned: success
type: str
sample: "2018-07-24 12:59:59"
status:
description: Status of the block storage.
returned: success
type: str
sample: active
attached_to_id:
description: Block storage is attached to this server ID.
returned: success
type: str
sample: null
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrBlockStorageFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrBlockStorageFacts, self).__init__(module, "vultr_block_storage_info")
self.returns = {
'attached_to_SUBID': dict(key='attached_to_id'),
'cost_per_month': dict(convert_to='float'),
'date_created': dict(),
'SUBID': dict(key='id'),
'label': dict(key='name'),
'DCID': dict(key='region', transform=self._get_region_name),
'size_gb': dict(key='size', convert_to='int'),
'status': dict()
}
def _get_region_name(self, region):
return self.get_region(region, 'DCID').get('name')
def get_block_storage_volumes(self):
return self.api_query(path="/v1/block/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
volume_info = AnsibleVultrBlockStorageFacts(module)
result = volume_info.get_result(volume_info.get_block_storage_volumes())
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,203 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_dns_domain
short_description: Manages DNS domains on Vultr.
description:
- Create and remove DNS domains.
author: "René Moser (@resmo)"
options:
name:
description:
- The domain name.
required: true
aliases: [ domain ]
server_ip:
description:
- The default server IP.
- Use M(vultr_dns_record) to change it once the domain is created.
- Required if C(state=present).
state:
description:
- State of the DNS domain.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Ensure a domain exists
local_action:
module: vultr_dns_domain
name: example.com
server_ip: 10.10.10.10
- name: Ensure a domain is absent
local_action:
module: vultr_dns_domain
name: example.com
state: absent
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_dns_domain:
description: Response from Vultr API
returned: success
type: complex
contains:
name:
description: Name of the DNS Domain.
returned: success
type: str
sample: example.com
date_created:
description: Date the DNS domain was created.
returned: success
type: str
sample: "2017-08-26 12:47:48"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrDnsDomain(Vultr):
def __init__(self, module):
super(AnsibleVultrDnsDomain, self).__init__(module, "vultr_dns_domain")
self.returns = {
'domain': dict(key='name'),
'date_created': dict(),
}
def get_domain(self):
domains = self.api_query(path="/v1/dns/list")
name = self.module.params.get('name').lower()
if domains:
for domain in domains:
if domain.get('domain').lower() == name:
return domain
return {}
def present_domain(self):
domain = self.get_domain()
if not domain:
domain = self._create_domain(domain)
return domain
def _create_domain(self, domain):
self.result['changed'] = True
data = {
'domain': self.module.params.get('name'),
'serverip': self.module.params.get('server_ip'),
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/dns/create_domain",
method="POST",
data=data
)
domain = self.get_domain()
return domain
def absent_domain(self):
domain = self.get_domain()
if domain:
self.result['changed'] = True
data = {
'domain': domain['domain'],
}
self.result['diff']['before'] = domain
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/dns/delete_domain",
method="POST",
data=data
)
return domain
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(required=True, aliases=['domain']),
server_ip=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
('state', 'present', ['server_ip']),
],
supports_check_mode=True,
)
vultr_domain = AnsibleVultrDnsDomain(module)
if module.params.get('state') == "absent":
domain = vultr_domain.absent_domain()
else:
domain = vultr_domain.present_domain()
result = vultr_domain.get_result(domain)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,122 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_dns_domain_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_dns_domain_info) instead.
short_description: Gather facts about the Vultr DNS domains available.
description:
- Gather facts about DNS domains available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr DNS domains facts
local_action:
module: vultr_dns_domains_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_dns_domain_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_dns_domain_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_dns_domain_facts": [
{
"date_created": "2018-07-19 07:14:21",
"domain": "ansibletest.com"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrDnsDomainFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrDnsDomainFacts, self).__init__(module, "vultr_dns_domain_facts")
self.returns = {
"date_created": dict(),
"domain": dict(),
}
def get_domains(self):
return self.api_query(path="/v1/dns/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
domain_facts = AnsibleVultrDnsDomainFacts(module)
result = domain_facts.get_result(domain_facts.get_domains())
ansible_facts = {
'vultr_dns_domain_facts': result['vultr_dns_domain_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,116 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_dns_domain_info
short_description: Gather information about the Vultr DNS domains available.
description:
- Gather information about DNS domains available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr DNS domains information
local_action:
module: vultr_dns_domains_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_dns_domain_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_dns_domain_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_dns_domain_info": [
{
"date_created": "2018-07-19 07:14:21",
"domain": "ansibletest.com"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrDnsDomainInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrDnsDomainInfo, self).__init__(module, "vultr_dns_domain_info")
self.returns = {
"date_created": dict(),
"domain": dict(),
}
def get_domains(self):
return self.api_query(path="/v1/dns/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
domain_info = AnsibleVultrDnsDomainInfo(module)
result = domain_info.get_result(domain_info.get_domains())
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,372 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_dns_record
short_description: Manages DNS records on Vultr.
description:
- Create, update and remove DNS records.
author: "René Moser (@resmo)"
options:
name:
description:
- The record name (subrecord).
default: ""
aliases: [ subrecord ]
domain:
description:
- The domain the record is related to.
required: true
record_type:
description:
- Type of the record.
default: A
choices:
- A
- AAAA
- CNAME
- MX
- SRV
- CAA
- TXT
- NS
- SSHFP
aliases: [ type ]
data:
description:
- Data of the record.
- Required if C(state=present) or C(multiple=yes).
ttl:
description:
- TTL of the record.
default: 300
multiple:
description:
- Whether to use more than one record with similar C(name) including no name and C(record_type).
- Only allowed for a few record types, e.g. C(record_type=A), C(record_type=NS) or C(record_type=MX).
- C(data) will not be updated, instead it is used as a key to find existing records.
default: no
type: bool
priority:
description:
- Priority of the record.
default: 0
state:
description:
- State of the DNS record.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: Ensure an A record exists
vultr_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_dns_record:
name: www
domain: example.com
data: 10.10.10.11
ttl: 60
multiple: yes
- name: Ensure a CNAME record exists
vultr_dns_record:
name: web
record_type: CNAME
domain: example.com
data: www.example.com
- name: Ensure MX record exists
vultr_dns_record:
record_type: MX
domain: example.com
data: "{{ item.data }}"
priority: "{{ item.priority }}"
multiple: yes
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
local_action:
module: vultr_dns_record
name: www
domain: example.com
state: absent
- name: Ensure MX record is absent in case multiple exists
vultr_dns_record:
record_type: MX
domain: example.com
data: mx1.example.com
multiple: yes
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_dns_record:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: The ID of the DNS record.
returned: success
type: int
sample: 1265277
name:
description: The name of the DNS record.
returned: success
type: str
sample: web
record_type:
description: The name of the DNS record.
returned: success
type: str
sample: web
data:
description: Data of the DNS record.
returned: success
type: str
sample: 10.10.10.10
domain:
description: Domain the DNS record is related to.
returned: success
type: str
sample: example.com
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
RECORD_TYPES = [
'A',
'AAAA',
'CNAME',
'MX',
'TXT',
'NS',
'SRV',
'CAA',
'SSHFP'
]
class AnsibleVultrDnsRecord(Vultr):
def __init__(self, module):
super(AnsibleVultrDnsRecord, self).__init__(module, "vultr_dns_record")
self.returns = {
'RECORDID': dict(key='id'),
'name': dict(),
'record': dict(),
'priority': dict(),
'data': dict(),
'type': dict(key='record_type'),
'ttl': dict(),
}
def get_record(self):
records = self.api_query(path="/v1/dns/records?domain=%s" % self.module.params.get('domain'))
multiple = self.module.params.get('multiple')
data = self.module.params.get('data')
name = self.module.params.get('name')
record_type = self.module.params.get('record_type')
result = {}
for record in records or []:
if record.get('type') != record_type:
continue
if record.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 = record
elif record.get('data') == data:
return record
return result
def present_record(self):
record = self.get_record()
if not record:
record = self._create_record(record)
else:
record = self._update_record(record)
return record
def _create_record(self, record):
self.result['changed'] = True
data = {
'name': self.module.params.get('name'),
'domain': self.module.params.get('domain'),
'data': self.module.params.get('data'),
'type': self.module.params.get('record_type'),
'priority': self.module.params.get('priority'),
'ttl': self.module.params.get('ttl'),
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/dns/create_record",
method="POST",
data=data
)
record = self.get_record()
return record
def _update_record(self, record):
data = {
'RECORDID': record['RECORDID'],
'name': self.module.params.get('name'),
'domain': self.module.params.get('domain'),
'data': self.module.params.get('data'),
'type': self.module.params.get('record_type'),
'priority': self.module.params.get('priority'),
'ttl': self.module.params.get('ttl'),
}
has_changed = [k for k in data if k in record and data[k] != record[k]]
if has_changed:
self.result['changed'] = True
self.result['diff']['before'] = record
self.result['diff']['after'] = record.copy()
self.result['diff']['after'].update(data)
if not self.module.check_mode:
self.api_query(
path="/v1/dns/update_record",
method="POST",
data=data
)
record = self.get_record()
return record
def absent_record(self):
record = self.get_record()
if record:
self.result['changed'] = True
data = {
'RECORDID': record['RECORDID'],
'domain': self.module.params.get('domain'),
}
self.result['diff']['before'] = record
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/dns/delete_record",
method="POST",
data=data
)
return record
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
domain=dict(required=True),
name=dict(default="", aliases=['subrecord']),
state=dict(choices=['present', 'absent'], default='present'),
ttl=dict(type='int', default=300),
record_type=dict(choices=RECORD_TYPES, default='A', aliases=['type']),
multiple=dict(type='bool', default=False),
priority=dict(type='int', default=0),
data=dict()
))
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
('state', 'present', ['data']),
('multiple', True, ['data']),
],
supports_check_mode=True,
)
vultr_record = AnsibleVultrDnsRecord(module)
if module.params.get('state') == "absent":
record = vultr_record.absent_record()
else:
record = vultr_record.present_record()
result = vultr_record.get_result(record)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,203 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_firewall_group
short_description: Manages firewall groups on Vultr.
description:
- Create and remove firewall groups.
author: "René Moser (@resmo)"
options:
name:
description:
- Name of the firewall group.
required: true
aliases: [ description ]
state:
description:
- State of the firewall group.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: ensure a firewall group is present
local_action:
module: vultr_firewall_group
name: my http firewall
- name: ensure a firewall group is absent
local_action:
module: vultr_firewall_group
name: my http firewall
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_firewall_group:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: ID of the firewall group
returned: success
type: str
sample: 1234abcd
name:
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: "2017-08-26 12:47:48"
date_modified:
description: Date the firewall group was modified
returned: success
type: str
sample: "2017-08-26 12:47:48"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrFirewallGroup(Vultr):
def __init__(self, module):
super(AnsibleVultrFirewallGroup, self).__init__(module, "vultr_firewall_group")
self.returns = {
'FIREWALLGROUPID': dict(key='id'),
'description': dict(key='name'),
'date_created': dict(),
'date_modified': dict(),
}
def get_firewall_group(self):
firewall_groups = self.api_query(path="/v1/firewall/group_list")
if firewall_groups:
for firewall_group_id, firewall_group_data in firewall_groups.items():
if firewall_group_data.get('description') == self.module.params.get('name'):
return firewall_group_data
return {}
def present_firewall_group(self):
firewall_group = self.get_firewall_group()
if not firewall_group:
firewall_group = self._create_firewall_group(firewall_group)
return firewall_group
def _create_firewall_group(self, firewall_group):
self.result['changed'] = True
data = {
'description': self.module.params.get('name'),
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/firewall/group_create",
method="POST",
data=data
)
firewall_group = self.get_firewall_group()
return firewall_group
def absent_firewall_group(self):
firewall_group = self.get_firewall_group()
if firewall_group:
self.result['changed'] = True
data = {
'FIREWALLGROUPID': firewall_group['FIREWALLGROUPID'],
}
self.result['diff']['before'] = firewall_group
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/firewall/group_delete",
method="POST",
data=data
)
return firewall_group
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(required=True, aliases=['description']),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr_firewall_group = AnsibleVultrFirewallGroup(module)
if module.params.get('state') == "absent":
firewall_group = vultr_firewall_group.absent_firewall_group()
else:
firewall_group = vultr_firewall_group.present_firewall_group()
result = vultr_firewall_group.get_result(firewall_group)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_firewall_group_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_firewall_group_info) instead.
short_description: Gather facts about the Vultr firewall groups available.
description:
- Gather facts about firewall groups available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr firewall groups facts
local_action:
module: vultr_firewall_group_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_firewall_group_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_firewall_group_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_firewall_group_facts": [
{
"date_created": "2018-07-12 10:27:14",
"date_modified": "2018-07-12 10:27:14",
"description": "test",
"id": "5e128ff0",
"instance_count": 0,
"max_rule_count": 50,
"rule_count": 0
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrFirewallGroupFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrFirewallGroupFacts, self).__init__(module, "vultr_firewall_group_facts")
self.returns = {
"FIREWALLGROUPID": dict(key='id'),
"date_created": dict(),
"date_modified": dict(),
"description": dict(),
"instance_count": dict(convert_to='int'),
"max_rule_count": dict(convert_to='int'),
"rule_count": dict(convert_to='int')
}
def get_firewall_group(self):
return self.api_query(path="/v1/firewall/group_list")
def parse_fw_group_list(fwgroups_list):
if not fwgroups_list:
return []
return [group for id, group in fwgroups_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
fw_group_facts = AnsibleVultrFirewallGroupFacts(module)
result = fw_group_facts.get_result(parse_fw_group_list(fw_group_facts.get_firewall_group()))
ansible_facts = {
'vultr_firewall_group_facts': result['vultr_firewall_group_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,133 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_firewall_group_info
short_description: Gather information about the Vultr firewall groups available.
description:
- Gather information about firewall groups available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr firewall groups information
local_action:
module: vultr_firewall_group_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_firewall_group_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_firewall_group_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_firewall_group_info": [
{
"date_created": "2018-07-12 10:27:14",
"date_modified": "2018-07-12 10:27:14",
"description": "test",
"id": "5e128ff0",
"instance_count": 0,
"max_rule_count": 50,
"rule_count": 0
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrFirewallGroupInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrFirewallGroupInfo, self).__init__(module, "vultr_firewall_group_info")
self.returns = {
"FIREWALLGROUPID": dict(key='id'),
"date_created": dict(),
"date_modified": dict(),
"description": dict(),
"instance_count": dict(convert_to='int'),
"max_rule_count": dict(convert_to='int'),
"rule_count": dict(convert_to='int')
}
def get_firewall_group(self):
return self.api_query(path="/v1/firewall/group_list")
def parse_fw_group_list(fwgroups_list):
if not fwgroups_list:
return []
return [group for id, group in fwgroups_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
fw_group_info = AnsibleVultrFirewallGroupInfo(module)
result = fw_group_info.get_result(parse_fw_group_list(fw_group_info.get_firewall_group()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,383 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_firewall_rule
short_description: Manages firewall rules on Vultr.
description:
- Create and remove firewall rules.
author: "René Moser (@resmo)"
options:
group:
description:
- Name of the firewall group.
required: true
ip_version:
description:
- IP address version
choices: [ v4, v6 ]
default: v4
aliases: [ ip_type ]
protocol:
description:
- Protocol of the firewall rule.
choices: [ icmp, tcp, udp, gre ]
default: tcp
cidr:
description:
- Network in CIDR format
- The CIDR format must match with the C(ip_version) value.
- Required if C(state=present).
- Defaulted to 0.0.0.0/0 or ::/0 depending on C(ip_version).
start_port:
description:
- Start port for the firewall rule.
- Required if C(protocol) is tcp or udp and I(state=present).
aliases: [ port ]
end_port:
description:
- End port for the firewall rule.
- Only considered if C(protocol) is tcp or udp and I(state=present).
state:
description:
- State of the firewall rule.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: ensure a firewall rule is present
local_action:
module: vultr_firewall_rule
group: application
protocol: tcp
start_port: 8000
end_port: 9000
cidr: 17.17.17.0/24
- name: open DNS port for all ipv4 and ipv6
local_action:
module: vultr_firewall_rule
group: dns
protocol: udp
port: 53
ip_version: "{{ item }}"
with_items: [ v4, v6 ]
- name: allow ping
local_action:
module: vultr_firewall_rule
group: web
protocol: icmp
- name: ensure a firewall rule is absent
local_action:
module: vultr_firewall_rule
group: application
protocol: tcp
start_port: 8000
end_port: 9000
cidr: 17.17.17.0/24
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_firewall_rule:
description: Response from Vultr API
returned: success
type: complex
contains:
rule_number:
description: Rule number of the firewall rule
returned: success
type: int
sample: 2
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
start_port:
description: Start port of the firewall rule
returned: success and protocol is tcp or udp
type: int
sample: 80
end_port:
description: End port of the firewall rule
returned: success and when port range and protocol is tcp or udp
type: int
sample: 8080
cidr:
description: CIDR of the firewall rule (IPv4 or IPv6)
returned: success and when port range
type: str
sample: 0.0.0.0/0
group:
description: Firewall group the rule is into.
returned: success
type: str
sample: web
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrFirewallRule(Vultr):
def __init__(self, module):
super(AnsibleVultrFirewallRule, self).__init__(module, "vultr_firewall_rule")
self.returns = {
'rulenumber': dict(key='rule_number'),
'action': dict(),
'protocol': dict(),
'start_port': dict(convert_to='int'),
'end_port': dict(convert_to='int'),
'cidr': dict(),
'group': dict(),
}
self.firewall_group = None
def get_firewall_group(self):
if self.firewall_group is not None:
return self.firewall_group
firewall_groups = self.api_query(path="/v1/firewall/group_list")
if firewall_groups:
for firewall_group_id, firewall_group_data in firewall_groups.items():
if firewall_group_data.get('description') == self.module.params.get('group'):
self.firewall_group = firewall_group_data
return self.firewall_group
self.fail_json(msg="Firewall group not found: %s" % self.module.params.get('group'))
def _transform_cidr(self):
cidr = self.module.params.get('cidr')
ip_version = self.module.params.get('ip_version')
if cidr is None:
if ip_version == "v6":
cidr = "::/0"
else:
cidr = "0.0.0.0/0"
elif cidr.count('/') != 1:
self.fail_json(msg="CIDR has an invalid format: %s" % cidr)
return cidr.split('/')
def get_firewall_rule(self):
ip_version = self.module.params.get('ip_version')
firewall_group_id = self.get_firewall_group()['FIREWALLGROUPID']
firewall_rules = self.api_query(
path="/v1/firewall/rule_list"
"?FIREWALLGROUPID=%s"
"&direction=in"
"&ip_type=%s"
% (firewall_group_id, ip_version))
if firewall_rules:
subnet, subnet_size = self._transform_cidr()
for firewall_rule_id, firewall_rule_data in firewall_rules.items():
if firewall_rule_data.get('protocol') != self.module.params.get('protocol'):
continue
if ip_version == 'v4' and (firewall_rule_data.get('subnet') or "0.0.0.0") != subnet:
continue
if ip_version == 'v6' and (firewall_rule_data.get('subnet') or "::") != subnet:
continue
if int(firewall_rule_data.get('subnet_size')) != int(subnet_size):
continue
if firewall_rule_data.get('protocol') in ['tcp', 'udp']:
rule_port = firewall_rule_data.get('port')
end_port = self.module.params.get('end_port')
start_port = self.module.params.get('start_port')
# Port range "8000 - 8080" from the API
if ' - ' in rule_port:
if end_port is None:
continue
port_range = "%s - %s" % (start_port, end_port)
if rule_port == port_range:
return firewall_rule_data
# Single port
elif int(rule_port) == start_port:
return firewall_rule_data
else:
return firewall_rule_data
return {}
def present_firewall_rule(self):
firewall_rule = self.get_firewall_rule()
if not firewall_rule:
firewall_rule = self._create_firewall_rule(firewall_rule)
return firewall_rule
def _create_firewall_rule(self, firewall_rule):
protocol = self.module.params.get('protocol')
if protocol in ['tcp', 'udp']:
start_port = self.module.params.get('start_port')
if start_port is None:
self.module.fail_on_missing_params(['start_port'])
end_port = self.module.params.get('end_port')
if end_port is not None:
if start_port >= end_port:
self.module.fail_json(msg="end_port must be higher than start_port")
port_range = "%s:%s" % (start_port, end_port)
else:
port_range = start_port
else:
port_range = None
self.result['changed'] = True
subnet, subnet_size = self._transform_cidr()
data = {
'FIREWALLGROUPID': self.get_firewall_group()['FIREWALLGROUPID'],
'direction': 'in', # currently the only option
'ip_type': self.module.params.get('ip_version'),
'protocol': protocol,
'subnet': subnet,
'subnet_size': subnet_size,
'port': port_range
}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/firewall/rule_create",
method="POST",
data=data
)
firewall_rule = self.get_firewall_rule()
return firewall_rule
def absent_firewall_rule(self):
firewall_rule = self.get_firewall_rule()
if firewall_rule:
self.result['changed'] = True
data = {
'FIREWALLGROUPID': self.get_firewall_group()['FIREWALLGROUPID'],
'rulenumber': firewall_rule['rulenumber']
}
self.result['diff']['before'] = firewall_rule
if not self.module.check_mode:
self.api_query(
path="/v1/firewall/rule_delete",
method="POST",
data=data
)
return firewall_rule
def get_result(self, resource):
if resource:
if 'port' in resource and resource['protocol'] in ['tcp', 'udp']:
if ' - ' in resource['port']:
resource['start_port'], resource['end_port'] = resource['port'].split(' - ')
else:
resource['start_port'] = resource['port']
if 'subnet' in resource:
resource['cidr'] = "%s/%s" % (resource['subnet'], resource['subnet_size'])
resource['group'] = self.get_firewall_group()['description']
return super(AnsibleVultrFirewallRule, self).get_result(resource)
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
group=dict(required=True),
start_port=dict(type='int', aliases=['port']),
end_port=dict(type='int'),
protocol=dict(choices=['tcp', 'udp', 'gre', 'icmp'], default='tcp'),
cidr=dict(),
ip_version=dict(choices=['v4', 'v6'], default='v4', aliases=['ip_type']),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr_firewall_rule = AnsibleVultrFirewallRule(module)
if module.params.get('state') == "absent":
firewall_rule = vultr_firewall_rule.absent_firewall_rule()
else:
firewall_rule = vultr_firewall_rule.present_firewall_rule()
result = vultr_firewall_rule.get_result(firewall_rule)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,232 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_network
short_description: Manages networks on Vultr.
description:
- Manage networks on Vultr. A network cannot be updated. It needs to be deleted and re-created.
author: "Yanis Guenane (@Spredzy)"
options:
name:
description:
- Name of the network.
required: true
aliases: [ description, label ]
cidr:
description:
- The CIDR IPv4 network block to be used when attaching servers to this network. Required if I(state=present).
region:
description:
- Region the network is deployed into. Required if I(state=present).
state:
description:
- State of the network.
default: present
choices: [ present, absent ]
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: Ensure a network is present
local_action:
module: vultr_network
name: mynet
cidr: 192.168.42.0/24
region: Amsterdam
- name: Ensure a network is absent
local_action:
module: vultr_network
name: mynet
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_network:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: ID of the network
returned: success
type: str
sample: "net5b62c6dc63ef5"
name:
description: Name (label) of the network
returned: success
type: str
sample: "mynetwork"
date_created:
description: Date when the network was created
returned: success
type: str
sample: "2018-08-02 08:54:52"
region:
description: Region the network was deployed into
returned: success
type: str
sample: "Amsterdam"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrNetwork(Vultr):
def __init__(self, module):
super(AnsibleVultrNetwork, self).__init__(module, "vultr_network")
self.returns = {
'NETWORKID': dict(key='id'),
'DCID': dict(key='region', transform=self._get_region_name),
'date_created': dict(),
'description': dict(key='name'),
'v4_subnet': dict(),
'v4_subnet_mask': dict(convert_to='int'),
}
def _get_region_name(self, region_id=None):
return self.get_region().get('name')
def get_network(self):
networks = self.api_query(path="/v1/network/list")
if networks:
for id, network in networks.items():
if network.get('description') == self.module.params.get('name'):
return network
return {}
def present_network(self):
network = self.get_network()
if not network:
network = self._create_network(network)
return network
def _create_network(self, network):
self.result['changed'] = True
data = {
'description': self.module.params.get('name'),
'DCID': self.get_region()['DCID'],
'v4_subnet': self.module.params.get('cidr').split('/')[0],
'v4_subnet_mask': self.module.params.get('cidr').split('/')[1]
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/network/create",
method="POST",
data=data
)
network = self.get_network()
return network
def absent_network(self):
network = self.get_network()
if network:
self.result['changed'] = True
data = {
'NETWORKID': network['NETWORKID'],
}
self.result['diff']['before'] = network
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/network/destroy",
method="POST",
data=data
)
return network
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(required=True, aliases=['description', 'label']),
cidr=dict(),
region=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[['state', 'present', ['cidr', 'region']]]
)
vultr_network = AnsibleVultrNetwork(module)
if module.params.get('state') == "absent":
network = vultr_network.absent_network()
else:
network = vultr_network.present_network()
result = vultr_network.get_result(network)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,145 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_network_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_network_info) instead.
short_description: Gather facts about the Vultr networks available.
description:
- Gather facts about networks available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr networks facts
local_action:
module: vultr_network_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_network_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_network_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_network_facts": [
{
"date_created": "2018-08-02 11:18:49",
"id": "net5b62e8991adfg",
"name": "mynet",
"region": "Amsterdam",
"v4_subnet": "192.168.42.0",
"v4_subnet_mask": 24
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrNetworkFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrNetworkFacts, self).__init__(module, "vultr_network_facts")
self.returns = {
'DCID': dict(key='region', transform=self._get_region_name),
'NETWORKID': dict(key='id'),
'date_created': dict(),
'description': dict(key='name'),
'v4_subnet': dict(),
'v4_subnet_mask': dict(convert_to='int'),
}
def _get_region_name(self, region):
return self.query_resource_by_key(
key='DCID',
value=region,
resource='regions',
use_cache=True
)['name']
def get_networks(self):
return self.api_query(path="/v1/network/list")
def parse_network_list(network_list):
if isinstance(network_list, list):
return []
return [network for id, network in network_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
network_facts = AnsibleVultrNetworkFacts(module)
result = network_facts.get_result(parse_network_list(network_facts.get_networks()))
ansible_facts = {
'vultr_network_facts': result['vultr_network_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_network_info
short_description: Gather information about the Vultr networks available.
description:
- Gather information about networks available in Vultr.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr networks information
local_action:
module: vultr_network_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_network_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_network_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_network_info": [
{
"date_created": "2018-08-02 11:18:49",
"id": "net5b62e8991adfg",
"name": "mynet",
"region": "Amsterdam",
"v4_subnet": "192.168.42.0",
"v4_subnet_mask": 24
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrNetworkInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrNetworkInfo, self).__init__(module, "vultr_network_info")
self.returns = {
'DCID': dict(key='region', transform=self._get_region_name),
'NETWORKID': dict(key='id'),
'date_created': dict(),
'description': dict(key='name'),
'v4_subnet': dict(),
'v4_subnet_mask': dict(convert_to='int'),
}
def _get_region_name(self, region):
return self.query_resource_by_key(
key='DCID',
value=region,
resource='regions',
use_cache=True
)['name']
def get_networks(self):
return self.api_query(path="/v1/network/list")
def parse_network_list(network_list):
if isinstance(network_list, list):
return []
return [network for id, network in network_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
network_info = AnsibleVultrNetworkInfo(module)
result = network_info.get_result(parse_network_list(network_info.get_networks()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,133 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_os_facts
short_description: Gather facts about the Vultr OSes available.
description:
- Gather facts about OSes available to boot servers.
author: "Yanis Guenane (@Spredzy)"
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_os_info) instead.
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr OSes facts
local_action:
module: vultr_os_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_os_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
ansible_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_os_facts": [
{
"arch": "x64",
"family": "openbsd",
"id": 234,
"name": "OpenBSD 6 x64",
"windows": false
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrOSFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrOSFacts, self).__init__(module, "vultr_os_facts")
self.returns = {
"OSID": dict(key='id', convert_to='int'),
"arch": dict(),
"family": dict(),
"name": dict(),
"windows": dict(convert_to='bool')
}
def get_oses(self):
return self.api_query(path="/v1/os/list")
def parse_oses_list(oses_list):
return [os for id, os in oses_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
os_facts = AnsibleVultrOSFacts(module)
result = os_facts.get_result(parse_oses_list(os_facts.get_oses()))
ansible_facts = {
'vultr_os_facts': result['vultr_os_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2019, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_os_info
short_description: Get information about the Vultr OSes available.
description:
- Get infos about OSes available to boot servers.
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Get Vultr OSes infos
vultr_os_info:
register: results
- name: Print the gathered infos
debug:
var: results.vultr_os_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_os_info:
description: Response from Vultr API as list
returned: available
type: complex
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrOSInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrOSInfo, self).__init__(module, "vultr_os_info")
self.returns = {
"OSID": dict(key='id', convert_to='int'),
"arch": dict(),
"family": dict(),
"name": dict(),
"windows": dict(convert_to='bool')
}
def get_oses(self):
return self.api_query(path="/v1/os/list")
def parse_oses_list(oses_list):
return [os for id, os in oses_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
os_info = AnsibleVultrOSInfo(module)
result = os_info.get_result(parse_oses_list(os_info.get_oses()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,149 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_plan_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_plan_info) instead.
short_description: Gather facts about the Vultr plans available.
description:
- Gather facts about plans available to boot servers.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr plans facts
local_action:
module: vultr_plan_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_plan_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_plan_facts:
description: Response from Vultr API
returned: success
type: complex
contains:
plan:
description: List of the plans available.
returned: success
type: list
sample: [{
"available_locations": [
1
],
"bandwidth": 40.0,
"bandwidth_gb": 40960,
"disk": 110,
"id": 118,
"name": "32768 MB RAM,110 GB SSD,40.00 TB BW",
"plan_type": "DEDICATED",
"price_per_month": 240.0,
"ram": 32768,
"vcpu_count": 8,
"windows": false
}]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrPlanFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrPlanFacts, self).__init__(module, "vultr_plan_facts")
self.returns = {
"VPSPLANID": dict(key='id', convert_to='int'),
"available_locations": dict(),
"bandwidth": dict(convert_to='float'),
"bandwidth_gb": dict(convert_to='int'),
"disk": dict(convert_to='int'),
"name": dict(),
"plan_type": dict(),
"price_per_month": dict(convert_to='float'),
"ram": dict(convert_to='int'),
"vcpu_count": dict(convert_to='int'),
"windows": dict(convert_to='bool')
}
def get_plans(self):
return self.api_query(path="/v1/plans/list")
def parse_plans_list(plans_list):
return [plan for id, plan in plans_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
plan_facts = AnsibleVultrPlanFacts(module)
result = plan_facts.get_result(parse_plans_list(plan_facts.get_plans()))
ansible_facts = {
'vultr_plan_facts': result['vultr_plan_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,143 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_plan_info
short_description: Gather information about the Vultr plans available.
description:
- Gather information about plans available to boot servers.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr plans information
local_action:
module: vultr_plan_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_plan_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_plan_info:
description: Response from Vultr API
returned: success
type: complex
contains:
plan:
description: List of the plans available.
returned: success
type: list
sample: [{
"available_locations": [
1
],
"bandwidth": 40.0,
"bandwidth_gb": 40960,
"disk": 110,
"id": 118,
"name": "32768 MB RAM,110 GB SSD,40.00 TB BW",
"plan_type": "DEDICATED",
"price_per_month": 240.0,
"ram": 32768,
"vcpu_count": 8,
"windows": false
}]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrPlanInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrPlanInfo, self).__init__(module, "vultr_plan_info")
self.returns = {
"VPSPLANID": dict(key='id', convert_to='int'),
"available_locations": dict(),
"bandwidth": dict(convert_to='float'),
"bandwidth_gb": dict(convert_to='int'),
"disk": dict(convert_to='int'),
"name": dict(),
"plan_type": dict(),
"price_per_month": dict(convert_to='float'),
"ram": dict(convert_to='int'),
"vcpu_count": dict(convert_to='int'),
"windows": dict(convert_to='bool')
}
def get_plans(self):
return self.api_query(path="/v1/plans/list")
def parse_plans_list(plans_list):
return [plan for id, plan in plans_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
plan_info = AnsibleVultrPlanInfo(module)
result = plan_info.get_result(parse_plans_list(plan_info.get_plans()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,139 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_region_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_region_info) instead.
short_description: Gather facts about the Vultr regions available.
description:
- Gather facts about regions available to boot servers.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr regions facts
local_action:
module: vultr_region_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_region_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_region_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_region_facts": [
{
"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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrRegionFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrRegionFacts, self).__init__(module, "vultr_region_facts")
self.returns = {
"DCID": dict(key='id', convert_to='int'),
"block_storage": dict(convert_to='bool'),
"continent": dict(),
"country": dict(),
"ddos_protection": dict(convert_to='bool'),
"name": dict(),
"regioncode": dict(),
"state": dict()
}
def get_regions(self):
return self.api_query(path="/v1/regions/list")
def parse_regions_list(regions_list):
return [region for id, region in regions_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
region_facts = AnsibleVultrRegionFacts(module)
result = region_facts.get_result(parse_regions_list(region_facts.get_regions()))
ansible_facts = {
'vultr_region_facts': result['vultr_region_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,133 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_region_info
short_description: Gather information about the Vultr regions available.
description:
- Gather information about regions available to boot servers.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr regions information
local_action:
module: vultr_region_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_region_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_region_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_region_info": [
{
"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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrRegionInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrRegionInfo, self).__init__(module, "vultr_region_info")
self.returns = {
"DCID": dict(key='id', convert_to='int'),
"block_storage": dict(convert_to='bool'),
"continent": dict(),
"country": dict(),
"ddos_protection": dict(convert_to='bool'),
"name": dict(),
"regioncode": dict(),
"state": dict()
}
def get_regions(self):
return self.api_query(path="/v1/regions/list")
def parse_regions_list(regions_list):
return [region for id, region in regions_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
region_info = AnsibleVultrRegionInfo(module)
result = region_info.get_result(parse_regions_list(region_info.get_regions()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,940 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_server
short_description: Manages virtual servers on Vultr.
description:
- Deploy, start, stop, update, restart, reinstall servers.
author: "René Moser (@resmo)"
options:
name:
description:
- Name of the server.
required: true
aliases: [ label ]
type: str
hostname:
description:
- The hostname to assign to this server.
type: str
os:
description:
- The operating system name or ID.
- Required if the server does not yet exist and is not restoring from a snapshot.
type: str
snapshot:
description:
- Name or ID of the snapshot to restore the server from.
type: str
firewall_group:
description:
- The firewall group description or ID to assign this server to.
type: str
plan:
description:
- Plan name or ID to use for the server.
- Required if the server does not yet exist.
type: str
force:
description:
- Force stop/start the server if required to apply changes
- Otherwise a running server will not be changed.
type: bool
default: no
notify_activate:
description:
- Whether to send an activation email when the server is ready or not.
- Only considered on creation.
type: bool
private_network_enabled:
description:
- Whether to enable private networking or not.
type: bool
auto_backup_enabled:
description:
- Whether to enable automatic backups or not.
type: bool
ipv6_enabled:
description:
- Whether to enable IPv6 or not.
type: bool
tag:
description:
- Tag for the server.
type: str
user_data:
description:
- User data to be passed to the server.
type: str
startup_script:
description:
- Name or ID of the startup script to execute on boot.
- Only considered while creating the server.
type: str
ssh_keys:
description:
- List of SSH key names or IDs passed to the server on creation.
aliases: [ ssh_key ]
type: list
reserved_ip_v4:
description:
- IP address of the floating IP to use as the main IP of this server.
- Only considered on creation.
type: str
region:
description:
- Region name or ID the server is deployed into.
- Required if the server does not yet exist.
type: str
state:
description:
- State of the server.
default: present
choices: [ present, absent, restarted, reinstalled, started, stopped ]
type: str
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = '''
- name: create server
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
os: CentOS 7 x64
plan: 1024 MB RAM,25 GB SSD,1.00 TB BW
ssh_keys:
- my_key
- your_key
region: Amsterdam
state: present
- name: ensure a server is present and started
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
os: CentOS 7 x64
plan: 1024 MB RAM,25 GB SSD,1.00 TB BW
firewall_group: my_group
ssh_key: my_key
region: Amsterdam
state: started
- name: ensure a server is present and stopped provisioned using IDs
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
os: "167"
plan: "201"
region: "7"
state: stopped
- name: ensure an existing server is stopped
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
state: stopped
- name: ensure an existing server is started
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
state: started
- name: ensure a server is absent
delegate_to: localhost
vultr_server:
name: "{{ vultr_server_name }}"
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_server:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
contains:
id:
description: ID of the server
returned: success
type: str
sample: 10194376
name:
description: Name (label) of the server
returned: success
type: str
sample: "ansible-test-vm"
plan:
description: Plan used for the server
returned: success
type: str
sample: "1024 MB RAM,25 GB SSD,1.00 TB BW"
allowed_bandwidth_gb:
description: Allowed bandwidth to use in GB
returned: success
type: int
sample: 1000
auto_backup_enabled:
description: Whether automatic backups are enabled
returned: success
type: bool
sample: false
cost_per_month:
description: Cost per month for the server
returned: success
type: float
sample: 5.00
current_bandwidth_gb:
description: Current bandwidth used for the server
returned: success
type: int
sample: 0
date_created:
description: Date when the server was created
returned: success
type: str
sample: "2017-08-26 12:47:48"
default_password:
description: Password to login as root into the server
returned: success
type: str
sample: "!p3EWYJm$qDWYaFr"
disk:
description: Information about the disk
returned: success
type: str
sample: "Virtual 25 GB"
v4_gateway:
description: IPv4 gateway
returned: success
type: str
sample: "45.32.232.1"
internal_ip:
description: Internal IP
returned: success
type: str
sample: ""
kvm_url:
description: URL to the VNC
returned: success
type: str
sample: "https://my.vultr.com/subs/vps/novnc/api.php?data=xyz"
region:
description: Region the server was deployed into
returned: success
type: str
sample: "Amsterdam"
v4_main_ip:
description: Main IPv4
returned: success
type: str
sample: "45.32.233.154"
v4_netmask:
description: Netmask IPv4
returned: success
type: str
sample: "255.255.254.0"
os:
description: Operating system used for the server
returned: success
type: str
sample: "CentOS 6 x64"
firewall_group:
description: Firewall group the server is assigned to
returned: success and available
type: str
sample: "CentOS 6 x64"
pending_charges:
description: Pending charges
returned: success
type: float
sample: 0.01
power_status:
description: Power status of the server
returned: success
type: str
sample: "running"
ram:
description: Information about the RAM size
returned: success
type: str
sample: "1024 MB"
server_state:
description: State about the server
returned: success
type: str
sample: "ok"
status:
description: Status about the deployment of the server
returned: success
type: str
sample: "active"
tag:
description: TBD
returned: success
type: str
sample: ""
v6_main_ip:
description: Main IPv6
returned: success
type: str
sample: ""
v6_network:
description: Network IPv6
returned: success
type: str
sample: ""
v6_network_size:
description: Network size IPv6
returned: success
type: str
sample: ""
v6_networks:
description: Networks IPv6
returned: success
type: list
sample: []
vcpu_count:
description: Virtual CPU count
returned: success
type: int
sample: 1
'''
import time
import base64
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_text, to_bytes
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrServer(Vultr):
def __init__(self, module):
super(AnsibleVultrServer, self).__init__(module, "vultr_server")
self.server = None
self.returns = {
'SUBID': dict(key='id'),
'label': dict(key='name'),
'date_created': dict(),
'allowed_bandwidth_gb': dict(convert_to='int'),
'auto_backups': dict(key='auto_backup_enabled', convert_to='bool'),
'current_bandwidth_gb': dict(),
'kvm_url': dict(),
'default_password': dict(),
'internal_ip': dict(),
'disk': dict(),
'cost_per_month': dict(convert_to='float'),
'location': dict(key='region'),
'main_ip': dict(key='v4_main_ip'),
'network_v4': dict(key='v4_network'),
'gateway_v4': dict(key='v4_gateway'),
'os': dict(),
'pending_charges': dict(convert_to='float'),
'power_status': dict(),
'ram': dict(),
'plan': dict(),
'server_state': dict(),
'status': dict(),
'firewall_group': dict(),
'tag': dict(),
'v6_main_ip': dict(),
'v6_network': dict(),
'v6_network_size': dict(),
'v6_networks': dict(),
'vcpu_count': dict(convert_to='int'),
}
self.server_power_state = None
def get_startup_script(self):
return self.query_resource_by_key(
key='name',
value=self.module.params.get('startup_script'),
resource='startupscript',
)
def get_os(self):
if self.module.params.get('snapshot'):
os_name = 'Snapshot'
else:
os_name = self.module.params.get('os')
return self.query_resource_by_key(
key='name',
value=os_name,
resource='os',
use_cache=True,
id_key='OSID',
)
def get_snapshot(self):
return self.query_resource_by_key(
key='description',
value=self.module.params.get('snapshot'),
resource='snapshot',
id_key='SNAPSHOTID',
)
def get_ssh_keys(self):
ssh_key_names = self.module.params.get('ssh_keys')
if not ssh_key_names:
return []
ssh_keys = []
for ssh_key_name in ssh_key_names:
ssh_key = self.query_resource_by_key(
key='name',
value=ssh_key_name,
resource='sshkey',
use_cache=True,
id_key='SSHKEYID',
)
if ssh_key:
ssh_keys.append(ssh_key)
return ssh_keys
def get_region(self):
return self.query_resource_by_key(
key='name',
value=self.module.params.get('region'),
resource='regions',
use_cache=True,
id_key='DCID',
)
def get_firewall_group(self):
return self.query_resource_by_key(
key='description',
value=self.module.params.get('firewall_group'),
resource='firewall',
query_by='group_list',
id_key='FIREWALLGROUPID'
)
def get_user_data(self):
user_data = self.module.params.get('user_data')
if user_data is not None:
user_data = to_text(base64.b64encode(to_bytes(user_data)))
return user_data
def get_server_user_data(self, server):
if not server or not server.get('SUBID'):
return None
user_data = self.api_query(path="/v1/server/get_user_data?SUBID=%s" % server.get('SUBID'))
return user_data.get('userdata')
def get_server(self, refresh=False):
if self.server is None or refresh:
self.server = None
server_list = self.api_query(path="/v1/server/list")
if server_list:
for server_id, server_data in server_list.items():
if server_data.get('label') == self.module.params.get('name'):
self.server = server_data
plan = self.query_resource_by_key(
key='VPSPLANID',
value=server_data['VPSPLANID'],
resource='plans',
use_cache=True
)
self.server['plan'] = plan.get('name')
os = self.query_resource_by_key(
key='OSID',
value=int(server_data['OSID']),
resource='os',
use_cache=True
)
self.server['os'] = os.get('name')
fwg_id = server_data.get('FIREWALLGROUPID')
fw = self.query_resource_by_key(
key='FIREWALLGROUPID',
value=server_data.get('FIREWALLGROUPID') if fwg_id and fwg_id != "0" else None,
resource='firewall',
query_by='group_list',
use_cache=True
)
self.server['firewall_group'] = fw.get('description')
return self.server
def present_server(self, start_server=True):
server = self.get_server()
if not server:
server = self._create_server(server=server)
else:
server = self._update_server(server=server, start_server=start_server)
return server
def _create_server(self, server=None):
required_params = [
'os',
'plan',
'region',
]
snapshot_restore = self.module.params.get('snapshot') is not None
if snapshot_restore:
required_params.remove('os')
self.module.fail_on_missing_params(required_params=required_params)
self.result['changed'] = True
if not self.module.check_mode:
data = {
'DCID': self.get_region().get('DCID'),
'VPSPLANID': self.get_plan().get('VPSPLANID'),
'FIREWALLGROUPID': self.get_firewall_group().get('FIREWALLGROUPID'),
'OSID': self.get_os().get('OSID'),
'SNAPSHOTID': self.get_snapshot().get('SNAPSHOTID'),
'label': self.module.params.get('name'),
'hostname': self.module.params.get('hostname'),
'SSHKEYID': ','.join([ssh_key['SSHKEYID'] for ssh_key in self.get_ssh_keys()]),
'enable_ipv6': self.get_yes_or_no('ipv6_enabled'),
'enable_private_network': self.get_yes_or_no('private_network_enabled'),
'auto_backups': self.get_yes_or_no('auto_backup_enabled'),
'notify_activate': self.get_yes_or_no('notify_activate'),
'tag': self.module.params.get('tag'),
'reserved_ip_v4': self.module.params.get('reserved_ip_v4'),
'user_data': self.get_user_data(),
'SCRIPTID': self.get_startup_script().get('SCRIPTID'),
}
self.api_query(
path="/v1/server/create",
method="POST",
data=data
)
server = self._wait_for_state(key='status', state='active')
server = self._wait_for_state(state='running', timeout=3600 if snapshot_restore else 60)
return server
def _update_auto_backups_setting(self, server, start_server):
auto_backup_enabled_changed = self.switch_enable_disable(server, 'auto_backup_enabled', 'auto_backups')
if auto_backup_enabled_changed:
if auto_backup_enabled_changed == "enable" and server['auto_backups'] == 'disable':
self.module.warn("Backups are disabled. Once disabled, backups can only be enabled again by customer support")
else:
server, warned = self._handle_power_status_for_update(server, start_server)
if not warned:
self.result['changed'] = True
self.result['diff']['before']['auto_backup_enabled'] = server.get('auto_backups')
self.result['diff']['after']['auto_backup_enabled'] = self.get_yes_or_no('auto_backup_enabled')
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/backup_%s" % auto_backup_enabled_changed,
method="POST",
data=data
)
return server
def _update_ipv6_setting(self, server, start_server):
ipv6_enabled_changed = self.switch_enable_disable(server, 'ipv6_enabled', 'v6_main_ip')
if ipv6_enabled_changed:
if ipv6_enabled_changed == "disable":
self.module.warn("The Vultr API does not allow to disable IPv6")
else:
server, warned = self._handle_power_status_for_update(server, start_server)
if not warned:
self.result['changed'] = True
self.result['diff']['before']['ipv6_enabled'] = False
self.result['diff']['after']['ipv6_enabled'] = True
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/ipv6_%s" % ipv6_enabled_changed,
method="POST",
data=data
)
server = self._wait_for_state(key='v6_main_ip')
return server
def _update_private_network_setting(self, server, start_server):
private_network_enabled_changed = self.switch_enable_disable(server, 'private_network_enabled', 'internal_ip')
if private_network_enabled_changed:
if private_network_enabled_changed == "disable":
self.module.warn("The Vultr API does not allow to disable private network")
else:
server, warned = self._handle_power_status_for_update(server, start_server)
if not warned:
self.result['changed'] = True
self.result['diff']['before']['private_network_enabled'] = False
self.result['diff']['after']['private_network_enabled'] = True
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/private_network_%s" % private_network_enabled_changed,
method="POST",
data=data
)
return server
def _update_plan_setting(self, server, start_server):
# Verify the exising plan is not discontined by Vultr and therefore won't be found by the API
server_plan = self.get_plan(plan=server.get('VPSPLANID'), optional=True)
if not server_plan:
plan = self.get_plan(optional=True)
if not plan:
self.module.warn("The plan used to create the server is not longer available as well as the desired plan. Assuming same plan, keeping as is.")
return server
else:
plan = self.get_plan()
plan_changed = True if plan and plan['VPSPLANID'] != server.get('VPSPLANID') else False
if plan_changed:
server, warned = self._handle_power_status_for_update(server, start_server)
if not warned:
self.result['changed'] = True
self.result['diff']['before']['plan'] = server.get('plan')
self.result['diff']['after']['plan'] = plan['name']
if not self.module.check_mode:
data = {
'SUBID': server['SUBID'],
'VPSPLANID': plan['VPSPLANID'],
}
self.api_query(
path="/v1/server/upgrade_plan",
method="POST",
data=data
)
return server
def _handle_power_status_for_update(self, server, start_server):
# Remember the power state before we handle any action
if self.server_power_state is None:
self.server_power_state = server['power_status']
# A stopped server can be updated
if self.server_power_state == "stopped":
return server, False
# A running server must be forced to update unless the wanted state is stopped
elif self.module.params.get('force') or not start_server:
warned = False
if not self.module.check_mode:
# Some update APIs would restart the VM, we handle the restart manually
# by stopping the server and start it at the end of the changes
server = self.stop_server(skip_results=True)
# Warn the user that a running server won't get changed
else:
warned = True
self.module.warn("Some changes won't be applied to running instances. " +
"Use force=true to allow the instance %s to be stopped/started." % server['label'])
return server, warned
def _update_server(self, server=None, start_server=True):
# Wait for server to unlock if restoring
if server.get('os').strip() == 'Snapshot':
server = self._wait_for_state(key='server_status', state='ok', timeout=3600)
# Update auto backups settings, stops server
server = self._update_auto_backups_setting(server=server, start_server=start_server)
# Update IPv6 settings, stops server
server = self._update_ipv6_setting(server=server, start_server=start_server)
# Update private network settings, stops server
server = self._update_private_network_setting(server=server, start_server=start_server)
# Update plan settings, stops server
server = self._update_plan_setting(server=server, start_server=start_server)
# User data
user_data = self.get_user_data()
server_user_data = self.get_server_user_data(server=server)
if user_data is not None and user_data != server_user_data:
self.result['changed'] = True
self.result['diff']['before']['user_data'] = server_user_data
self.result['diff']['after']['user_data'] = user_data
if not self.module.check_mode:
data = {
'SUBID': server['SUBID'],
'userdata': user_data,
}
self.api_query(
path="/v1/server/set_user_data",
method="POST",
data=data
)
# Tags
tag = self.module.params.get('tag')
if tag is not None and tag != server.get('tag'):
self.result['changed'] = True
self.result['diff']['before']['tag'] = server.get('tag')
self.result['diff']['after']['tag'] = tag
if not self.module.check_mode:
data = {
'SUBID': server['SUBID'],
'tag': tag,
}
self.api_query(
path="/v1/server/tag_set",
method="POST",
data=data
)
# Firewall group
firewall_group = self.get_firewall_group()
if firewall_group and firewall_group.get('description') != server.get('firewall_group'):
self.result['changed'] = True
self.result['diff']['before']['firewall_group'] = server.get('firewall_group')
self.result['diff']['after']['firewall_group'] = firewall_group.get('description')
if not self.module.check_mode:
data = {
'SUBID': server['SUBID'],
'FIREWALLGROUPID': firewall_group.get('FIREWALLGROUPID'),
}
self.api_query(
path="/v1/server/firewall_group_set",
method="POST",
data=data
)
# Start server again if it was running before the changes
if not self.module.check_mode:
if self.server_power_state in ['starting', 'running'] and start_server:
server = self.start_server(skip_results=True)
server = self._wait_for_state(key='status', state='active')
return server
def absent_server(self):
server = self.get_server()
if server:
self.result['changed'] = True
self.result['diff']['before']['id'] = server['SUBID']
self.result['diff']['after']['id'] = ""
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/destroy",
method="POST",
data=data
)
for s in range(0, 60):
if server is not None:
break
time.sleep(2)
server = self.get_server(refresh=True)
else:
self.fail_json(msg="Wait for server '%s' to get deleted timed out" % server['label'])
return server
def restart_server(self):
self.result['changed'] = True
server = self.get_server()
if server:
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/reboot",
method="POST",
data=data
)
server = self._wait_for_state(state='running')
return server
def reinstall_server(self):
self.result['changed'] = True
server = self.get_server()
if server:
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/reinstall",
method="POST",
data=data
)
server = self._wait_for_state(state='running')
return server
def _wait_for_state(self, key='power_status', state=None, timeout=60):
time.sleep(1)
server = self.get_server(refresh=True)
for s in range(0, timeout):
# Check for Truely if wanted state is None
if state is None and server.get(key):
break
elif server.get(key) == state:
break
time.sleep(2)
server = self.get_server(refresh=True)
# Timed out
else:
if state is None:
msg = "Wait for '%s' timed out" % key
else:
msg = "Wait for '%s' to get into state '%s' timed out" % (key, state)
self.fail_json(msg=msg)
return server
def start_server(self, skip_results=False):
server = self.get_server()
if server:
if server['power_status'] == 'starting':
server = self._wait_for_state(state='running')
elif server['power_status'] != 'running':
if not skip_results:
self.result['changed'] = True
self.result['diff']['before']['power_status'] = server['power_status']
self.result['diff']['after']['power_status'] = "running"
if not self.module.check_mode:
data = {
'SUBID': server['SUBID']
}
self.api_query(
path="/v1/server/start",
method="POST",
data=data
)
server = self._wait_for_state(state='running')
return server
def stop_server(self, skip_results=False):
server = self.get_server()
if server and server['power_status'] != "stopped":
if not skip_results:
self.result['changed'] = True
self.result['diff']['before']['power_status'] = server['power_status']
self.result['diff']['after']['power_status'] = "stopped"
if not self.module.check_mode:
data = {
'SUBID': server['SUBID'],
}
self.api_query(
path="/v1/server/halt",
method="POST",
data=data
)
server = self._wait_for_state(state='stopped')
return server
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(required=True, aliases=['label']),
hostname=dict(type='str'),
os=dict(type='str'),
snapshot=dict(type='str'),
plan=dict(type='str'),
force=dict(type='bool', default=False),
notify_activate=dict(type='bool', default=False),
private_network_enabled=dict(type='bool'),
auto_backup_enabled=dict(type='bool'),
ipv6_enabled=dict(type='bool'),
tag=dict(type='str'),
reserved_ip_v4=dict(type='str'),
firewall_group=dict(type='str'),
startup_script=dict(type='str'),
user_data=dict(type='str'),
ssh_keys=dict(type='list', aliases=['ssh_key']),
region=dict(type='str'),
state=dict(choices=['present', 'absent', 'restarted', 'reinstalled', 'started', 'stopped'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
vultr_server = AnsibleVultrServer(module)
if module.params.get('state') == "absent":
server = vultr_server.absent_server()
else:
if module.params.get('state') == "started":
server = vultr_server.present_server()
server = vultr_server.start_server()
elif module.params.get('state') == "stopped":
server = vultr_server.present_server(start_server=False)
server = vultr_server.stop_server()
elif module.params.get('state') == "restarted":
server = vultr_server.present_server()
server = vultr_server.restart_server()
elif module.params.get('state') == "reinstalled":
server = vultr_server.reinstall_server()
else:
server = vultr_server.present_server()
result = vultr_server.get_result(server)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,198 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_server_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_server_info) instead.
short_description: Gather facts about the Vultr servers available.
description:
- Gather facts about servers available.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr servers facts
local_action:
module: vultr_server_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_server_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_server_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_server_facts": [
{
"allowed_bandwidth_gb": 1000,
"auto_backup_enabled": false,
"application": null,
"cost_per_month": 5.00,
"current_bandwidth_gb": 0,
"date_created": "2018-07-19 08:23:03",
"default_password": "p4ssw0rd!",
"disk": "Virtual 25 GB",
"firewallgroup": null,
"id": 17241096,
"internal_ip": "",
"kvm_url": "https://my.vultr.com/subs/vps/novnc/api.php?data=OFB...",
"name": "ansibletest",
"os": "CentOS 7 x64",
"pending_charges": 0.01,
"plan": "1024 MB RAM,25 GB SSD,1.00 TB BW",
"power_status": "running",
"ram": "1024 MB",
"region": "Amsterdam",
"server_state": "ok",
"status": "active",
"tag": "",
"v4_gateway": "105.178.158.1",
"v4_main_ip": "105.178.158.181",
"v4_netmask": "255.255.254.0",
"v6_main_ip": "",
"v6_network": "",
"v6_network_size": "",
"v6_networks": [],
"vcpu_count": 1
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrServerFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrServerFacts, self).__init__(module, "vultr_server_facts")
self.returns = {
"APPID": dict(key='application', convert_to='int', transform=self._get_application_name),
"FIREWALLGROUPID": dict(key='firewallgroup', transform=self._get_firewallgroup_name),
"SUBID": dict(key='id', convert_to='int'),
"VPSPLANID": dict(key='plan', convert_to='int', transform=self._get_plan_name),
"allowed_bandwidth_gb": dict(convert_to='int'),
'auto_backups': dict(key='auto_backup_enabled', convert_to='bool'),
"cost_per_month": dict(convert_to='float'),
"current_bandwidth_gb": dict(convert_to='float'),
"date_created": dict(),
"default_password": dict(),
"disk": dict(),
"gateway_v4": dict(key='v4_gateway'),
"internal_ip": dict(),
"kvm_url": dict(),
"label": dict(key='name'),
"location": dict(key='region'),
"main_ip": dict(key='v4_main_ip'),
"netmask_v4": dict(key='v4_netmask'),
"os": dict(),
"pending_charges": dict(convert_to='float'),
"power_status": dict(),
"ram": dict(),
"server_state": dict(),
"status": dict(),
"tag": dict(),
"v6_main_ip": dict(),
"v6_network": dict(),
"v6_network_size": dict(),
"v6_networks": dict(),
"vcpu_count": dict(convert_to='int'),
}
def _get_application_name(self, application):
if application == 0:
return None
return self.get_application(application, 'APPID').get('name')
def _get_firewallgroup_name(self, firewallgroup):
if firewallgroup == 0:
return None
return self.get_firewallgroup(firewallgroup, 'FIREWALLGROUPID').get('description')
def _get_plan_name(self, plan):
return self.get_plan(plan, 'VPSPLANID').get('name')
def get_servers(self):
return self.api_query(path="/v1/server/list")
def parse_servers_list(servers_list):
return [server for id, server in servers_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
server_facts = AnsibleVultrServerFacts(module)
result = server_facts.get_result(parse_servers_list(server_facts.get_servers()))
ansible_facts = {
'vultr_server_facts': result['vultr_server_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,192 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_server_info
short_description: Gather information about the Vultr servers available.
description:
- Gather information about servers available.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr servers information
local_action:
module: vultr_server_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_server_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_server_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_server_info": [
{
"allowed_bandwidth_gb": 1000,
"auto_backup_enabled": false,
"application": null,
"cost_per_month": 5.00,
"current_bandwidth_gb": 0,
"date_created": "2018-07-19 08:23:03",
"default_password": "p4ssw0rd!",
"disk": "Virtual 25 GB",
"firewallgroup": null,
"id": 17241096,
"internal_ip": "",
"kvm_url": "https://my.vultr.com/subs/vps/novnc/api.php?data=OFB...",
"name": "ansibletest",
"os": "CentOS 7 x64",
"pending_charges": 0.01,
"plan": "1024 MB RAM,25 GB SSD,1.00 TB BW",
"power_status": "running",
"ram": "1024 MB",
"region": "Amsterdam",
"server_state": "ok",
"status": "active",
"tag": "",
"v4_gateway": "105.178.158.1",
"v4_main_ip": "105.178.158.181",
"v4_netmask": "255.255.254.0",
"v6_main_ip": "",
"v6_network": "",
"v6_network_size": "",
"v6_networks": [],
"vcpu_count": 1
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrServerInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrServerInfo, self).__init__(module, "vultr_server_info")
self.returns = {
"APPID": dict(key='application', convert_to='int', transform=self._get_application_name),
"FIREWALLGROUPID": dict(key='firewallgroup', transform=self._get_firewallgroup_name),
"SUBID": dict(key='id', convert_to='int'),
"VPSPLANID": dict(key='plan', convert_to='int', transform=self._get_plan_name),
"allowed_bandwidth_gb": dict(convert_to='int'),
'auto_backups': dict(key='auto_backup_enabled', convert_to='bool'),
"cost_per_month": dict(convert_to='float'),
"current_bandwidth_gb": dict(convert_to='float'),
"date_created": dict(),
"default_password": dict(),
"disk": dict(),
"gateway_v4": dict(key='v4_gateway'),
"internal_ip": dict(),
"kvm_url": dict(),
"label": dict(key='name'),
"location": dict(key='region'),
"main_ip": dict(key='v4_main_ip'),
"netmask_v4": dict(key='v4_netmask'),
"os": dict(),
"pending_charges": dict(convert_to='float'),
"power_status": dict(),
"ram": dict(),
"server_state": dict(),
"status": dict(),
"tag": dict(),
"v6_main_ip": dict(),
"v6_network": dict(),
"v6_network_size": dict(),
"v6_networks": dict(),
"vcpu_count": dict(convert_to='int'),
}
def _get_application_name(self, application):
if application == 0:
return None
return self.get_application(application, 'APPID').get('name')
def _get_firewallgroup_name(self, firewallgroup):
if firewallgroup == 0:
return None
return self.get_firewallgroup(firewallgroup, 'FIREWALLGROUPID').get('description')
def _get_plan_name(self, plan):
return self.get_plan(plan, 'VPSPLANID', optional=True).get('name') or 'N/A'
def get_servers(self):
return self.api_query(path="/v1/server/list")
def parse_servers_list(servers_list):
return [server for id, server in servers_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
server_info = AnsibleVultrServerInfo(module)
result = server_info.get_result(parse_servers_list(server_info.get_servers()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,238 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: vultr_ssh_key
short_description: Manages ssh keys on Vultr.
description:
- Create, update and remove ssh keys.
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:
- community.general.vultr
'''
EXAMPLES = '''
- name: ensure an SSH key is present
vultr_ssh_key:
name: my ssh key
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: ensure an SSH key is absent
vultr_ssh_key:
name: my ssh key
state: absent
'''
RETURN = '''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_ssh_key:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: ID of the ssh key
returned: success
type: str
sample: 5904bc6ed9234
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: "2017-08-26 12:47:48"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrSshKey(Vultr):
def __init__(self, module):
super(AnsibleVultrSshKey, self).__init__(module, "vultr_ssh_key")
self.returns = {
'SSHKEYID': dict(key='id'),
'name': dict(),
'ssh_key': dict(),
'date_created': dict(),
}
def get_ssh_key(self):
ssh_keys = self.api_query(path="/v1/sshkey/list")
if ssh_keys:
for ssh_key_id, ssh_key_data in ssh_keys.items():
if ssh_key_data.get('name') == self.module.params.get('name'):
return ssh_key_data
return {}
def present_ssh_key(self):
ssh_key = self.get_ssh_key()
if not ssh_key:
ssh_key = self._create_ssh_key(ssh_key)
else:
ssh_key = self._update_ssh_key(ssh_key)
return ssh_key
def _create_ssh_key(self, ssh_key):
self.result['changed'] = True
data = {
'name': self.module.params.get('name'),
'ssh_key': self.module.params.get('ssh_key'),
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/sshkey/create",
method="POST",
data=data
)
ssh_key = self.get_ssh_key()
return ssh_key
def _update_ssh_key(self, ssh_key):
param_ssh_key = self.module.params.get('ssh_key')
if param_ssh_key != ssh_key['ssh_key']:
self.result['changed'] = True
data = {
'SSHKEYID': ssh_key['SSHKEYID'],
'ssh_key': param_ssh_key,
}
self.result['diff']['before'] = ssh_key
self.result['diff']['after'] = data
self.result['diff']['after'].update({'date_created': ssh_key['date_created']})
if not self.module.check_mode:
self.api_query(
path="/v1/sshkey/update",
method="POST",
data=data
)
ssh_key = self.get_ssh_key()
return ssh_key
def absent_ssh_key(self):
ssh_key = self.get_ssh_key()
if ssh_key:
self.result['changed'] = True
data = {
'SSHKEYID': ssh_key['SSHKEYID'],
}
self.result['diff']['before'] = ssh_key
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/sshkey/destroy",
method="POST",
data=data
)
return ssh_key
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(type='str', required=True),
ssh_key=dict(type='str',),
state=dict(type='str', choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
('state', 'present', ['ssh_key']),
],
supports_check_mode=True,
)
vultr_ssh_key = AnsibleVultrSshKey(module)
if module.params.get('state') == "absent":
ssh_key = vultr_ssh_key.absent_ssh_key()
else:
ssh_key = vultr_ssh_key.present_ssh_key()
result = vultr_ssh_key.get_result(ssh_key)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,134 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_ssh_key_facts
short_description: Gather facts about the Vultr SSH keys available.
description:
- Gather facts about SSH keys available.
author: "Yanis Guenane (@Spredzy)"
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_ssh_key_info) instead.
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr SSH keys facts
local_action:
module: vultr_ssh_key_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_ssh_key_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
ansible_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_ssh_key_facts": [
{
"date_created": "2018-02-24 15:04:01",
"id": "5abf426403479",
"name": "me@home",
"ssh_key": "ssh-rsa AAAAB3Nz...NnPz me@home"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrSSHKeyFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrSSHKeyFacts, self).__init__(module, "vultr_ssh_key_facts")
self.returns = {
'SSHKEYID': dict(key='id'),
'name': dict(),
'ssh_key': dict(),
'date_created': dict(),
}
def get_sshkeys(self):
return self.api_query(path="/v1/sshkey/list")
def parse_keys_list(keys_list):
if not keys_list:
return []
return [key for id, key in keys_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
sshkey_facts = AnsibleVultrSSHKeyFacts(module)
result = sshkey_facts.get_result(parse_keys_list(sshkey_facts.get_sshkeys()))
ansible_facts = {
'vultr_ssh_key_facts': result['vultr_ssh_key_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,143 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# (c) 2019, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_ssh_key_info
short_description: Get information about the Vultr SSH keys available.
description:
- Get infos about SSH keys available.
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Get Vultr SSH keys infos
vultr_ssh_key_info:
register: result
- name: Print the infos
debug:
var: result.vultr_ssh_key_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_ssh_key_info:
description: Response from Vultr API as list
returned: success
type: complex
contains:
id:
description: ID of the ssh key
returned: success
type: str
sample: 5904bc6ed9234
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: "2017-08-26 12:47:48"
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrSSHKeyInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrSSHKeyInfo, self).__init__(module, "vultr_ssh_key_info")
self.returns = {
'SSHKEYID': dict(key='id'),
'name': dict(),
'ssh_key': dict(),
'date_created': dict(),
}
def get_sshkeys(self):
return self.api_query(path="/v1/sshkey/list")
def parse_keys_list(keys_list):
if not keys_list:
return []
return [key for id, key in keys_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
sshkey_info = AnsibleVultrSSHKeyInfo(module)
result = sshkey_info.get_result(parse_keys_list(sshkey_info.get_sshkeys()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,267 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_startup_script
short_description: Manages startup scripts on Vultr.
description:
- Create, update and remove startup scripts.
author: "René Moser (@resmo)"
options:
name:
description:
- The script name.
required: true
type: str
script_type:
description:
- The script type, can not be changed once created.
default: boot
choices: [ boot, pxe ]
aliases: [ 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:
- community.general.vultr
'''
EXAMPLES = r'''
- name: ensure a pxe script exists, source from a file
vultr_startup_script:
name: my_web_script
script_type: pxe
script: "{{ lookup('file', 'path/to/script') }}"
- name: ensure a boot script exists
vultr_startup_script:
name: vultr_startup_script
script: "#!/bin/bash\necho Hello World > /root/hello"
- name: ensure a script is absent
vultr_startup_script:
name: my_web_script
state: absent
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_startup_script:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: ID of the startup script.
returned: success
type: str
sample: 249395
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"
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: "2017-08-26 12:47:48"
date_modified:
description: Date the startup script was modified.
returned: success
type: str
sample: "2017-08-26 12:47:48"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrStartupScript(Vultr):
def __init__(self, module):
super(AnsibleVultrStartupScript, self).__init__(module, "vultr_startup_script")
self.returns = {
'SCRIPTID': dict(key='id'),
'type': dict(key='script_type'),
'name': dict(),
'script': dict(),
'date_created': dict(),
'date_modified': dict(),
}
def get_script(self):
scripts = self.api_query(path="/v1/startupscript/list")
name = self.module.params.get('name')
if scripts:
for script_id, script_data in scripts.items():
if script_data.get('name') == name:
return script_data
return {}
def present_script(self):
script = self.get_script()
if not script:
script = self._create_script(script)
else:
script = self._update_script(script)
return script
def _create_script(self, script):
self.result['changed'] = True
data = {
'name': self.module.params.get('name'),
'script': self.module.params.get('script'),
'type': self.module.params.get('script_type'),
}
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
self.api_query(
path="/v1/startupscript/create",
method="POST",
data=data
)
script = self.get_script()
return script
def _update_script(self, script):
if script['script'] != self.module.params.get('script'):
self.result['changed'] = True
data = {
'SCRIPTID': script['SCRIPTID'],
'script': self.module.params.get('script'),
}
self.result['diff']['before'] = script
self.result['diff']['after'] = script.copy()
self.result['diff']['after'].update(data)
if not self.module.check_mode:
self.api_query(
path="/v1/startupscript/update",
method="POST",
data=data
)
script = self.get_script()
return script
def absent_script(self):
script = self.get_script()
if script:
self.result['changed'] = True
data = {
'SCRIPTID': script['SCRIPTID'],
}
self.result['diff']['before'] = script
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/startupscript/destroy",
method="POST",
data=data
)
return script
def main():
argument_spec = vultr_argument_spec()
argument_spec.update(dict(
name=dict(type='str', required=True),
script=dict(type='str',),
script_type=dict(type='str', default='boot', choices=['boot', 'pxe'], aliases=['type']),
state=dict(type='str', choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
('state', 'present', ['script']),
],
supports_check_mode=True,
)
vultr_script = AnsibleVultrStartupScript(module)
if module.params.get('state') == "absent":
script = vultr_script.absent_script()
else:
script = vultr_script.present_script()
result = vultr_script.get_result(script)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,138 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_startup_script_facts
deprecated:
removed_in: '2.13'
why: Deprecated in favour of C(_info) module.
alternative: Use M(vultr_startup_script_info) instead.
short_description: Gather facts about the Vultr startup scripts available.
description:
- Gather facts about vultr_startup_scripts available.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr startup scripts facts
local_action:
module: vultr_startup_script_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_startup_script_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_startup_script_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_startup_script_facts": [
{
"date_created": "2018-07-19 08:38:36",
"date_modified": "2018-07-19 08:38:36",
"id": 327133,
"name": "lolo",
"script": "#!/bin/bash\necho Hello World > /root/hello",
"type": "boot"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrStartupScriptFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrStartupScriptFacts, self).__init__(module, "vultr_startup_script_facts")
self.returns = {
"SCRIPTID": dict(key='id', convert_to='int'),
"date_created": dict(),
"date_modified": dict(),
"name": dict(),
"script": dict(),
"type": dict(),
}
def get_startupscripts(self):
return self.api_query(path="/v1/startupscript/list")
def parse_startupscript_list(startupscipts_list):
if not startupscipts_list:
return []
return [startupscript for id, startupscript in startupscipts_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
startupscript_facts = AnsibleVultrStartupScriptFacts(module)
result = startupscript_facts.get_result(parse_startupscript_list(startupscript_facts.get_startupscripts()))
ansible_facts = {
'vultr_startup_script_facts': result['vultr_startup_script_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,132 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_startup_script_info
short_description: Gather information about the Vultr startup scripts available.
description:
- Gather information about vultr_startup_scripts available.
author: "Yanis Guenane (@Spredzy)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr startup scripts information
local_action:
module: vultr_startup_script_info
register: result
- name: Print the gathered information
debug:
var: result.vultr_startup_script_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_startup_script_info:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_startup_script_info": [
{
"date_created": "2018-07-19 08:38:36",
"date_modified": "2018-07-19 08:38:36",
"id": 327133,
"name": "lolo",
"script": "#!/bin/bash\necho Hello World > /root/hello",
"type": "boot"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrStartupScriptInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrStartupScriptInfo, self).__init__(module, "vultr_startup_script_info")
self.returns = {
"SCRIPTID": dict(key='id', convert_to='int'),
"date_created": dict(),
"date_modified": dict(),
"name": dict(),
"script": dict(),
"type": dict(),
}
def get_startupscripts(self):
return self.api_query(path="/v1/startupscript/list")
def parse_startupscript_list(startupscipts_list):
if not startupscipts_list:
return []
return [startupscript for id, startupscript in startupscipts_list.items()]
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
startupscript_info = AnsibleVultrStartupScriptInfo(module)
result = startupscript_info.get_result(parse_startupscript_list(startupscript_info.get_startupscripts()))
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,329 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_user
short_description: Manages users on Vultr.
description:
- Create, update and remove users.
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, see U(https://www.vultr.com/api/#user_user_list).
- Required if C(state=present).
- One or more of the choices list, some depend on each other.
choices:
- manage_users
- subscriptions
- provisioning
- billing
- support
- abuse
- dns
- upgrade
aliases: [ acl ]
type: list
state:
description:
- State of the user.
default: present
choices: [ present, absent ]
type: str
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Ensure a user exists
local_action:
module: vultr_user
name: john
email: john.doe@example.com
password: s3cr3t
acls:
- upgrade
- dns
- manage_users
- subscriptions
- upgrade
- name: Remove a user
local_action:
module: vultr_user
name: john
state: absent
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_user:
description: Response from Vultr API
returned: success
type: complex
contains:
id:
description: ID of the user.
returned: success
type: str
sample: 5904bc6ed9234
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
ACLS = [
'manage_users',
'subscriptions',
'provisioning',
'billing',
'support',
'abuse',
'dns',
'upgrade',
]
class AnsibleVultrUser(Vultr):
def __init__(self, module):
super(AnsibleVultrUser, self).__init__(module, "vultr_user")
self.returns = {
'USERID': dict(key='id'),
'name': dict(),
'email': dict(),
'api_enabled': dict(convert_to='bool'),
'acls': dict(),
'api_key': dict()
}
def _common_args(self):
return {
'name': self.module.params.get('name'),
'email': self.module.params.get('email'),
'acls': self.module.params.get('acls'),
'password': self.module.params.get('password'),
'api_enabled': self.get_yes_or_no('api_enabled'),
}
def get_user(self):
users = self.api_query(path="/v1/user/list")
for user in users or []:
if user.get('name') == self.module.params.get('name'):
return user
return {}
def present_user(self):
user = self.get_user()
if not user:
user = self._create_user(user)
else:
user = self._update_user(user)
return user
def _has_changed(self, user, data):
for k, v in data.items():
if k not in user:
continue
elif isinstance(v, list):
for i in v:
if i not in user[k]:
return True
elif data[k] != user[k]:
return True
return False
def _create_user(self, user):
self.module.fail_on_missing_params(required_params=['password'])
self.result['changed'] = True
data = self._common_args()
self.result['diff']['before'] = {}
self.result['diff']['after'] = data
if not self.module.check_mode:
user = self.api_query(
path="/v1/user/create",
method="POST",
data=data
)
user.update(self.get_user())
return user
def _update_user(self, user):
data = self._common_args()
data.update({
'USERID': user['USERID'],
})
force = self.module.params.get('force')
if not force:
del data['password']
if force or self._has_changed(user=user, data=data):
self.result['changed'] = True
self.result['diff']['before'] = user
self.result['diff']['after'] = user.copy()
self.result['diff']['after'].update(data)
if not self.module.check_mode:
self.api_query(
path="/v1/user/update",
method="POST",
data=data
)
user = self.get_user()
return user
def absent_user(self):
user = self.get_user()
if user:
self.result['changed'] = True
data = {
'USERID': user['USERID'],
}
self.result['diff']['before'] = user
self.result['diff']['after'] = {}
if not self.module.check_mode:
self.api_query(
path="/v1/user/delete",
method="POST",
data=data
)
return user
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', choices=ACLS, aliases=['acl']),
state=dict(type='str', choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(
argument_spec=argument_spec,
required_if=[
('state', 'present', ['email', 'acls']),
],
supports_check_mode=True,
)
vultr_user = AnsibleVultrUser(module)
if module.params.get('state') == "absent":
user = vultr_user.absent_user()
else:
user = vultr_user.present_user()
result = vultr_user.get_result(user)
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,128 +0,0 @@
#!/usr/bin/python
#
# (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_user_facts
short_description: Gather facts about the Vultr user available.
description:
- Gather facts about users available in Vultr.
author: "Yanis Guenane (@Spredzy)"
deprecated:
removed_in: "2.12"
why: Transformed into an info module.
alternative: Use M(vultr_user_info) instead.
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Gather Vultr user facts
local_action:
module: vultr_user_facts
- name: Print the gathered facts
debug:
var: ansible_facts.vultr_user_facts
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_user_facts:
description: Response from Vultr API
returned: success
type: complex
sample:
"vultr_user_facts": [
{
"acls": [],
"api_enabled": "yes",
"email": "mytestuser@example.com",
"id": "a235b4f45e87f",
"name": "mytestuser"
}
]
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrUserFacts(Vultr):
def __init__(self, module):
super(AnsibleVultrUserFacts, self).__init__(module, "vultr_user_facts")
self.returns = {
"USERID": dict(key='id'),
"acls": dict(),
"api_enabled": dict(),
"email": dict(),
"name": dict()
}
def get_regions(self):
return self.api_query(path="/v1/user/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
user_facts = AnsibleVultrUserFacts(module)
result = user_facts.get_result(user_facts.get_regions())
ansible_facts = {
'vultr_user_facts': result['vultr_user_facts']
}
module.exit_json(ansible_facts=ansible_facts, **result)
if __name__ == '__main__':
main()

View file

@ -1,146 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright (c) 2019, 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
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: vultr_user_info
short_description: Get information about the Vultr user available.
description:
- Get infos about users available in Vultr.
author:
- "Yanis Guenane (@Spredzy)"
- "René Moser (@resmo)"
extends_documentation_fragment:
- community.general.vultr
'''
EXAMPLES = r'''
- name: Get Vultr user infos
vultr_user_info:
register: result
- name: Print the infos
debug:
var: result.vultr_user_info
'''
RETURN = r'''
---
vultr_api:
description: Response from Vultr API with a few additions/modification
returned: success
type: complex
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"
vultr_user_info:
description: Response from Vultr API as list
returned: available
type: complex
contains:
id:
description: ID of the user.
returned: success
type: str
sample: 5904bc6ed9234
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 ansible_collections.community.general.plugins.module_utils.vultr import (
Vultr,
vultr_argument_spec,
)
class AnsibleVultrUserInfo(Vultr):
def __init__(self, module):
super(AnsibleVultrUserInfo, self).__init__(module, "vultr_user_info")
self.returns = {
"USERID": dict(key='id'),
"acls": dict(),
"api_enabled": dict(),
"email": dict(),
"name": dict()
}
def get_regions(self):
return self.api_query(path="/v1/user/list")
def main():
argument_spec = vultr_argument_spec()
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
user_info = AnsibleVultrUserInfo(module)
result = user_info.get_result(user_info.get_regions())
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_account_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_account_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_block_storage.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_block_storage_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_block_storage_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_dns_domain.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_dns_domain_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_dns_domain_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_dns_record.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_firewall_group.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_firewall_group_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_firewall_group_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_firewall_rule.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_network.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_network_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_network_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_os_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_os_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_plan_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_plan_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_region_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_region_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_server.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_server_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_server_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_ssh_key.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_ssh_key_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_ssh_key_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_startup_script.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_startup_script_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_startup_script_info.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_user.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_user_facts.py

View file

@ -1 +0,0 @@
./cloud/vultr/vultr_user_info.py

View file

@ -1,2 +0,0 @@
cloud/vultr
unsupported

View file

@ -1,27 +0,0 @@
# Copyright (c) 2018, René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: test get vultr account infos in check mode
vultr_account_info:
check_mode: yes
register: result
- name: verify test get vultr account infos in check mode
assert:
that:
- result.vultr_account_info.balance is defined
- result.vultr_account_info.last_payment_amount is defined
- result.vultr_account_info.last_payment_date is defined
- result.vultr_account_info.last_payment_amount is defined
- name: test get vultr account fact
vultr_account_info:
register: result
- name: verify test get vultr account infos
assert:
that:
- result.vultr_account_info.balance is defined
- result.vultr_account_info.last_payment_amount is defined
- result.vultr_account_info.last_payment_date is defined
- result.vultr_account_info.last_payment_amount is defined

View file

@ -1,2 +0,0 @@
cloud/vultr
unsupported

View file

@ -1,5 +0,0 @@
---
vultr_resource_prefix: "vultr-test-prefix"
vultr_block_storage_name: "{{ vultr_resource_prefix }}-volume"
vultr_block_storage_size: 10
vultr_block_storage_region: New Jersey

View file

@ -1,111 +0,0 @@
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: setup
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
state: absent
register: result
- name: verify setup
assert:
that:
- result is success
- name: test fail if missing name
vultr_block_storage:
register: result
ignore_errors: yes
- name: verify test fail if missing name
assert:
that:
- result is failed
- 'result.msg == "missing required arguments: name"'
- name: test fail if missing params for state=present
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
register: result
ignore_errors: yes
- name: verify fail if missing params for state=present
assert:
that:
- result is failed
- 'result.msg == "state is present but all of the following are missing: size, region"'
- name: test create block storage volume in check mode
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
size: "{{ vultr_block_storage_size }}"
region: "{{ vultr_block_storage_region }}"
register: result
check_mode: yes
- name: verify test create server in check mode
assert:
that:
- result is changed
- name: test create block storage volume
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
size: "{{ vultr_block_storage_size }}"
region: "{{ vultr_block_storage_region }}"
register: result
- name: verify test create block storage volume
assert:
that:
- result is changed
- result.vultr_block_storage.name == "{{ vultr_block_storage_name }}"
- result.vultr_block_storage.region == "{{ vultr_block_storage_region }}"
- result.vultr_block_storage.size == 10
- name: test create block storage volume idempotence
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
size: "{{ vultr_block_storage_size }}"
region: "{{ vultr_block_storage_region }}"
register: result
- name: verify test block storage volume idempotence
assert:
that:
- result is not changed
- result.vultr_block_storage.name == "{{ vultr_block_storage_name }}"
- result.vultr_block_storage.region == "{{ vultr_block_storage_region }}"
- result.vultr_block_storage.size == 10
- name: test destroy block storage volume in check mode
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
state: absent
register: result
check_mode: yes
- name: verify test destroy block storage volume in check mode
assert:
that:
- result is changed
- result.vultr_block_storage.name == "{{ vultr_block_storage_name }}"
- name: test destroy block storage volume
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
state: absent
register: result
- name: verify test destroy an existing block storage volume
assert:
that:
- result is changed
- result.vultr_block_storage.name == "{{ vultr_block_storage_name }}"
- name: test destroy an existing block storage volume idempotence
vultr_block_storage:
name: "{{ vultr_block_storage_name }}"
state: absent
register: result
- name: verify test destroy an existing block storage volume idempotence
assert:
that:
- result is not changed

View file

@ -1,2 +0,0 @@
cloud/vultr
unsupported

View file

@ -1,5 +0,0 @@
---
vultr_resource_prefix: "vultr-test-prefix"
vultr_block_storage_name: "{{ vultr_resource_prefix }}-volume"
vultr_block_storage_size: 10
vultr_block_storage_region: New Jersey

View file

@ -1,35 +0,0 @@
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: test gather vultr block storage volume info - empty resource
vultr_block_storage_info:
- name: Create the block storage volume
vultr_block_storage:
name: '{{ vultr_block_storage_name }}'
size: '{{ vultr_block_storage_size }}'
region: '{{ vultr_block_storage_region }}'
- name: test gather vultr block storage volume info in check mode
vultr_block_storage_info:
check_mode: yes
register: result
- name: verify test gather vultr block storage volume info in check mode
assert:
that:
- result.vultr_block_storage_info|selectattr('name','equalto','{{ vultr_block_storage_name }}') | list | count == 1
- name: test gather vultr block storage volume info
vultr_block_storage_info:
register: result
- name: verify test gather vultr block storage volume info
assert:
that:
- result.vultr_block_storage_info|selectattr('name','equalto','{{ vultr_block_storage_name }}') | list | count == 1
- name: Delete the block storage volume
vultr_block_storage:
name: '{{ vultr_block_storage_name }}'
state: absent

View file

@ -1,2 +0,0 @@
cloud/vultr
unsupported

View file

@ -1,5 +0,0 @@
# Copyright (c) 2018, René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
vultr_resource_prefix: "vultr-test-prefix"
vultr_dns_domain_name: "{{ vultr_resource_prefix }}-example-ansible.com"

View file

@ -1,99 +0,0 @@
# Copyright (c) 2018, René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: setup
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
state: absent
register: result
- name: verify setup
assert:
that:
- result is success
- name: test fail if missing name
vultr_dns_domain:
register: result
ignore_errors: yes
- name: verify test fail if missing name
assert:
that:
- result is failed
- 'result.msg == "missing required arguments: name"'
- name: test fail if missing params for state=present
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
register: result
ignore_errors: yes
- name: verify fail if missing params for state=present
assert:
that:
- result is failed
- 'result.msg == "state is present but all of the following are missing: server_ip"'
- name: test create dns domain in check mode
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
server_ip: 10.10.10.10
register: result
check_mode: yes
- name: verify test create dns domain in check mode
assert:
that:
- result is changed
- name: test create dns domain
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
server_ip: 10.10.10.10
register: result
- name: verify test create dns domain
assert:
that:
- result is changed
- result.vultr_dns_domain.name == '{{ vultr_dns_domain_name }}'
- name: test create dns domain idempotence
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
server_ip: 10.10.10.10
register: result
- name: verify test create dns domain idempotence
assert:
that:
- result is not changed
- result.vultr_dns_domain.name == '{{ vultr_dns_domain_name }}'
- name: test absent dns domain in check mode
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
state: absent
register: result
check_mode: yes
- name: verify test absent dns domain in check mode
assert:
that:
- result is changed
- result.vultr_dns_domain.name == '{{ vultr_dns_domain_name }}'
- name: test absent dns domain
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
state: absent
register: result
- name: verify test absent dns domain
assert:
that:
- result is changed
- result.vultr_dns_domain.name == '{{ vultr_dns_domain_name }}'
- name: test absent dns domain idempotence
vultr_dns_domain:
name: "{{ vultr_dns_domain_name }}"
state: absent
register: result
- name: verify test absent dns domain idempotence
assert:
that:
- result is not changed

View file

@ -1,2 +0,0 @@
cloud/vultr
unsupported

View file

@ -1,4 +0,0 @@
---
vultr_resource_prefix: "vultr-test-prefix"
dns_domain_name: "{{ vultr_resource_prefix }}-example-ansible.com"
dns_domain_server_ip: 104.24.16.59

View file

@ -1,32 +0,0 @@
# Copyright (c) 2018, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: Create the record
vultr_dns_domain:
name: '{{ dns_domain_name }}'
server_ip: '{{ dns_domain_server_ip }}'
- name: test gather vultr dns domain info in check mode
vultr_dns_domain_info:
check_mode: yes
register: result
- name: verify test gather vultr dns domain info in check mode
assert:
that:
- result.vultr_dns_domain_info|selectattr('domain','equalto','{{ dns_domain_name }}') | list | count == 1
- name: test gather vultr dns domain info
vultr_dns_domain_info:
register: result
- name: verify test gather vultr dns domain info
assert:
that:
- result.vultr_dns_domain_info|selectattr('domain','equalto','{{ dns_domain_name }}') | list | count == 1
- name: Delete the record
vultr_dns_domain:
name: '{{ dns_domain_name }}'
server_ip: '{{ dns_domain_server_ip }}'
state: absent

Some files were not shown because too many files have changed in this diff Show more