1#!/usr/bin/env python 2 3# (c) 2015, Marc Abramowitz <marca@surveymonkey.com> 4# 5# This file is part of Ansible. 6# 7# Ansible is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# Ansible is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 19 20# Dynamic inventory script which lets you use nodes discovered by Canonical's 21# Landscape (http://www.ubuntu.com/management/landscape-features). 22# 23# Requires the `landscape_api` Python module 24# See: 25# - https://landscape.canonical.com/static/doc/api/api-client-package.html 26# - https://landscape.canonical.com/static/doc/api/python-api.html 27# 28# Environment variables 29# --------------------- 30# - `LANDSCAPE_API_URI` 31# - `LANDSCAPE_API_KEY` 32# - `LANDSCAPE_API_SECRET` 33# - `LANDSCAPE_API_SSL_CA_FILE` (optional) 34 35 36import argparse 37import collections 38import os 39import sys 40 41from landscape_api.base import API, HTTPError 42 43import json 44 45_key = 'landscape' 46 47 48class EnvironmentConfig(object): 49 uri = os.getenv('LANDSCAPE_API_URI') 50 access_key = os.getenv('LANDSCAPE_API_KEY') 51 secret_key = os.getenv('LANDSCAPE_API_SECRET') 52 ssl_ca_file = os.getenv('LANDSCAPE_API_SSL_CA_FILE') 53 54 55def _landscape_client(): 56 env = EnvironmentConfig() 57 return API( 58 uri=env.uri, 59 access_key=env.access_key, 60 secret_key=env.secret_key, 61 ssl_ca_file=env.ssl_ca_file) 62 63 64def get_landscape_members_data(): 65 return _landscape_client().get_computers() 66 67 68def get_nodes(data): 69 return [node['hostname'] for node in data] 70 71 72def get_groups(data): 73 groups = collections.defaultdict(list) 74 75 for node in data: 76 for value in node['tags']: 77 groups[value].append(node['hostname']) 78 79 return groups 80 81 82def get_meta(data): 83 meta = {'hostvars': {}} 84 for node in data: 85 meta['hostvars'][node['hostname']] = {'tags': node['tags']} 86 return meta 87 88 89def print_list(): 90 data = get_landscape_members_data() 91 nodes = get_nodes(data) 92 groups = get_groups(data) 93 meta = get_meta(data) 94 inventory_data = {_key: nodes, '_meta': meta} 95 inventory_data.update(groups) 96 print(json.dumps(inventory_data)) 97 98 99def print_host(host): 100 data = get_landscape_members_data() 101 meta = get_meta(data) 102 print(json.dumps(meta['hostvars'][host])) 103 104 105def get_args(args_list): 106 parser = argparse.ArgumentParser( 107 description='ansible inventory script reading from landscape cluster') 108 mutex_group = parser.add_mutually_exclusive_group(required=True) 109 help_list = 'list all hosts from landscape cluster' 110 mutex_group.add_argument('--list', action='store_true', help=help_list) 111 help_host = 'display variables for a host' 112 mutex_group.add_argument('--host', help=help_host) 113 return parser.parse_args(args_list) 114 115 116def main(args_list): 117 args = get_args(args_list) 118 if args.list: 119 print_list() 120 if args.host: 121 print_host(args.host) 122 123 124if __name__ == '__main__': 125 main(sys.argv[1:]) 126