From 5d81de3cf975de09a1dc21d4ef7b68a20e7cba46 Mon Sep 17 00:00:00 2001 From: Paul-Henri Froidmont Date: Mon, 30 Jul 2018 19:42:48 +0200 Subject: [PATCH] Custom Scaleway dynamic inventory --- inventories/staging/scaleway.ini | 4 -- inventories/staging/scaleway.yml | 10 --- inventories/staging/scw.ini | 4 ++ inventories/staging/scw.sh | 4 ++ roles/scaleway-provision/tasks/main.yml | 10 +-- scripts/scw_inventory.py | 93 +++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 19 deletions(-) delete mode 100644 inventories/staging/scaleway.ini delete mode 100644 inventories/staging/scaleway.yml create mode 100644 inventories/staging/scw.ini create mode 100755 inventories/staging/scw.sh create mode 100755 scripts/scw_inventory.py diff --git a/inventories/staging/scaleway.ini b/inventories/staging/scaleway.ini deleted file mode 100644 index 214e8cb..0000000 --- a/inventories/staging/scaleway.ini +++ /dev/null @@ -1,4 +0,0 @@ -cache_max_age = 0 -SCW_TOKEN = {{ scw_token }} - - diff --git a/inventories/staging/scaleway.yml b/inventories/staging/scaleway.yml deleted file mode 100644 index dbe7bdd..0000000 --- a/inventories/staging/scaleway.yml +++ /dev/null @@ -1,10 +0,0 @@ -plugin: scaleway -oauth_token: "{{ scw_token }}" -regions: - - ams1 - - par1 -tags: - - staging -hostnames: - - hostname - - public_ipv4 diff --git a/inventories/staging/scw.ini b/inventories/staging/scw.ini new file mode 100644 index 0000000..baa27a8 --- /dev/null +++ b/inventories/staging/scw.ini @@ -0,0 +1,4 @@ +[credentials] +token_file = ~/.ssh/scw-token +[config] +environment = staging diff --git a/inventories/staging/scw.sh b/inventories/staging/scw.sh new file mode 100755 index 0000000..ba32772 --- /dev/null +++ b/inventories/staging/scw.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd "$(dirname $0)" + +exec ../../scripts/scw_inventory.py diff --git a/roles/scaleway-provision/tasks/main.yml b/roles/scaleway-provision/tasks/main.yml index b8c8192..b13126a 100644 --- a/roles/scaleway-provision/tasks/main.yml +++ b/roles/scaleway-provision/tasks/main.yml @@ -17,9 +17,9 @@ commercial_type: VC1S wait: true tags: - - k8s_master - - k8s_etcd - - "{{ k8s_scw_environment }}" + - group:k8s_master + - group:k8s_etcd + - env:{{ k8s_scw_environment }} loop: "{{ range(1,k8s_scw_master_nodes_count+1)|list }}" - name: Provision worker nodes @@ -33,8 +33,8 @@ commercial_type: VC1S wait: true tags: - - k8s_worker - - "{{ k8s_scw_environment }}" + - group:k8s_worker + - env:{{ k8s_scw_environment }} loop: "{{ range(1,k8s_scw_worker_nodes_count+1)|list }}" - meta: refresh_inventory diff --git a/scripts/scw_inventory.py b/scripts/scw_inventory.py new file mode 100755 index 0000000..ebbe0a5 --- /dev/null +++ b/scripts/scw_inventory.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +''' +Generate an inventory of servers from scaleway which is +suitable for use as an ansible dynamic inventory +Right now, only the group 'cci-customer' is exported +''' + +import argparse +import os +import json +import configparser + +from scaleway.apis import ComputeAPI + +class SCWInventory(object): + ''' + The inventory class which calls out to scaleway and digests + the returned data, making it usable by ansible as an inventory + ''' + def __init__(self): + self.inventory = None + self.auth_token = None + self.environment = None + self.response = { + '_meta': { + 'hostvars': { + } + } + } + + def parse_config(self, creds_file='scw.ini'): + ''' + Parse the ini file to get the auth token + ''' + config = configparser.ConfigParser() + config.read(creds_file) + with open(os.path.expanduser(config['credentials']['token_file']), 'r') as content_file: + self.auth_token = content_file.read().replace('\n', '') + self.environment = config['config']['environment'] + + def get_servers(self): + ''' + query scaleway api and pull down a list of servers + ''' + self.parse_config() + api_par1 = ComputeAPI(auth_token=self.auth_token, region='par1') + api_ams1 = ComputeAPI(auth_token=self.auth_token, region='ams1') + result_par1 = api_par1.query().servers.get() + result_ams1 = api_ams1.query().servers.get() + self.inventory = [ + [i['name'], i['public_ip'], i['tags'], i['private_ip']] for i in result_par1['servers'] + result_ams1['servers'] + ] + for host, ip_info, tags, private_ip in self.inventory: + if 'env:'+self.environment in tags: + if ip_info: + self.response['_meta']['hostvars'][host] = { + 'ansible_host': private_ip, + 'public_ip': ip_info['address'] + } + if tags: + for tag in tags: + if tag.startswith('group:'): + self._add_to_response( + tag.split(':')[1], + host + ) + + def _add_to_response(self, group, hostname): + ''' + add a host to a group within the response + ''' + if group not in self.response: + self.response[group] = list() + if group in self.response: + self.response[group].append(hostname) + + def print_inventory(self): + ''' + simply display the collected inventory + ''' + print(json.dumps(self.response)) + +def main(): + ''' + run the program starting here + ''' + inventory = SCWInventory() + inventory.get_servers() + inventory.print_inventory() + +if __name__ == '__main__': + main()