summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRémy Léone <remy.leone@gmail.com>2018-04-25 19:35:54 +0200
committerBrian Coca <bcoca@users.noreply.github.com>2018-04-25 13:35:54 -0400
commite45a5e1c868eb544c69fdea383f7022c92b08390 (patch)
tree42b892397197f107fc90b9d6b3ca79b70c38a95f /lib
parent0f3480d35907f21737b3459abce90f60fa9542e6 (diff)
downloadansible-e45a5e1c868eb544c69fdea383f7022c92b08390.tar.gz
Add a Scaleway dynamic inventory plugin (#38739)
Diffstat (limited to 'lib')
-rw-r--r--lib/ansible/module_utils/scaleway.py9
-rw-r--r--lib/ansible/modules/cloud/scaleway/scaleway_compute.py9
-rw-r--r--lib/ansible/plugins/inventory/scaleway.py151
3 files changed, 161 insertions, 8 deletions
diff --git a/lib/ansible/module_utils/scaleway.py b/lib/ansible/module_utils/scaleway.py
index d15c9efc56..762ceed806 100644
--- a/lib/ansible/module_utils/scaleway.py
+++ b/lib/ansible/module_utils/scaleway.py
@@ -76,3 +76,12 @@ class ScalewayAPI(object):
def update(self, path, data=None, headers=None):
return self.send("UPDATE", path, data, headers)
+
+
+SCALEWAY_LOCATION = {
+ 'par1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
+ 'EMEA-FR-PAR1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
+
+ 'ams1': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'},
+ 'EMEA-NL-EVS': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'}
+}
diff --git a/lib/ansible/modules/cloud/scaleway/scaleway_compute.py b/lib/ansible/modules/cloud/scaleway/scaleway_compute.py
index a909084920..09ac2fb263 100644
--- a/lib/ansible/modules/cloud/scaleway/scaleway_compute.py
+++ b/lib/ansible/modules/cloud/scaleway/scaleway_compute.py
@@ -160,7 +160,7 @@ import time
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.six.moves.urllib.parse import quote as urlquote
-from ansible.module_utils.scaleway import ScalewayAPI
+from ansible.module_utils.scaleway import ScalewayAPI, SCALEWAY_LOCATION
SCALEWAY_COMMERCIAL_TYPES = [
@@ -189,13 +189,6 @@ SCALEWAY_COMMERCIAL_TYPES = [
'X64-120GB',
]
-SCALEWAY_LOCATION = {
- 'par1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
- 'EMEA-FR-PAR1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
- 'ams1': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'},
- 'EMEA-NL-EVS': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'},
-}
-
SCALEWAY_SERVER_STATES = (
'stopped',
'stopping',
diff --git a/lib/ansible/plugins/inventory/scaleway.py b/lib/ansible/plugins/inventory/scaleway.py
new file mode 100644
index 0000000000..82f6ca0ed4
--- /dev/null
+++ b/lib/ansible/plugins/inventory/scaleway.py
@@ -0,0 +1,151 @@
+# Copyright (c) 2017 Ansible Project
+# 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 = '''
+ name: scaleway
+ plugin_type: inventory
+ authors:
+ - Remy Leone <rleone@online.net>
+ short_description: Scaleway inventory source
+ description:
+ - Get inventory hosts from Scaleway
+ options:
+ regions:
+ description: Filter results on a specific Scaleway region
+ type: list
+ default:
+ - ams1
+ - par1
+ tags:
+ description: Filter results on a specific tag
+ type: list
+ oauth_token:
+ description: Scaleway OAuth token.
+ env:
+ # in order of precedence
+ - name: SCW_TOKEN
+ - name: SCW_API_KEY
+ - name: SCW_OAUTH_TOKEN
+'''
+
+EXAMPLES = '''
+# scaleway_inventory.yml file in YAML format
+# Example command line: ansible-inventory --list -i scaleway_inventory.yml
+
+plugin: scaleway
+regions:
+ - ams1
+ - par1
+tags:
+ - foobar
+'''
+
+import json
+import os
+
+from ansible.errors import AnsibleError
+from ansible.plugins.inventory import BaseInventoryPlugin
+from ansible.module_utils.scaleway import SCALEWAY_LOCATION
+from ansible.module_utils.urls import open_url
+
+
+def _fetch_information(token, url):
+ try:
+ response = open_url(url,
+ headers={'X-Auth-Token': token,
+ 'Content-type': 'application/json'})
+ except Exception:
+ raise AnsibleError("Error while fetching %s" % url)
+
+ try:
+ raw_json = json.loads(response.read())
+ except ValueError:
+ raise AnsibleError("Incorrect JSON payload")
+
+ try:
+ return raw_json["servers"]
+ except KeyError:
+ raise AnsibleError("Incorrect format from the Scaleway API response")
+
+
+def _build_server_url(api_endpoint):
+ return "/".join([api_endpoint, "servers"])
+
+
+class InventoryModule(BaseInventoryPlugin):
+ NAME = 'scaleway'
+
+ def __init__(self):
+ super(InventoryModule, self).__init__()
+
+ self.token = self.get_option("oauth_token")
+ self.config_data = None
+
+ def verify_file(self, path):
+ return "scaleway" in path
+
+ def _fill_host_variables(self, server_id, server_info):
+ targeted_attributes = (
+ "arch",
+ "commercial_type",
+ "organization",
+ "state",
+ "hostname",
+ "state"
+ )
+ for attribute in targeted_attributes:
+ self.inventory.set_variable(server_id, attribute, server_info[attribute])
+
+ self.inventory.set_variable(server_id, "tags", server_info["tags"])
+ self.inventory.set_variable(server_id, "ipv4", server_info["public_ip"]["address"])
+
+ def _get_zones(self):
+ config_zones = self.get_option("regions")
+ return set(SCALEWAY_LOCATION.keys()).intersection(config_zones)
+
+ def _get_tags(self):
+ return self.get_option("tags")
+
+ def match_groups(self, server_info):
+ server_zone = server_info["location"]["zone_id"]
+ server_tags = server_info["tags"]
+
+ # If no filtering is defined, all tags are valid groups
+ if self._get_tags() is None:
+ return set(server_tags).union((server_zone,))
+
+ matching_tags = set(server_tags).intersection(self._get_tags())
+
+ if not matching_tags:
+ return set()
+ else:
+ return matching_tags.union((server_zone,))
+
+ def do_zone_inventory(self, zone):
+ self.inventory.add_group(zone)
+ zone_info = SCALEWAY_LOCATION[zone]
+
+ url = _build_server_url(zone_info["api_endpoint"])
+ all_servers = _fetch_information(url=url, token=self.token)
+
+ for server_info in all_servers:
+
+ groups = self.match_groups(server_info)
+ print(groups)
+ server_id = server_info["id"]
+
+ for group in groups:
+ self.inventory.add_group(group=group)
+ self.inventory.add_host(group=group, host=server_id)
+ self._fill_host_variables(server_id=server_id, server_info=server_info)
+
+ def parse(self, inventory, loader, path, cache=True):
+ super(InventoryModule, self).parse(inventory, loader, path)
+ self.config_data = self._read_config_data(path=path)
+
+ for zone in self._get_zones():
+ self.do_zone_inventory(zone=zone)