blob: 380ffe6d0bbb889f633e048c85de7f60734828b6 [file] [log] [blame]
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# salt-adapter — adapter between Salt and reclass
#
# Note that this file is not really necessary and exists mostly for debugging
# purposes and admin joys. Have a look at README.Salt for proper integration
# between Salt and reclass.
#
# Copyright © 2007–13 martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
__name__ = 'salt-reclass'
__description__ = 'reclass adapter for Salt'
__version__ = '1.0'
__author__ = 'martin f. krafft <madduck@madduck.net>'
__copyright__ = 'Copyright © 2007–13 ' + __author__
__licence__ = 'Artistic Licence 2.0'
import sys, os, posix
# 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 os, sys, posix
import reclass.config
from reclass.output import OutputLoader
from reclass.storage import StorageBackendLoader
from reclass.errors import ReclassException, InvocationError
from reclass import output
from reclass.adapters.salt import ext_pillar, top
def _error(msg, rc):
print >>sys.stderr, msg
sys.exit(rc)
try:
if len(sys.argv) == 1:
raise InvocationError('Need to specify --top or --pillar.',
posix.EX_USAGE)
# initialise options and try to read ./reclass-config.yml, which is
# expected to sit next to the salt-reclass CLI
options = {'storage_type': 'yaml_fs',
'pretty_print' : True,
'output' : 'yaml'
}
basedir = os.path.dirname(sys.argv[0])
config_path = os.path.join(basedir, '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))
nodes_uri, classes_uri = reclass.config.path_mangler(options.get('inventory_base_uri'),
options.get('nodes_uri'),
options.get('classes_uri'))
options['nodes_uri'] = nodes_uri
options['classes_uri'] = classes_uri
if sys.argv[1] in ('--top', '-t'):
if len(sys.argv) > 2:
raise InvocationError('Unknown arguments: ' + \
' '.join(sys.argv[2:]), posix.EX_USAGE)
node = False
elif sys.argv[1] in ('--pillar', '-p'):
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)
node = sys.argv[2]
else:
raise InvocationError('Unknown mode (--top or --pillar required).',
posix.EX_USAGE)
if not node:
reclass_opts = options.copy()
del reclass_opts['output']
del reclass_opts['pretty_print']
data = top(**reclass_opts)
else:
pillar={}
data = ext_pillar(node, pillar, options.get('storage_type'),
options.get('inventory_base_uri'),
options.get('nodes_uri'),
options.get('classes_uri'))
print output(data, options.get('output'), options.get('pretty_print'))
sys.exit(posix.EX_OK)
except ReclassException, e:
_error(e.message, e.rc)