#! /usr/bin/env python
+from __future__ import with_statement
# sfi -- slice-based facility interface
import sys
-import os
+import os, os.path
#from cert import Keypair, Certificate
from optparse import OptionParser
+#from util.geniclient import GeniClient
+sfi_dir = os.path.expanduser("~/.sfi/")
+sm_chan = None
+reg_chan = None
+
+#
+# Establish Connection to SliceMgr and Registry Servers
+#
+def set_servers(options):
+ global sm_chan
+ global reg_chan
+
+ # Set SliceMgr and Registry URLs
+ if (options.sm is not None):
+ sm = options.sm
+ elif ("SM" in os.environ):
+ sm = os.environ["SM"]
+ else:
+ print "No Known Slice Manager"
+ sys.exit(1)
+ if (options.registry is not None):
+ registry = options.registry
+ elif ("REGISTRY" in os.environ):
+ registry = os.environ["REGISTRY"]
+ else:
+ print "No Known Registry"
+ sys.exit(1)
+ if options.verbose:
+ print "Contacting Slice Manager at:", sm
+ print "Contacting Registry at:", registry
+
+ # SliceMgr and Registry may be available on the same server
+# if (sm == registry):
+# sm_chan = GeniClient(sm, key_file, cert_file)
+# reg_chan = sm_chan
+# else:
+# sm_chan = GeniClient(sm, key_file, cert_file)
+# reg_chan = GeniClient(registry, key_file, cert_file)
+ return
+
+#
+# Get file names for various credentials and specs
+#
+# Establishes limiting conventions
+# - conflates MAs and SAs
+# - assumes a single user per working directory
+# - assumes last token in slice name is unique
+#
+# Bootstraps credentials (not done yet)
+#
+
+def get_leaf(name):
+ parts = name.split(".")
+ return parts[-1]
+
+def get_user_cred_fn():
+ file = os.path.join(sfi_dir, os.environ["USER"] + ".cred")
+ if (os.path.isfile(file)):
+ return file
+ else:
+ print "bootstrap user credential here"
+
+def get_auth_cred_fn():
+ file = os.path.join(sfi_dir, "auth.cred")
+ if (os.path.isfile(file)):
+ return file
+ else:
+ print "bootstrap authority credential here"
+
+def get_slice_cred_fn(name):
+ file = os.path.join(sfi_dir, "slice_" + get_leaf(name) + ".cred")
+ if (os.path.isfile(file)):
+ return file
+ else:
+ print "bootstrap slice credential here"
+
+def get_rspec_fn(rspec):
+ if (os.path.isabs(rspec)):
+ file = rspec
+ else:
+ file = os.path.join(sfi_dir, rspec)
+ if (os.path.isfile(file)):
+ return file
+ else:
+ print "No such rspec file"
+ sys.exit(1)
+
+def get_record_fn(record):
+ if (os.path.isabs(record)):
+ file = record
+ else:
+ file = os.path.join(sfi_dir, record)
+ if (os.path.isfile(file)):
+ return file
+ else:
+ print "No such registry record file"
+ sys.exit(1)
+
+#
+# Generate sub-command parser
+#
def create_cmd_parser(command):
cmdargs = {"list": "name",
"show": "name",
- "delete": "name",
+ "remove": "name",
"add": "name record",
"update": "name record",
"nodes": "[name]",
}
if command not in cmdargs:
print "Invalid command\n"
- print "Commands:list,show,delete,add,update,nodes,slices,resources,create,delete,start,stop,reset"
+ print "Commands:list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset"
sys.exit(2)
parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
parser.add_option("-f", "--format", dest="format",type="choice",
help="output format (dns|ip|hrn|rspec)",default="rspec",
choices=("dns","ip","hrn","rspec"))
- elif command in ("list", "show", "delete"):
+ elif command in ("list", "show", "remove"):
parser.add_option("-t", "--type", dest="type",type="choice",
help="type filter (user|slice|sa|ma|node|aggregate)",
- choices=("user","slice","sa","ma","node","aggregate"))
+ choices=("user","slice","sa","ma","node","aggregate", "all"),
+ default="all")
return parser
+#
+# Main: parse arguments and dispatch to command
+#
def main():
+ global sm_chan
+ global reg_chan
+
+ # Generate command line parser
parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
- description="Commands: list,show,delete,add,update,nodes,slices,resources,create,delete,start,stop,reset")
+ description="Commands: list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
parser.add_option("-r", "--registry", dest="registry",
- help="root registry", metavar="URL")
+ help="root registry", metavar="URL", default=None)
parser.add_option("-s", "--slicemgr", dest="sm",
- help="slice manager", metavar="URL")
+ help="slice manager", metavar="URL", default=None)
parser.add_option("-d", "--dir", dest="dir",
- help="working directory", metavar="PATH")
+ help="working directory", metavar="PATH", default = sfi_dir)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help="verbose mode")
print command
if command in ("nodes", "resources"):
print cmd_opts.format
- elif command in ("list","show","delete"):
+ elif command in ("list","show","remove"):
print cmd_opts.type
- print cmd_args
+ print cmd_args
+
+ set_servers(options)
+
+ # Dispatch to selected command
+ try:
+ globals()[command](cmd_opts, cmd_args)
+ except KeyError:
+ print "Command not found:", command
+ sys.exit(1)
+ return
+
+#
+# Following functions implement the commands
+# todo: make sure args exist
+#
+# First, the Registry-related commands
+#
+
+# list entires in named authority registry
+def list(opts, args):
+ global reg_chan
+ cred_file = get_user_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ print "list:", opts.type, args[0], reg_chan, credential
+# result = reg_chan.list(credential, args[0])
+# ...filter output based on opts.type...
+ return
+
+# show named registry record
+def show(opts, args):
+# pretty print or return record xml?
+ global reg_chan
+ cred_file = get_user_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ print "show:", opts.type, args[0], reg_chan, credential
+# result = reg_chan.resolve(credential, args[0])
+# ...filter output based on opts.type...
+ return
+
+# removed named registry record
+def remove(opts, args):
+ global reg_chan
+ cred_file = get_auth_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ print "remove:", opts.type, args[0], reg_chan, credential
+# ...first retrieve named record...
+# results = reg_chan.resolve(credential, args[0])
+# ...filter desired record from result using opts.type
+# ...use that record to call remove...
+# result = reg_chan.remove(credential, record)
return
+# add named registry record
+def add(opts, args):
+ global reg_chan
+ cred_file = get_auth_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ rec_file = get_record_fn(args[1])
+ with open(rec_file) as g:
+ record = g.read()
+ print "add:", record, reg_chan, credential
+# result = reg_chan.register(credential, record)
+ return
+
+# update named registry entry
+def update(opts, args):
+ global reg_chan
+ cred_file = get_auth_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ rec_file = get_record_fn(args[1])
+ with open(rec_file) as g:
+ record = g.read()
+ print "update:", record, reg_chan, credential
+# result = reg_chan.update(credential, record)
+ return
+
+#
+# Second, the Slice-related commands
+#
+
+# list available nodes
+def nodes(opts, args):
+ global sm_chan
+ cred_file = get_user_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ if (args[0] is None):
+ context = "root"
+ else:
+ context = args[0]
+ print "nodes:", opts.format, context, sm_chan, credential
+# result = sm_chan.list_nodes(credential, context)
+# ...format output based on opts.format...
+ return
+
+# list instantiated slices
+def slices(opts, args):
+ global sm_chan
+ cred_file = get_user_cred_fn()
+ with open(cred_file) as f:
+ credential = f.read()
+ print "slices:", sm_chan, credential
+# result = sm_chan.list_slices(credential)
+ return
+
+# show rspec for named slice
+def resources(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ print "resources:", opts.format, args[0], sm_chan, credential
+# result = sm_chan.get_resources(credential, args[0])
+# ...format output based on opts.format...
+ return
+
+# created named slice with given rspec
+def create(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ rspec_file = get_rspec_fn(args[1])
+ with open(rspec_file) as g:
+ rspec = g.read()
+ print "create:", args[0], rspec, sm_chan, credential
+# result = sm_chan.instantiate(credential, rspec)
+ return
+
+# delete named slice
+def delete(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ print "delete:", args[0], sm_chan, credential
+# result = sm_chan.delete_slice(credential)
+ return
+
+# start named slice
+def start(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ print "start:", args[0], sm_chan, credential
+# result = sm_chan.start_slice(credential)
+ return
+
+# stop named slice
+def stop(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ print "stop:", args[0], sm_chan, credential
+# result = sm_chan.stop_slice(credential)
+ return
+
+# reset named slice
+def reset(opts, args):
+ global sm_chan
+ cred_file = get_slice_cred_fn(args[0])
+ with open(cred_file) as f:
+ credential = f.read()
+ print "reset:", args[0], sm_chan, credential
+# result = sm_chan.reset_slice(credential)
+ return
+
+
if __name__=="__main__":
main()