dfd0c57c53a32001df9b0c66c730fec241fb5df5
[sfa.git] / cmdline / sfi.py
1 #! /usr/bin/env python
2 from __future__ import with_statement
3
4 # sfi -- slice-based facility interface
5
6 import sys
7 import os, os.path
8 #from cert import Keypair, Certificate
9 from optparse import OptionParser
10 #from util.geniclient import GeniClient
11
12 sfi_dir = os.path.expanduser("~/.sfi/")
13 sm_chan = None
14 reg_chan = None
15
16 #
17 # Establish Connection to SliceMgr and Registry Servers
18 #
19 def set_servers(options):
20    global sm_chan
21    global reg_chan
22
23    # Set SliceMgr and Registry URLs
24    if (options.sm is not None):
25       sm = options.sm
26    elif ("SM" in os.environ):
27       sm = os.environ["SM"]
28    else:
29       print "No Known Slice Manager"
30       sys.exit(1)
31    if (options.registry is not None):
32       registry = options.registry
33    elif ("REGISTRY" in os.environ):
34       registry = os.environ["REGISTRY"]
35    else:
36       print "No Known Registry"
37       sys.exit(1)
38    if options.verbose:
39       print "Contacting Slice Manager at:", sm
40       print "Contacting Registry at:", registry
41
42    # SliceMgr and Registry may be available on the same server
43 #   if (sm == registry):
44 #      sm_chan = GeniClient(sm, key_file, cert_file)
45 #      reg_chan = sm_chan
46 #   else:
47 #      sm_chan = GeniClient(sm, key_file, cert_file)
48 #      reg_chan = GeniClient(registry, key_file, cert_file)
49    return
50
51 #
52 # Get file names for various credentials and specs
53 #
54 # Establishes limiting conventions
55 #   - conflates MAs and SAs
56 #   - assumes a single user per working directory
57 #   - assumes last token in slice name is unique
58 #
59 # Bootstraps credentials (not done yet)
60 #
61
62 def get_leaf(name):
63    parts = name.split(".")
64    return parts[-1]
65
66 def get_user_cred_fn():
67    file = os.path.join(sfi_dir, os.environ["USER"] + ".cred")
68    if (os.path.isfile(file)):
69       return file
70    else:
71       print "bootstrap user credential here"
72
73 def get_auth_cred_fn():
74    file = os.path.join(sfi_dir, "auth.cred")
75    if (os.path.isfile(file)):
76       return file
77    else:
78       print "bootstrap authority credential here"
79
80 def get_slice_cred_fn(name):
81    file = os.path.join(sfi_dir, "slice_" + get_leaf(name) + ".cred")
82    if (os.path.isfile(file)):
83       return file
84    else:
85       print "bootstrap slice credential here"
86
87 def get_rspec_fn(rspec):
88    if (os.path.isabs(rspec)):
89       file = rspec
90    else:
91       file = os.path.join(sfi_dir, rspec)
92    if (os.path.isfile(file)):
93       return file
94    else:
95       print "No such rspec file"
96       sys.exit(1)
97
98 def get_record_fn(record):
99    if (os.path.isabs(record)):
100       file = record
101    else:
102       file = os.path.join(sfi_dir, record)
103    if (os.path.isfile(file)):
104       return file
105    else:
106       print "No such registry record file"
107       sys.exit(1)
108
109 #
110 # Generate sub-command parser
111 #
112 def create_cmd_parser(command):
113    cmdargs = {"list": "name",
114               "show": "name",
115               "remove": "name",
116               "add": "name record",
117               "update": "name record",
118               "nodes": "[name]",
119               "slices": "",
120               "resources": "name",
121               "create": "name rspec",
122               "delete": "name",
123               "reset": "name",
124               "start": "name",
125               "stop": "name"
126              }
127    if command not in cmdargs:
128       print "Invalid command\n"
129       print "Commands:list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset"
130       sys.exit(2)
131
132    parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
133       % (command, cmdargs[command]))
134    if command in ("nodes", "resources"):
135       parser.add_option("-f", "--format", dest="format",type="choice",
136            help="output format (dns|ip|hrn|rspec)",default="rspec",
137            choices=("dns","ip","hrn","rspec"))
138    elif command in ("list", "show", "remove"):
139       parser.add_option("-t", "--type", dest="type",type="choice",
140            help="type filter (user|slice|sa|ma|node|aggregate)", 
141            choices=("user","slice","sa","ma","node","aggregate", "all"),
142            default="all")
143    return parser
144
145 #
146 # Main: parse arguments and dispatch to command
147 #
148 def main():
149    global sm_chan
150    global reg_chan
151
152    # Generate command line parser
153    parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
154         description="Commands: list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
155    parser.add_option("-r", "--registry", dest="registry",
156         help="root registry", metavar="URL", default=None)
157    parser.add_option("-s", "--slicemgr", dest="sm",
158         help="slice manager", metavar="URL", default=None)
159    parser.add_option("-d", "--dir", dest="dir",
160         help="working directory", metavar="PATH", default = sfi_dir)
161    parser.add_option("-v", "--verbose",
162         action="store_true", dest="verbose", default=False,
163         help="verbose mode")
164    parser.disable_interspersed_args()
165    (options, args) = parser.parse_args()
166    command = args[0]
167    (cmd_opts, cmd_args) = create_cmd_parser(command).parse_args(args[1:])
168    if options.verbose :
169       print options.registry,options.sm,options.dir,options.verbose
170       print command
171       if command in ("nodes", "resources"):
172          print cmd_opts.format
173       elif command in ("list","show","remove"):
174          print cmd_opts.type
175       print cmd_args 
176
177    set_servers(options)
178
179    # Dispatch to selected command
180    try:
181       globals()[command](cmd_opts, cmd_args)
182    except KeyError:
183       print "Command not found:", command
184       sys.exit(1)
185    return
186
187 #
188 # Following functions implement the commands
189 #   todo: make sure args exist
190 #
191 # First, the Registry-related commands
192 #
193
194 # list entires in named authority registry
195 def list(opts, args):
196    global reg_chan
197    cred_file = get_user_cred_fn() 
198    with open(cred_file) as f:
199       credential = f.read()
200    print "list:", opts.type, args[0], reg_chan, credential
201 #   result = reg_chan.list(credential, args[0])
202 #   ...filter output based on opts.type...
203    return
204
205 # show named registry record
206 def show(opts, args):
207 # pretty print or return record xml?
208    global reg_chan
209    cred_file = get_user_cred_fn() 
210    with open(cred_file) as f:
211       credential = f.read()
212    print "show:", opts.type, args[0], reg_chan, credential
213 #   result = reg_chan.resolve(credential, args[0])
214 #   ...filter output based on opts.type...
215    return
216
217 # removed named registry record
218 def remove(opts, args):
219    global reg_chan
220    cred_file = get_auth_cred_fn() 
221    with open(cred_file) as f:
222       credential = f.read()
223    print "remove:", opts.type, args[0], reg_chan, credential
224 #   ...first retrieve named record...
225 #   results = reg_chan.resolve(credential, args[0])
226 #   ...filter desired record from result using opts.type
227 #   ...use that record to call remove...
228 #   result = reg_chan.remove(credential, record)
229    return
230
231 # add named registry record
232 def add(opts, args):
233    global reg_chan
234    cred_file = get_auth_cred_fn() 
235    with open(cred_file) as f:
236       credential = f.read()
237    rec_file = get_record_fn(args[1])
238    with open(rec_file) as g:
239       record = g.read()
240    print "add:", record, reg_chan, credential
241 #   result = reg_chan.register(credential, record)
242    return
243
244 # update named registry entry
245 def update(opts, args):
246    global reg_chan
247    cred_file = get_auth_cred_fn() 
248    with open(cred_file) as f:
249       credential = f.read()
250    rec_file = get_record_fn(args[1])
251    with open(rec_file) as g:
252       record = g.read()
253    print "update:", record, reg_chan, credential
254 #   result = reg_chan.update(credential, record)
255    return
256
257 #
258 # Second, the Slice-related commands
259 #
260
261 # list available nodes
262 def nodes(opts, args):
263    global sm_chan
264    cred_file = get_user_cred_fn() 
265    with open(cred_file) as f:
266       credential = f.read()
267    if (args[0] is None):
268       context = "root"
269    else:
270       context = args[0]
271    print "nodes:", opts.format, context, sm_chan, credential
272 #   result = sm_chan.list_nodes(credential, context)
273 #   ...format output based on opts.format...
274    return
275
276 # list instantiated slices
277 def slices(opts, args):
278    global sm_chan
279    cred_file = get_user_cred_fn() 
280    with open(cred_file) as f:
281       credential = f.read()
282    print "slices:", sm_chan, credential
283 #   result = sm_chan.list_slices(credential)
284    return
285
286 # show rspec for named slice
287 def resources(opts, args):
288    global sm_chan
289    cred_file = get_slice_cred_fn(args[0]) 
290    with open(cred_file) as f:
291       credential = f.read()
292    print "resources:", opts.format, args[0], sm_chan, credential
293 #   result = sm_chan.get_resources(credential, args[0])
294 #   ...format output based on opts.format...
295    return
296
297 # created named slice with given rspec
298 def create(opts, args):
299    global sm_chan
300    cred_file = get_slice_cred_fn(args[0]) 
301    with open(cred_file) as f:
302       credential = f.read()
303    rspec_file = get_rspec_fn(args[1])
304    with open(rspec_file) as g:
305       rspec = g.read()
306    print "create:", args[0], rspec, sm_chan, credential
307 #   result = sm_chan.instantiate(credential, rspec)
308    return
309
310 # delete named slice
311 def delete(opts, args):
312    global sm_chan
313    cred_file = get_slice_cred_fn(args[0]) 
314    with open(cred_file) as f:
315       credential = f.read()
316    print "delete:", args[0], sm_chan, credential
317 #   result = sm_chan.delete_slice(credential)
318    return
319
320 # start named slice
321 def start(opts, args):
322    global sm_chan
323    cred_file = get_slice_cred_fn(args[0]) 
324    with open(cred_file) as f:
325       credential = f.read()
326    print "start:", args[0], sm_chan, credential
327 #   result = sm_chan.start_slice(credential)
328    return
329
330 # stop named slice
331 def stop(opts, args):
332    global sm_chan
333    cred_file = get_slice_cred_fn(args[0]) 
334    with open(cred_file) as f:
335       credential = f.read()
336    print "stop:", args[0], sm_chan, credential
337 #   result = sm_chan.stop_slice(credential)
338    return
339
340 # reset named slice
341 def reset(opts, args):
342    global sm_chan
343    cred_file = get_slice_cred_fn(args[0]) 
344    with open(cred_file) as f:
345       credential = f.read()
346    print "reset:", args[0], sm_chan, credential
347 #   result = sm_chan.reset_slice(credential)
348    return
349
350
351 if __name__=="__main__":
352    main()