610f9ab5adc6d5702c36f353398bcfda6b93593f
[sfa.git] / cmdline / genicli.py
1 # command line interface
2
3 import getopt
4 import sys
5 import os
6 from cert import *
7 from geniclient import *
8
9 long_opts = ["keyfile=", "help", "outfile=", "credfile=", "username=", "email="]
10
11 # default command line options
12 username = "client"
13 opname = None
14 type = None
15 hrn = None
16
17 key_file = None
18 cred_file = None
19 cert_file = None
20 out_file = None
21
22 email = None
23 uuid = None
24 gid_pkey_fn = None
25 gid_fn = None
26
27 leaf_name = None
28 server_url = "https://localhost:12345/"
29
30 def get_leaf(hrn):
31     parts = hrn.split(".")\r
32     return parts[-1]
33
34 def showhelp():
35    print "syntax: cli <options> command <args>"
36    print "options:"
37    print "    --username       ... username (or hrn) of user making call"
38    print "    --outfile        ... save response to a file"
39    print "    --credfile       ... credential of user making call (or 'None')"
40    print "    --keyfile        ... private key file of user making call"
41    print "    --email          ... email address"
42    print "commands:"
43    print "    resolve <hrn>"
44    print "    dumpCredential"
45    print "    getCredential <type> <hrn>"
46    print "    start <hrn>"
47    print "    createKey <filename>"
48    print "    createGid <hrn> <uuid|None> <pubkey_fn>"
49    print "    register <type> <hrn> <gid_filename>"
50    print "    remove <type> <hrn>"
51
52 def process_options():
53    global username
54    global opname
55    global type, hrn
56    global cert_file, cred_file
57    global key_file, out_file
58    global uuid, pkey_fn, gid_fn, email, gid_pkey_fn
59
60    (options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
61    for opt in options:
62        name = opt[0]
63        val = opt[1]
64
65        if name == "--help":
66            showhelp()
67            sys.exit(0)
68        elif name == "--username":
69            username = val
70        elif name == "--outfile":
71            out_file = val
72        elif name == "--credfile":
73            cred_file = val
74        elif name == "--certfile":
75            cred_file = val
76        elif name == "--keyfile":
77            key_file = val
78        elif name == "--email":
79            email = val
80
81    if not args:
82        print "no operation specified"
83        sys.exit(-1)
84
85    opname = args[0]
86
87    if opname == "resolve":
88        if len(args) < 2:
89            print "syntax: resolve <hrn>"
90            sys.exit(-1)
91        hrn = args[1]
92
93    elif opname == "getCredential":
94        if len(args) < 3:
95            print "syntax: getcredential <type> <hrn>"
96            sys.exit(-1)
97        type = args[1]
98        hrn = args[2]
99
100    elif opname == "createGid":
101        if len(args) < 4:
102            print "syntax: createGid <hrn> <uuid|None> <pubkey_fn>"
103        hrn = args[1]
104        if args[2]=="None":
105            uuid=None
106        else:
107            uuid = int(args[2])
108        gid_pkey_fn = args[3]
109
110    elif opname == "register":
111        if len(args) < 4:
112            print "syntax: register <type> <hrn> <gid_filename>"
113        type = args[1]
114        hrn = args[2]
115        gid_fn = args[3]
116
117    elif opname == "remove":
118        if len(args) < 3:
119            print "syntax: remove <type> <hrn>"
120        type = args[1]
121        hrn = args[2]
122
123    leaf_name = get_leaf(username)
124
125    if cert_file == None:
126        cert_file = leaf_name + ".cert"
127
128    if key_file == None:
129        key_file = leaf_name + ".pkey"
130
131    if cred_file == None:
132        cred_file = leaf_name + ".cred"
133
134 def show_options():
135    print " username:", username
136    print "cert_file:", cert_file
137    print " key_file:", key_file
138    print "cred_file:", cred_file
139    print "operation:", opname
140    print "     type:", type
141    print "      hrn:", hrn
142    print " out_file:", out_file
143
144 def get_authority(x):
145     parts = x.split(".")
146     return ".".join(parts[:3])
147
148 def dumpCredential():
149    pass
150
151 # creates a self-signed certificate and private key
152 def createKey():
153    k = Keypair(create=True)
154
155    self_signed = False
156    if self_signed:
157       ik = k
158       iname = username
159    else:
160       ik = Keypair(create=True)
161       iname = "issuer"
162
163    print "writing private key to", key_file
164    k.save_to_file(key_file)
165
166    #cert = Certificate(subject=username)
167    #cert.set_pubkey(k)
168    #cert.set_issuer(ik, iname)
169    #cert.sign()
170    #print "writing self-signed cert to", cert_file
171    #cert.save_to_file(cert_file)
172
173 def load_publickey_string(fn):
174    f = file(fn,"r")
175    key_string = f.read()
176
177    # if the filename is a private key file, then extract the public key
178    if "PRIVATE KEY" in key_string:
179        outfn = tempfile.mktemp()
180        cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
181        os.system(cmd)
182        f = file(outfn, "r")
183        key_string = f.read()
184        os.remove(outfn)
185
186    return key_string
187
188 def main():
189    process_options()
190    show_options()
191
192    result = None
193
194    # if the operation is not a local operation, then create a geniclient to
195    # talk to the server
196    if (opname != "dumpCredential") and (opname != "help") and (opname != "createKey"):
197        if not os.path.exists(key_file):
198            print "key file", key_file, "does not exist"
199            sys.exit(-1)
200        if not os.path.exists(cert_file):
201            k = Keypair(filename = key_file)
202            cert = Certificate(subject=username)
203            cert.set_pubkey(k)
204            cert.set_issuer(k, username)
205            cert.sign()
206            print "writing self-signed cert to", cert_file
207            cert.save_to_file(cert_file)
208        client = GeniClient(server_url, key_file, cert_file)
209
210    # if a cred_file was specified, then load the credential
211    if (cred_file=="None") or (opname == "help") or (opname == "createKey"):
212       cred = None
213    else:
214       cred = Credential(filename = cred_file)
215
216    if opname == "dumpCredential":
217       dumpCredential()
218
219    elif opname == "help":
220       showhelp()
221
222    elif opname == "createKey":
223       createKey()
224
225    elif (opname == "resolve"):
226       result = client.resolve(cred, hrn)
227       if result:
228           for record in result:
229               print "RESULT:"
230               record.dump()
231       else:
232           print "NO RESULT"
233
234    elif (opname == "getCredential"):
235       result = client.get_credential(cred, type, hrn)
236       if result:
237           print "RESULT:"
238           result.dump()
239           if out_file:
240               file(out_file, "w").write(result.save_to_string(save_parents=True))
241       else:
242           print "NO RESULT"
243
244    elif (opname == "list"):
245       result = client.list(cred)
246       if result:
247           for record in result:
248               print "RESULT:"
249               record.dump()
250       else:
251           print "NO RESULT"
252
253    elif (opname == "createGid"):
254        # try loading it from a private or a public key file
255        pkey_string = load_publickey_string(gid_pkey_fn)
256
257        gid = client.create_gid(cred, hrn, uuid, pkey_string)
258        if gid:
259            print "RESULT:"
260            gid.dump()
261            if out_file:
262                file(out_file,"w").write(gid.save_to_string(save_parents=True))
263        else:
264            print "NO RESULT"
265
266    elif (opname == "register"):
267        geni_info = {}
268        if type == "user":
269            if not email:
270                print "ERROR: must specify --email <addr> when registering users"
271            geni_info['email'] = email
272        gid = GID(filename=gid_fn)
273        record = GeniRecord(name=hrn, gid=gid, type=type, pointer=-1)
274        record.set_geni_info(geni_info)
275
276        result = client.register(cred, record)
277
278    elif (opname == "remove"):
279        record_list = client.resolve(cred, hrn)
280        if not record_list:
281            print "no records match hrn"
282
283        matching_records = []
284        for record in record_list:
285            if record.get_type() == type:
286                matching_records.append(record)
287
288        if not matching_records:
289            print "records match hrn, but no records match type"
290
291        for record in matching_records:
292            client.remove(cred,record)
293
294    else:
295       print "unknown operation: " + opname
296
297 if __name__=="__main__":
298    main()
299