blob: 609d13c488a7b9d549798f623e933a17bfd192b0 [file] [log] [blame]
Dmitry Teselkin9b3097a2018-11-21 15:45:07 +03001from inspect import getmembers, isclass, isfunction
2from functools import wraps
3
4import importlib
5import pkgutil
6import sys
7
8
9class Loader(object):
10 def __init__(self, name):
11 self.name = name
12 self.loader = pkgutil.get_loader(self.name)
13 self.path = self.loader.filename
14 sys.path.append(self.path)
15
16 def get(self, name, *args, **kwargs):
17 parts = name.split('.')
18 module_name = '.'.join(parts[:-1])
19 module = importlib.import_module(module_name)
20 module.__salt__ = __salt__
21 return getattr(module, parts[-1])
22
23 def info(self, name, *args, **kwargs):
24 return {name: getattr(self.get(name), '__doc__')}
25
26 def call(self, name, *args, **kwargs):
27 return self.get(name)(*args, **kwargs)
28
29 def list(self, *args, **kwargs):
30 classes = set()
31 functions = set()
32 for _,name,ispkg in pkgutil.walk_packages([self.path,]):
33 if ispkg:
34 continue
35 try:
36 module = importlib.import_module(name)
37 for member_name,_ in getmembers(module, isfunction):
38 functions.add('.'.join((name, member_name)))
39 for member_name,_ in getmembers(module, isclass):
40 classes.add('.'.join((name, member_name)))
41 except:
42 pass
43 return {'functions': sorted(functions), 'classes': sorted(classes)}
44
45
46LOADER = Loader('sharedlib')
47
48
49def loader_attr(name):
50 def wrapper(f):
51 @wraps(f)
52 def func_wrapper(*args, **kwargs):
53 return getattr(LOADER, name)(*args, **kwargs)
54 return func_wrapper
55 return wrapper
56
57
58def wrap_output(f):
59 @wraps(f)
60 def wrapper(*args, **kwargs):
61 return {kwargs.get('__pub_fun'): f(*args, **kwargs)}
62 return wrapper
63
64
65@wrap_output
66@loader_attr('list')
67def list(*args, **kwargs):
68 '''
69 List available functions.
70
71 .. code-block:: text
72
73 salt-call sharedlib.list
74 '''
75
76@wrap_output
77@loader_attr('info')
78def info(name, *args, **kwargs):
79 '''
80 Returns info about function.
81
82 .. code-block:: text
83
84 salt-call sharedlib.info function.name
85 '''
86
87@loader_attr('get')
88def get(name):
89 '''
90 Returns function / class object (but not calls it) for later use.
91 This is mostly useful in jinja templates.
92
93 .. code-block:: jinja
94
95 {%- set func = salt['sharedlib.get']('function.name') %}
96 {%- func(*args, **kwargs) %}
97 '''
98
99@loader_attr('call')
100def call(name, *args, **kwargs):
101 '''
102 Calls a function from library.
103
104 For more information about a function being called use 'sharedlib.info'.
105
106 .. code-block:: jinja
107
108 {%- set x = salt['sharedlib.call']('function.name', *args, **kwargs) %}
109 '''
110