Import of working code base
Signed-off-by: martin f. krafft <madduck@madduck.net>
diff --git a/adapters/ansible b/adapters/ansible
new file mode 100755
index 0000000..bb35e3f
--- /dev/null
+++ b/adapters/ansible
@@ -0,0 +1,81 @@
+#!/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 usage_error(msg):
+ print >>sys.stderr, msg
+ sys.exit(posix.EX_USAGE)
+
+if len(sys.argv) == 1:
+ usage_error('Need to specify --list or --host.')
+
+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
+
+# 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:
+ usage_error('nodes_uri not specified')
+
+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:
+ usage_error('Unknown arguments: ' + ' '.join(sys.argv[2:]))
+ options['node'] = False
+
+elif sys.argv[1] == '--host':
+ if len(sys.argv) < 3:
+ usage_error('Missing hostname.')
+ elif len(sys.argv) > 3:
+ usage_error('Unknown arguments: ' + ' '.join(sys.argv[3:]))
+ options['node'] = sys.argv[2]
+
+else:
+ usage_error('Unknown mode (--list or --host required).')
+
+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)