--- /dev/null
+#! /usr/bin/env python
+from __future__ import with_statement
+
+# sfi -- slice-based facility interface
+
+import sys
+import os, os.path
+import getopt
+from util.cert import Keypair, Certificate
+from util.credential import Credential
+from util.geniclient import GeniClient
+from util.record import GeniRecord
+from util.gid import GID
+
+infile = None
+outfile = None
+gidfile = None
+email = None
+ip = None
+dns = None
+hrn = None
+type = None
+dump = False
+researcher = []
+
+long_opts = ["infile=", "outfile=", "email=", "ip=", "dns=", "gidfile=", "hrn=", "type=", "addresearcher=", "delresearcher=", "dump"]
+
+def showhelp():
+ print "syntax: editRecord.py <options>"
+ print " --help ... show help"
+ print " --infile <name> ... read record from file"
+ print " --outfile <name> ... write record to file"
+ print " --dump ... dump record to stdout"
+ print " --gidfile <fn> ... load gid from file"
+ print " --hrn <name> ... set hrn"
+ print " --type <type> ... set type (user|slice|sa|ma|...)"
+ print " --email <addr> ... user: set email address"
+ print " --ip <addr> ... node: set ip address"
+ print " --dns <hostname> ... node: set hostname"
+ print " --addresearcher <hrn> ... slice: add researcher"
+ print " --delresearcher <hrn> ... slice: delete researcher"
+
+def process_options():
+ global infile, outfile
+ global email, ip, dns, gidfile, hrn, type
+ global researcher
+ global dump
+
+ (options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
+ for opt in options:
+ name = opt[0]
+ val = opt[1]
+
+ if name == "--help":
+ showhelp()
+ sys.exit(0)
+ elif name == "--infile":
+ infile = val
+ elif name == "--outfile":
+ outfile = val
+ elif name == "--email":
+ email = val
+ elif name == "--ip":
+ ip = val
+ elif name == "--dns":
+ dns = val
+ elif name == "--gidfile":
+ gidfile = val
+ elif name == "--hrn":
+ hrn = val
+ elif name == "--type":
+ type = val
+ elif name == "--dump":
+ dump = True
+ elif name == "--addresearcher":
+ researcher.append(val)
+ elif name == "--delresearcher":
+ researcher.append("-" + val)
+
+def errorcheck(record):
+ geni_info = record.get_geni_info()
+
+ if not record.type:
+ print "Warning: no type specified"
+ if not record.type in ["user", "sa", "ma", "slice", "node"]:
+ print "Warning: unknown record type"
+ if not record.name:
+ print "Warning: unknown record name"
+ if not record.gid:
+ print "Warning: unknown record gid"
+
+ if record.type == "user":
+ if not geni_info.get("email",None):
+ print "Warning: unknown email in user record"
+
+ if record.type == "node":
+ if not geni_info.get("ip",None):
+ print "Warning: unknown ip in node record"
+ if not geni_info.get("dns",None):
+ print "Warning: unknown dns in node record"
+
+# updates is a list of items to add or remove. If an item starts with "-", then
+# it will be removed. Otherwise it will be added
+def update_list(dict, listname, updates):
+ list = dict.get(listname, [])
+ for hrn in updates:
+ if hrn.startswith("-"):
+ real_hrn = hrn[1:]
+ if real_hrn in list:
+ list.delete(real_hrn)
+ else:
+ if not hrn in list:
+ list.append(hrn)
+
+ dict[listname] = list
+
+def main():
+ process_options()
+
+ # if the user didn't tell us to do much of anything, then maybe he needs
+ # some help
+ if (not infile) and (not outfile) and (not dump):
+ showhelp()
+ return
+
+ if infile:
+ str = file(infile, "r").read()
+ record = GeniRecord(string = str)
+ else:
+ record = GeniRecord()
+
+ geni_info = record.get_geni_info()
+ geni_info_orig = geni_info.copy()
+
+ if email:
+ geni_info["email"] = email
+
+ if ip:
+ geni_info["ip"] = ip
+
+ if dns:
+ geni_info["dns"] = dns
+
+ if hrn:
+ record.name = hrn
+
+ if type:
+ record.type = type
+
+ if gidfile:
+ gid_str = file(gidfile, "r").read()
+ gid = GID(string=gid_str)
+ record.set_gid(gid)
+
+ if researcher:
+ update_list(geni_info, "researcher", researcher)
+
+ if (geni_info != geni_info_orig):
+ record.set_geni_info(geni_info)
+
+ errorcheck(record)
+
+ if dump:
+ record.dump(False)
+
+ if outfile:
+ str = record.save_to_string()
+ file(outfile, "w").write(str)
+ print "wrote record to", outfile
+
+if __name__=="__main__":
+ main()
gid_fn = None
filter = None
+dump_fn = None
+
dump_parents = False
leaf_name = None
print " --short ... list records in short format (name only)"
print "commands:"
print " resolve <hrn>"
- print " dumpCredential"
+ print " dumpCredential <filename>"
+ print " dumpGid <filename>"
print " getCredential <type> <hrn>"
print " list <hrn>"
print " start <hrn>"
global server_url
global filter
global short
+ global dump_fn
(options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
for opt in options:
sys.exit(-1)
hrn = args[1]
+ elif opname == "dumpGid":
+ if len(args) < 2:
+ print "syntax: dumpGid <filename>"
+ sys.exit(-1)
+ dump_fn = args[1]
+
leaf_name = get_leaf(username)
if cert_file == None:
def dumpCredential():
pass
+def dumpGid():
+ gid = GID(filename = dump_fn)
+ gid.dump()
+
# creates a self-signed certificate and private key
def createKey():
k = Keypair(create=True)
# if the operation is not a local operation, then create a geniclient to
# talk to the server
- if (opname != "dumpCredential") and (opname != "help") and (opname != "createKey"):
+ if (opname != "dumpCredential") and (opname != "help") and (opname != "createKey") and (opname != "dumpGid"):
if not os.path.exists(key_file):
print "key file", key_file, "does not exist"
sys.exit(-1)
# if a cred_file was specified, then load the credential
if (cred_file=="None") or (opname == "help") or (opname == "createKey") or \
- (opname == "redeemTicket"):
+ (opname == "redeemTicket") or (opname == "dumpCredential") or (opname == "dumpGid"):
cred = None
else:
cred = Credential(filename = cred_file)
if opname == "dumpCredential":
dumpCredential()
+ elif opname == "dumpGid":
+ dumpGid()
+
elif opname == "help":
showhelp()
import sys
import os, os.path
+import tempfile
from optparse import OptionParser
from util.cert import Keypair, Certificate
from util.credential import Credential
from util.geniclient import GeniClient
+from util.gid import create_uuid
+from util.record import GeniRecord
sfi_dir = os.path.expanduser("~/.sfi/")
slicemgr = None
def get_auth_cred():
global authority
- file = os.path.join(sfi_dir, "authority.cred")
+ if not authority:
+ print "no authority specified. Use -a or set SF_AUTH"
+ sys.exit(-1)
+
+ file = os.path.join(sfi_dir, get_leaf("authority") +".cred")
if (os.path.isfile(file)):
auth_cred = Credential(filename=file)
return auth_cred
if (os.path.isfile(file)):
return file
else:
- print "No such rspec file"
+ print "No such rspec file", rspec
sys.exit(1)
def get_record_file(record):
if (os.path.isfile(file)):
return file
else:
- print "No such registry record file"
+ print "No such registry record file", record
sys.exit(1)
+def load_publickey_string(fn):
+ f = file(fn,"r")
+ key_string = f.read()
+
+ # if the filename is a private key file, then extract the public key
+ if "PRIVATE KEY" in key_string:
+ outfn = tempfile.mktemp()
+ cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
+ os.system(cmd)
+ f = file(outfn, "r")
+ key_string = f.read()
+ os.remove(outfn)
+
+ return key_string
+
#
# Generate sub-command parser
cmdargs = {"list": "name",
"show": "name",
"remove": "name",
+ "creategid": "hrn publickey_fn",
"add": "name record",
"update": "name record",
"nodes": "[name]",
help="type filter (user|slice|sa|ma|node|aggregate)",
choices=("user","slice","sa","ma","node","aggregate", "all"),
default="all")
- if command in ("show", "list", "nodes", "resources"):
+ if command in ("show", "list", "nodes", "resources", "creategid"):
parser.add_option("-o", "--output", dest="file",
help="output XML to file", metavar="FILE", default=None)
return parser
auth_cred = get_auth_cred()
return registry.remove(auth_cred, opts.type, args[0])
+def creategid(opts, args):
+ global registry
+ auth_cred = get_auth_cred()
+ hrn = args[0]
+ pkey_string = load_publickey_string(args[1])
+ gid = registry.create_gid(auth_cred, hrn, create_uuid(), pkey_string)
+ if (opts.file is not None):
+ gid.save_to_file(opts.file, save_parents=True)
+ else:
+ print "I created your gid, but you did not ask me to save it"
+
# add named registry record
def add(opts, args):
global registry
auth_cred = get_auth_cred()
- rec_file = get_record_file(args[1])
- with open(rec_file) as f:
- record = f.read()
+ rec_file = get_record_file(args[0])
+ record = load_record_from_file(rec_file)
return registry.register(auth_cred, record)
# update named registry entry
def update(opts, args):
global registry
user_cred = get_user_cred()
- rec_file = get_record_file(args[1])
- with open(rec_file) as f:
- record = f.read()
- return registry.update(user_cred, record)
+ rec_file = get_record_file(args[0])
+ record = load_record_from_file(rec_file)
+
+ if record.get_type() == "user":
+ cred = user_cred
+ elif record.get_type() in ["sa", "ma", "slice", "node"]:
+ cred = get_auth_cred()
+ else:
+ raise "unknown record type" + record.get_type()
+
+ return registry.update(cred, record)
#
# Slice-related commands
# show rspec for named slice
def resources(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
result = slicemgr.get_slice_resources(slice_cred, args[0])
display_rspec(opts.format, result)
if (opts.file is not None):
# created named slice with given rspec
def create(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
rspec_file = get_rspec_file(args[1])
with open(rspec_file) as f:
rspec = f.read()
# delete named slice
def delete(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
return slicemgr.delete_slice(slice_cred)
# start named slice
def start(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
return slicemgr.start_slice(slice_cred)
# stop named slice
def stop(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
return slicemgr.stop_slice(slice_cred)
# reset named slice
def reset(opts, args):
global slicemgr
- slice_cred = get_slice_cred(args[0])
+ slice_cred = get_slice_cred(args[0])
return slicemgr.reset_slice(slice_cred)
#
file(filename, "w").write(str)
return
+def load_record_from_file(filename):
+ str = file(filename, "r").read()
+ record = GeniRecord(string=str)
+ return record
+
if __name__=="__main__":
main()
--- /dev/null
+#!/bin/bash
+
+source configSfi.sh
+
+rm -f saved_record.*
+
+python ./sfi.py show -o saved_record.$SFI_USER $SFI_USER
+python ./sfi.py list -o saved_record.$SFI_AUTH $SFI_AUTH
+
+#rm -f saved_record.*
--- /dev/null
+#!/bin/bash
+
+source configSfi.sh
+
+CWD=`pwd`
+
+# private key to use when creating GID for new slice
+export TEST_KEY=$CWD/testkey.pkey
+
+export TEST_SLICE_GID=$CWD/testslice.gid
+export TEST_SLICE_RECORD=$CWD/testslice.record
+export TEST_SLICE_HRN=$SFI_AUTH.testslice
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Creating a GID for test slice $TEST_SLICE_HRN
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py creategid -o $TEST_SLICE_GID $TEST_SLICE_HRN $TEST_KEY
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Removing the test slice. this will cause an error if the slice does
+echo XXXXX not exist -- this error can be ignored
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py remove --type slice $TEST_SLICE_HRN
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Creating a record for the test slice
+echo XXXXX -------------------------------------------------------------------
+
+python ./editRecord.py --hrn $TEST_SLICE_HRN --gidfile $TEST_SLICE_GID --type slice --addresearcher $SFI_USER --outfile $TEST_SLICE_RECORD
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Adding the test slice, $TEST_SLICE_HRN
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py add $TEST_SLICE_RECORD
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX The slice should have one researcher, $SFI_USER
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py show $TEST_SLICE_HRN
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Adding $TEST_USER_2 to the slice researchers
+echo XXXXX -------------------------------------------------------------------
+
+python ./editRecord.py --infile $TEST_SLICE_RECORD --outfile $TEST_SLICE_RECORD --addresearcher $TEST_USER_2 --outfile $TEST_SLICE_RECORD
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Updating the slice
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py update $TEST_SLICE_RECORD
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX The slice record should now have two users: $SFI_USER, $TEST_USER_2
+echo XXXXX -------------------------------------------------------------------
+
+python ./sfi.py show $TEST_SLICE_HRN
+
echo XXXXX Update Self
python ./genicli.py --server $PLC_URL --username $USERNAME update user $USER_HRN
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX List Records in parent authority
+python ./genicli.py --server $PLC_URL --username $USERNAME --short list $PARENT_HRN
\ No newline at end of file