blob: 2e485ecdbc4c2e7ec88a5ef7db103ecd306e2094 [file] [log] [blame]
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ansible-adapter — adapter between Ansible and reclass
#
# Copyright © 2007–13 martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
import os, sys, posix, stat
def exit_error(msg, rc):
print >>sys.stderr, msg
sys.exit(rc)
if len(sys.argv) == 1:
exit_error('Need to specify --list or --host.', posix.EX_USAGE)
ansible_dir = os.path.dirname(sys.argv[0])
# In order to be able to use reclass as modules, manipulate the search path,
# starting from the location of the adapter. Realpath will make sure that
# symlinks are resolved.
realpath = os.path.realpath(sys.argv[0] + '/../../')
sys.path.insert(0, realpath)
import reclass, config, errors
# The adapter resides in the Ansible directory, so let's look there for an
# optional configuration file called reclass-config.yml.
options = {'output':'json', 'pretty_print':True}
config_path = os.path.join(ansible_dir, 'reclass-config.yml')
if os.path.exists(config_path) and os.access(config_path, os.R_OK):
options.update(config.read_config_file(config_path))
# Massage options into shape
if 'storage_type' not in options:
options['storage_type'] = 'yaml_fs'
if 'nodes_uri' not in options:
nodes_uri = os.path.join(ansible_dir, 'nodes')
if stat.S_ISDIR(os.stat(nodes_uri).st_mode):
options['nodes_uri'] = nodes_uri
else:
exit_error('nodes_uri not specified', posix.EX_USAGE)
if 'classes_uri' not in options:
classes_uri = os.path.join(ansible_dir, 'classes')
if not stat.S_ISDIR(os.stat(classes_uri).st_mode):
classes_uri = options['nodes_uri']
options['classes_uri'] = classes_uri
# Invoke reclass according to what Ansible wants.
# If the 'node' option is set, we want node information. If the option is
# False instead, we print the inventory. Yeah for option abuse!
if sys.argv[1] == '--list':
if len(sys.argv) > 2:
exit_error('Unknown arguments: ' + ' '.join(sys.argv[2:]),
posix.EX_USAGE)
options['node'] = False
elif sys.argv[1] == '--host':
if len(sys.argv) < 3:
exit_error('Missing hostname.', posix.EX_USAGE)
elif len(sys.argv) > 3:
exit_error('Unknown arguments: ' + ' '.join(sys.argv[3:]),
posix.EX_USAGE)
options['node'] = sys.argv[2]
else:
exit_error('Unknown mode (--list or --host required).', posix.EX_USAGE)
try:
data = reclass.get_data(options['storage_type'], options['nodes_uri'],
options['classes_uri'], options['node'])
if options['node']:
# Massage and shift the data like Ansible wants it
data['parameters']['RECLASS'] = data['RECLASS']
for i in ('classes', 'applications'):
data['parameters']['RECLASS'][i] = data[i]
data = data['parameters']
print reclass.output(data, options['output'], options['pretty_print'])
sys.exit(posix.EX_OK)
except errors.ReclassException, e:
exit_error(e.message, e.rc)