summaryrefslogtreecommitdiffstats
path: root/scripts/func-transmit
blob: af0e8f21af71be7cc85a48dcec863209a33edd5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/python

##
## func yaml wrapper tool.
## allows usage of func over stdin/stdin using yaml as a marshalling format
## for access to the Overlord() API from non-Python code.
## this should typically be accessed via a pipe, though also works as
##     func-transmit < yamlfile
##
## Copyright 2008, Various
## Marco Mornati <mmornati@byte-code.com>
## Michael DeHaan <mdehaan@redhat.com>
## Adrian Likins <alikins@redhat.com>
##
## This software may be freely redistributed under the terms of the GNU
## general public license.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##


## Example yaml input file format:
"""
clients: "*"
aysnc: False
nforks: 1
module: command
method: run
parameters: "/bin/echo Hello World"
"""


import exceptions
import string
import sys
import distutils.sysconfig
import optparse

import simplejson

import func.overlord.func_command as func_command
import func.overlord.client as fc
import func.yaml as yaml
import func.CommonErrors


class NoAsyncForListMinionException(exceptions.Exception):
    def __init__(self, msg):
        self.msg = msg
    # scan arguments

class FuncTransmitError(object):
    def __init__(self, name="", message="", info={}):
        self.data = {'error':1,
		     # not all of the marshall types support bools, so 1 will have to do 
		      'name':name, 
		     'message':message,
		     'info':info}


def is_a_list(item):
    if type(item) in [type([]), type(())]:
        return True
    return False

def read_data(format, data):
    if format == "yaml":
        params = yaml.load(data).next()
    elif format == "json":
        params = simplejson.loads(data)
    return params

def write_data(format, data):
    # convert to selected language (default is JSON)
    if format == "json":
        output = simplejson.dumps(data)
    elif format == "yaml":
        output = yaml.dump(data)
    print output

def main(argv):
# load input parameters
    parser = optparse.OptionParser()
    parser.add_option("-j","--json",
                      help="Json Parser",
                      action="store_true",
                      dest="json",
                      default=False)
    parser.add_option("-y","--yaml",
                      help="Yaml Parser",
                      action="store_true",
                      dest="yaml",
                      default=False)
    
    (options,args) = parser.parse_args()

    # load input from stdin
    input = sys.stdin.read()

    # Setting default language if no one is selected by user
    if (options.json==False and options.yaml==False):
        options.json = True

    format = "json"
    if (options.yaml):
        format = "yaml"

    params  = read_data(format, input)
    

    # slightly odd, but we expect clients to be a string we parse
    # out later (glob and group expansion, etc). So if it is a list,
    # flatten it into a string. 
    clients    = params.get('clients', "*")
    if is_a_list(clients):
        clients  = string.join(clients,';')

    method     = params.get('method','unknown')
    async      = params.get('async', False)

    # scan more arguments
    nforks     = params.get('nforks', 1)
    module     = params.get('module', None)
    parameters = params.get('parameters', None)

    # make the call
    try:
	    client = fc.Overlord(clients, async=async, nforks=nforks)
    except func.CommonErrors.Func_Client_Exception, e:
	    error = FuncTransmitError("Func Client Exception", str(e))
	    write_data(format, error.data)
	    return 1

    if module is None:
        method_handle = getattr(client, method)
    else:
        module_handle = getattr(client, module)
        method_handle = getattr(module_handle, method)

    if parameters is not None:
        # listify if we get something thats not a list
        if not is_a_list(parameters):
            parameters = [parameters]
        results = method_handle(*parameters)
    else:
        results = method_handle()

    # convert to selected language (default is JSON) and output
    write_data(format, results)


    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv))