mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
commit
e33e3c130e
124
salt/sdb/rest.py
Normal file
124
salt/sdb/rest.py
Normal file
@ -0,0 +1,124 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Generic REST API SDB Module
|
||||
|
||||
:maintainer: SaltStack
|
||||
:maturity: New
|
||||
:platform: all
|
||||
|
||||
.. versionadded:: Beryllium
|
||||
|
||||
This module allows access to a REST interface using an ``sdb://`` URI.
|
||||
|
||||
Like all REST modules, the REST module requires a configuration profile to
|
||||
be configured in either the minion or master configuration file. This profile
|
||||
requires very little. In the example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-rest-api:
|
||||
driver: rest
|
||||
urls:
|
||||
url: https://api.github.com/
|
||||
keys:
|
||||
url: https://api.github.com/users/{{user}}/keys
|
||||
requests_lib: True
|
||||
|
||||
The ``driver`` refers to the REST module, and must be set to ``rest`` in order
|
||||
to use this driver. Each of the other items inside this block refers to a
|
||||
separate set of HTTP items, including a URL and any options associated with it.
|
||||
The options used here should match the options available in
|
||||
``salt.utils.http.query()``.
|
||||
|
||||
In order to call the ``urls`` item in the example, the following reference can
|
||||
be made inside a configuration file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
github_urls: sdb://my-rest-api/urls
|
||||
|
||||
Key/Value pairs may also be used with this driver, and merged into the URL using
|
||||
the configured renderer (``jinja``, by default). For instance, in order to use
|
||||
the ``keys`` item in the example, the following reference can be made:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
github_urls: sdb://my-rest-api/keys?user=myuser
|
||||
|
||||
This will cause the following URL to actually be called:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
https://api.github.com/users/myuser/keys
|
||||
|
||||
Key/Value pairs will NOT be passed through as GET data. If GET data needs to be
|
||||
sent to the URL, then it should be configured in the SDB configuration block.
|
||||
For instance:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
another-rest-api:
|
||||
driver: rest
|
||||
user_data:
|
||||
url: https://api.example.com/users/
|
||||
params:
|
||||
user: myuser
|
||||
'''
|
||||
|
||||
# import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
|
||||
import salt.loader
|
||||
import salt.utils.http as http
|
||||
from salt.template import compile_template
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__func_alias__ = {
|
||||
'set_': 'set'
|
||||
}
|
||||
|
||||
|
||||
def set_(key, value, service=None, profile=None): # pylint: disable=W0613
|
||||
'''
|
||||
Set a key/value pair in the REST interface
|
||||
'''
|
||||
return query(key, value, service, profile)
|
||||
|
||||
|
||||
def get(key, service=None, profile=None): # pylint: disable=W0613
|
||||
'''
|
||||
Get a value from the REST interface
|
||||
'''
|
||||
return query(key, None, service, profile)
|
||||
|
||||
|
||||
def query(key, value=None, service=None, profile=None): # pylint: disable=W0613
|
||||
'''
|
||||
Get a value from the REST interface
|
||||
'''
|
||||
comps = key.split('?')
|
||||
key = comps[0]
|
||||
key_vars = {}
|
||||
for pair in comps[1].split('&'):
|
||||
pair_key, pair_val = pair.split('=')
|
||||
key_vars[pair_key] = pair_val
|
||||
|
||||
renderer = __opts__.get('renderer', 'yaml_jinja')
|
||||
rend = salt.loader.render(__opts__, {})
|
||||
url = compile_template(
|
||||
':string:',
|
||||
rend,
|
||||
renderer,
|
||||
input_data=profile[key]['url'],
|
||||
**key_vars
|
||||
)
|
||||
|
||||
result = http.query(
|
||||
url,
|
||||
decode=True,
|
||||
**key_vars
|
||||
)
|
||||
|
||||
return result['dict']
|
@ -31,6 +31,7 @@ def compile_template(template,
|
||||
default,
|
||||
saltenv='base',
|
||||
sls='',
|
||||
input_data='',
|
||||
**kwargs):
|
||||
'''
|
||||
Take the path to a template and return the high data structure
|
||||
@ -50,29 +51,30 @@ def compile_template(template,
|
||||
_dont_call_warnings=True
|
||||
)
|
||||
|
||||
# Template was specified incorrectly
|
||||
if not isinstance(template, string_types):
|
||||
log.error('Template was specified incorrectly: {0}'.format(template))
|
||||
return ret
|
||||
# Template does not exist
|
||||
if not os.path.isfile(template):
|
||||
log.error('Template does not exist: {0}'.format(template))
|
||||
return ret
|
||||
# Template is an empty file
|
||||
if salt.utils.is_empty(template):
|
||||
log.warn('Template is an empty file: {0}'.format(template))
|
||||
return ret
|
||||
if template != ':string:':
|
||||
# Template was specified incorrectly
|
||||
if not isinstance(template, string_types):
|
||||
log.error('Template was specified incorrectly: {0}'.format(template))
|
||||
return ret
|
||||
# Template does not exist
|
||||
if not os.path.isfile(template):
|
||||
log.error('Template does not exist: {0}'.format(template))
|
||||
return ret
|
||||
# Template is an empty file
|
||||
if salt.utils.is_empty(template):
|
||||
log.warn('Template is an empty file: {0}'.format(template))
|
||||
return ret
|
||||
|
||||
with codecs.open(template, encoding=SLS_ENCODING) as ifile:
|
||||
# data input to the first render function in the pipe
|
||||
input_data = ifile.read()
|
||||
if not input_data.strip():
|
||||
# Template is nothing but whitespace
|
||||
log.error('Template is nothing but whitespace: {0}'.format(template))
|
||||
return ret
|
||||
|
||||
# Get the list of render funcs in the render pipe line.
|
||||
render_pipe = template_shebang(template, renderers, default)
|
||||
|
||||
with codecs.open(template, encoding=SLS_ENCODING) as ifile:
|
||||
# data input to the first render function in the pipe
|
||||
input_data = ifile.read()
|
||||
if not input_data.strip():
|
||||
# Template is nothing but whitespace
|
||||
log.error('Template is nothing but whitespace: {0}'.format(template))
|
||||
return ret
|
||||
render_pipe = template_shebang(template, renderers, default, input_data)
|
||||
|
||||
input_data = string_io(input_data)
|
||||
for render, argline in render_pipe:
|
||||
@ -117,7 +119,7 @@ def compile_template_str(template, renderers, default):
|
||||
return compile_template(fn_, renderers, default)
|
||||
|
||||
|
||||
def template_shebang(template, renderers, default):
|
||||
def template_shebang(template, renderers, default, input_data):
|
||||
'''
|
||||
Check the template shebang line and return the list of renderers specified
|
||||
in the pipe.
|
||||
@ -137,15 +139,19 @@ def template_shebang(template, renderers, default):
|
||||
'''
|
||||
render_pipe = []
|
||||
|
||||
line = ''
|
||||
# Open up the first line of the sls template
|
||||
with salt.utils.fopen(template, 'r') as ifile:
|
||||
line = ifile.readline()
|
||||
if template == ':string:':
|
||||
line = input_data.split()[0]
|
||||
else:
|
||||
with salt.utils.fopen(template, 'r') as ifile:
|
||||
line = ifile.readline()
|
||||
|
||||
# Check if it starts with a shebang and not a path
|
||||
if line.startswith('#!') and not line.startswith('#!/'):
|
||||
# Check if it starts with a shebang and not a path
|
||||
if line.startswith('#!') and not line.startswith('#!/'):
|
||||
|
||||
# pull out the shebang data
|
||||
render_pipe = check_render_pipe_str(line.strip()[2:], renderers)
|
||||
# pull out the shebang data
|
||||
render_pipe = check_render_pipe_str(line.strip()[2:], renderers)
|
||||
|
||||
if not render_pipe:
|
||||
render_pipe = check_render_pipe_str(default, renderers)
|
||||
|
Loading…
Reference in New Issue
Block a user