diff --git a/README.md b/README.md index 3a53a8e..0a8761c 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,21 @@ users: As you can see the 'users' hash was merged this time while now the 'repos' array/list only contains the entry from the node file. +## Embedded http server +You can start varstack without any variables set but the additional `--server` parameter. In this mode Varstack will be listening on _http://localhost:5050/_. +This interface can be queried with optional http GET parameters to get a stacked yaml as a http response. +Please note that this feature is intended to be run locally on a dev box only and should nerver be exposed to any actual network! + +### Example: +Run Varstack +``` +varstack --server --config ~/pillar/varstack.yaml +``` +and query it: +``` +curl 'http://localhost:5050/?fqdn=supersecure.example.com' +``` + ## GPG encryption for stacked data You can also work with encrypted data. If a value is PGP encrypted, varstack can decrypt this value (given the private key is available) and the result is itself interpreted as YAML. This means that the encrypted data can be nested but also keep in mind that for any other structe than single-line strings / integers, a proper yaml must be constructed before encryption! diff --git a/bin/varstack b/bin/varstack index 1bd0fd7..f56d552 100755 --- a/bin/varstack +++ b/bin/varstack @@ -1,6 +1,7 @@ #!/usr/bin/python2 import varstack, yaml, argparse, logging +from varstack.server import * from pprint import pprint def validateVar(var): @@ -14,6 +15,7 @@ if __name__ == '__main__': parser.add_argument('--debug', dest='debug', action='store_true') parser.add_argument('--config', type=str, default='/etc/varstack.yaml', help='configuration filename') + parser.add_argument('-s','--server', dest='server', action='store_true') parser.add_argument('variables', nargs=argparse.REMAINDER, type=validateVar, metavar='key=value', help='any number of variable assignments in the form of "key=value"') @@ -25,11 +27,19 @@ if __name__ == '__main__': loglevel = logging.WARNING log = logging.basicConfig(level=loglevel) - vardata = {} - for entry in args.variables: - vardata[entry['key']] = entry['value'] + if args.server: + try: + setup_server(varstack.Varstack(config_filename=args.config)) + while True: + pass + finally: + teardown_server() + else: + vardata = {} + for entry in args.variables: + vardata[entry['key']] = entry['value'] - vs = varstack.Varstack(config_filename=args.config) - res = vs.evaluate(vardata) - print '---' - print yaml.dump(res) + vs = varstack.Varstack(config_filename=args.config) + res = vs.evaluate(vardata) + print '---' + print yaml.dump(res) diff --git a/devel_requirements.txt b/devel_requirements.txt index c54f8b8..c212ad5 100644 --- a/devel_requirements.txt +++ b/devel_requirements.txt @@ -1,4 +1,5 @@ nose==1.3.7 testfixtures==4.1.2 coverage==3.7.1 -python-gnupg==0.3.7 \ No newline at end of file +python-gnupg==0.3.7 +CherryPy==6.0.1 diff --git a/setup.py b/setup.py index b674cb2..e6180d4 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ version = '0.4' -install_requires = ['setuptools', 'PyYAML'] +install_requires = ['setuptools', 'PyYAML', 'cherrypy'] if sys.version_info < (2, 7): install_requires.append('simplejson') install_requires.append('argparse') diff --git a/varstack/server.py b/varstack/server.py new file mode 100644 index 0000000..4c1eac8 --- /dev/null +++ b/varstack/server.py @@ -0,0 +1,25 @@ +import cherrypy +import yaml + +class VarstackServer(object): + + def __init__(self, varstack_obj): + self.varstack_obj = varstack_obj + + @cherrypy.expose + @cherrypy.tools.response_headers(headers=[('Content-Type', 'application/yaml')]) + def index(self, **variables): + res = self.varstack_obj.evaluate(variables) + return yaml.dump(res) + + + +def setup_server(varstack_obj, interface='localhost', port=5050): + cherrypy.config.update({'server.socket_host': interface, + 'server.socket_port': port}) + cherrypy.tree.mount(VarstackServer(varstack_obj), "/", {}) + cherrypy.engine.start() + + +def teardown_server(): + cherrypy.engine.stop()