Refactor the Ansible adapter
Signed-off-by: martin f. krafft <madduck@madduck.net>
diff --git a/adapters/ansible.in b/adapters/ansible.in
index d225c9e..9ac7ea1 100644
--- a/adapters/ansible.in
+++ b/adapters/ansible.in
@@ -6,5 +6,20 @@
# Copyright © 2007–13 martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
+import os, sys, posix
+
+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)
from reclass.adapters.ansible import ansible_adapter
-ansible_adapter()
+
+def exc_handler(message, rc):
+ print >>sys.stderr, message
+ sys.exit(rc)
+
+ansible_adapter(ansible_dir, exc_handler)
+sys.exit(posix.EX_OK)
diff --git a/reclass/adapters/ansible.py b/reclass/adapters/ansible.py
index 3bb6d4e..0fd1c85 100644
--- a/reclass/adapters/ansible.py
+++ b/reclass/adapters/ansible.py
@@ -8,76 +8,68 @@
#
import os, sys, posix, stat
-def exit_error(msg, rc):
- print >>sys.stderr, msg
- sys.exit(rc)
+import reclass.config
+from reclass.errors import InvocationError, ReclassException
+from reclass import get_data, output
-def ansible_adapter():
- 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
- import reclass.errors
- from reclass import get_data, output
-
- # 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(reclass.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
-
- if 'applications_postfix' not in options:
- options['applications_postfix'] = '_hosts'
-
- # 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)
-
+def ansible_adapter(ansible_dir, exc_handler):
try:
+ if len(sys.argv) == 1:
+ raise InvocationError('Need to specify --list or --host.',
+ posix.EX_USAGE)
+
+ # 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(reclass.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:
+ raise InvocationError('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
+
+ if 'applications_postfix' not in options:
+ options['applications_postfix'] = '_hosts'
+
+ # 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:
+ raise InvocationError('Unknown arguments: ' + \
+ ' '.join(sys.argv[2:]), posix.EX_USAGE)
+ options['node'] = False
+
+ elif sys.argv[1] == '--host':
+ if len(sys.argv) < 3:
+ raise InvocationError('Missing hostname.', posix.EX_USAGE)
+ elif len(sys.argv) > 3:
+ raise InvocationError('Unknown arguments: ' + \
+ ' '.join(sys.argv[3:]), posix.EX_USAGE)
+ options['node'] = sys.argv[2]
+
+ else:
+ raise InvocationError('Unknown mode (--list or --host required).',
+ posix.EX_USAGE)
+
data = get_data(options['storage_type'], options['nodes_uri'],
- options['classes_uri'], options['applications_postfix'],
- options['node'])
+ options['classes_uri'],
+ options['applications_postfix'], options['node'])
if options['node']:
# Massage and shift the data like Ansible wants it
@@ -88,7 +80,5 @@
print output(data, options['output'], options['pretty_print'])
- sys.exit(posix.EX_OK)
-
- except reclass.errors.ReclassException, e:
- exit_error(e.message, e.rc)
+ except ReclassException, e:
+ exc_handler(e.message, e.rc)