more genicli operations, test scripts
authorScott Baker <bakers@cs.arizona.edu>
Tue, 26 Aug 2008 17:53:49 +0000 (17:53 +0000)
committerScott Baker <bakers@cs.arizona.edu>
Tue, 26 Aug 2008 17:53:49 +0000 (17:53 +0000)
cmdline/genicli.py
cmdline/testSA.sh [new file with mode: 0755]
cmdline/testUser.sh [new file with mode: 0755]

index 06cb466..610f9ab 100644 (file)
 
 import getopt
 import sys
-from clientstub import *
+import os
+from cert import *
+from geniclient import *
 
-long_opts = ["username=", "usertype=", "help", "outfile=", "credfile="]
+long_opts = ["keyfile=", "help", "outfile=", "credfile=", "username=", "email="]
 
 # default command line options
-username = "planetlab.scott.pl.smbaker"
-usertype = "user"
-opname = "lookup"
+username = "client"
+opname = None
 type = None
 hrn = None
-cred_name = None
-id_file = None
+
 key_file = None
-acc_file = None
 cred_file = None
-leaf_name = None
-server_host = "127.0.0.1"
-server_port = 8002
+cert_file = None
 out_file = None
 
+email = None
+uuid = None
+gid_pkey_fn = None
+gid_fn = None
+
+leaf_name = None
+server_url = "https://localhost:12345/"
+
+def get_leaf(hrn):
+    parts = hrn.split(".")\r
+    return parts[-1]
+
 def showhelp():
    print "syntax: cli <options> command <args>"
    print "options:"
-   print "    --username       ... hrn of user performing op"
-   print "    --usertype       ... kind of user performing op (user, slice, ...)"
-   print "    --outfile        ... write reply to file"
-   print "    --credfile       ... credential to pass"
+   print "    --username       ... username (or hrn) of user making call"
+   print "    --outfile        ... save response to a file"
+   print "    --credfile       ... credential of user making call (or 'None')"
+   print "    --keyfile        ... private key file of user making call"
+   print "    --email          ... email address"
    print "commands:"
-   print "    lookup <type> <hrn>"
+   print "    resolve <hrn>"
    print "    dumpCredential"
-   print "    getCredential <cred_name>"
+   print "    getCredential <type> <hrn>"
    print "    start <hrn>"
+   print "    createKey <filename>"
+   print "    createGid <hrn> <uuid|None> <pubkey_fn>"
+   print "    register <type> <hrn> <gid_filename>"
+   print "    remove <type> <hrn>"
 
 def process_options():
-   global username, usertype, opname
-   global type, hrn, cred_name
-   global leaf_name
-   global id_file, cred_file
-   global acc_file, key_file, out_file
+   global username
+   global opname
+   global type, hrn
+   global cert_file, cred_file
+   global key_file, out_file
+   global uuid, pkey_fn, gid_fn, email, gid_pkey_fn
 
    (options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
    for opt in options:
        name = opt[0]
        val = opt[1]
 
-       if name == "--username":
-           username = val
-       elif name == "--usertype":
-           usertype = val
-       elif name == "--help":
+       if name == "--help":
            showhelp()
            sys.exit(0)
+       elif name == "--username":
+           username = val
        elif name == "--outfile":
            out_file = val
        elif name == "--credfile":
            cred_file = val
+       elif name == "--certfile":
+           cred_file = val
+       elif name == "--keyfile":
+           key_file = val
+       elif name == "--email":
+           email = val
 
    if not args:
-       report.error("no operation specified")
+       print "no operation specified"
        sys.exit(-1)
 
    opname = args[0]
 
-   if opname == "lookup":
-       if len(args) < 3:
-           report.error("syntax: lookup <type> <hrn>")
+   if opname == "resolve":
+       if len(args) < 2:
+           print "syntax: resolve <hrn>"
            sys.exit(-1)
-       type = args[1]
-       hrn = args[2]
+       hrn = args[1]
 
    elif opname == "getCredential":
-       if len(args) < 1:
-           report.error("syntax: getcredential <cred_name>")
+       if len(args) < 3:
+           print "syntax: getcredential <type> <hrn>"
            sys.exit(-1)
-       cred_name = args[1]
+       type = args[1]
+       hrn = args[2]
 
-   elif opname == "start":
-       if len(args) < 1:
-           report.error("syntax: start <hrn>")
-           sys.exit(-1)
+   elif opname == "createGid":
+       if len(args) < 4:
+           print "syntax: createGid <hrn> <uuid|None> <pubkey_fn>"
        hrn = args[1]
+       if args[2]=="None":
+           uuid=None
+       else:
+           uuid = int(args[2])
+       gid_pkey_fn = args[3]
+
+   elif opname == "register":
+       if len(args) < 4:
+           print "syntax: register <type> <hrn> <gid_filename>"
+       type = args[1]
+       hrn = args[2]
+       gid_fn = args[3]
+
+   elif opname == "remove":
+       if len(args) < 3:
+           print "syntax: remove <type> <hrn>"
+       type = args[1]
+       hrn = args[2]
 
-   if not leaf_name:
-       leaf_name = get_leaf(username)
+   leaf_name = get_leaf(username)
 
-   if id_file == None:
-       id_file = leaf_name + ".cert"
+   if cert_file == None:
+       cert_file = leaf_name + ".cert"
 
    if key_file == None:
        key_file = leaf_name + ".pkey"
 
-   if acc_file == None:
-       acc_file = "acc_file"
-
    if cred_file == None:
-       cred_file = "cred_file"
+       cred_file = leaf_name + ".cred"
 
 def show_options():
    print " username:", username
-   print "     leaf:", leaf_name
-   print " usertype:", usertype
-   print "  id_file:", id_file
+   print "cert_file:", cert_file
    print " key_file:", key_file
-   print " acc_file:", acc_file
    print "cred_file:", cred_file
    print "operation:", opname
    print "     type:", type
    print "      hrn:", hrn
-   print "cred_name:", cred_name
    print " out_file:", out_file
 
 def get_authority(x):
     parts = x.split(".")
     return ".".join(parts[:3])
 
-def compose_message():
-   g_params = {}
-   p_params = {}
-   dict = {"opname": opname}
-
-   if opname == "lookup":
-      g_params["hrn"] = hrn
-      g_params["type"] = type
-
-   elif opname == "getCredential":
-      g_params["cred_name"] = cred_name
-
-      parts = cred_name.split(":")
-      if len(parts) < 2:
-          report.error("bad format for getCredential (slice:hrn.of.slice, ...)")
-
-      # XXX smbaker: this looks redundant
-      if parts[0] == "slice":
-         g_params["hrn"] = get_authority(parts[1])
-         g_params["type"] = "slice"
-
-   elif opname == "start":
-      g_params["hrn"] = hrn
-      g_params["type"] = "slice"
-
-   dict["g_params"] = g_params
-   dict["p_params"] = p_params
-
-   return dict
-
-def do_remote_op():
-   message = compose_message()
-
-   client = GENIClient(username, usertype, id_file, key_file, acc_file, cred_file)
-
-   server = client.connect(server_host, server_port)
-   if not server:
-       report.error("failed to connect to server")
-       sys.exit(-1)
-
-   report.trace("message:" + str(message))
-
-   server.write(str(message))
+def dumpCredential():
+   pass
 
-   reply = server.read(MAX_RESULT)
-   if not reply:
-      report.error("No reply")
-      sys.exit(-1)
+# creates a self-signed certificate and private key
+def createKey():
+   k = Keypair(create=True)
 
-   if out_file:
-      open(out_file, "w").write(reply)
+   self_signed = False
+   if self_signed:
+      ik = k
+      iname = username
    else:
-      print "////// RESULT: //////"
-      print reply
-
-def dumpCredential():
-    cred_str = open(cred_file).read()
-    c_pem = X509.load_cert_string(cred_str)
-    subjectAltName = c_pem.get_ext("subjectAltName").get_value()
-    info_cert = get_cred_info(subjectAltName)
-
-    print "subject:", c_pem.get_subject().CN
-    print "issuer:", c_pem.get_issuer().CN
-    print "cred_str:"
-    print " ", subjectAltName
-    print "rights:"
-    op_set = info_cert['operation_set']
-    for item in op_set.keys():
-       rights = op_set[item]
-       print " ", item, ", ".join(rights)
-
-    print "interfaces:"
-    interfaces = info_cert['on_interfaces']
-    for item in interfaces:
-       print " ", item['lbl'], item['type'], item['name']
+      ik = Keypair(create=True)
+      iname = "issuer"
+
+   print "writing private key to", key_file
+   k.save_to_file(key_file)
+
+   #cert = Certificate(subject=username)
+   #cert.set_pubkey(k)
+   #cert.set_issuer(ik, iname)
+   #cert.sign()
+   #print "writing self-signed cert to", cert_file
+   #cert.save_to_file(cert_file)
+
+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
 
 def main():
    process_options()
    show_options()
 
+   result = None
+
+   # 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 not os.path.exists(key_file):
+           print "key file", key_file, "does not exist"
+           sys.exit(-1)
+       if not os.path.exists(cert_file):
+           k = Keypair(filename = key_file)
+           cert = Certificate(subject=username)
+           cert.set_pubkey(k)
+           cert.set_issuer(k, username)
+           cert.sign()
+           print "writing self-signed cert to", cert_file
+           cert.save_to_file(cert_file)
+       client = GeniClient(server_url, key_file, cert_file)
+
+   # if a cred_file was specified, then load the credential
+   if (cred_file=="None") or (opname == "help") or (opname == "createKey"):
+      cred = None
+   else:
+      cred = Credential(filename = cred_file)
+
    if opname == "dumpCredential":
       dumpCredential()
-      sys.exit(0)
-      
+
    elif opname == "help":
       showhelp()
-      sys.exit(0)
 
-   elif (opname == "lookup") or \
-        (opname == "getCredential") or \
-        (opname == "start"):
-      do_remote_op()
+   elif opname == "createKey":
+      createKey()
+
+   elif (opname == "resolve"):
+      result = client.resolve(cred, hrn)
+      if result:
+          for record in result:
+              print "RESULT:"
+              record.dump()
+      else:
+          print "NO RESULT"
+
+   elif (opname == "getCredential"):
+      result = client.get_credential(cred, type, hrn)
+      if result:
+          print "RESULT:"
+          result.dump()
+          if out_file:
+              file(out_file, "w").write(result.save_to_string(save_parents=True))
+      else:
+          print "NO RESULT"
+
+   elif (opname == "list"):
+      result = client.list(cred)
+      if result:
+          for record in result:
+              print "RESULT:"
+              record.dump()
+      else:
+          print "NO RESULT"
+
+   elif (opname == "createGid"):
+       # try loading it from a private or a public key file
+       pkey_string = load_publickey_string(gid_pkey_fn)
+
+       gid = client.create_gid(cred, hrn, uuid, pkey_string)
+       if gid:
+           print "RESULT:"
+           gid.dump()
+           if out_file:
+               file(out_file,"w").write(gid.save_to_string(save_parents=True))
+       else:
+           print "NO RESULT"
+
+   elif (opname == "register"):
+       geni_info = {}
+       if type == "user":
+           if not email:
+               print "ERROR: must specify --email <addr> when registering users"
+           geni_info['email'] = email
+       gid = GID(filename=gid_fn)
+       record = GeniRecord(name=hrn, gid=gid, type=type, pointer=-1)
+       record.set_geni_info(geni_info)
+
+       result = client.register(cred, record)
+
+   elif (opname == "remove"):
+       record_list = client.resolve(cred, hrn)
+       if not record_list:
+           print "no records match hrn"
+
+       matching_records = []
+       for record in record_list:
+           if record.get_type() == type:
+               matching_records.append(record)
+
+       if not matching_records:
+           print "records match hrn, but no records match type"
+
+       for record in matching_records:
+           client.remove(cred,record)
 
    else:
-      report.error("unknown operation: " + opname)
+      print "unknown operation: " + opname
 
 if __name__=="__main__":
    main()
diff --git a/cmdline/testSA.sh b/cmdline/testSA.sh
new file mode 100755 (executable)
index 0000000..1ebd96f
--- /dev/null
@@ -0,0 +1,51 @@
+rm -f root.cred
+rm -f root.cert
+rm -f rootsa.cred
+rm -f testkey.pkey
+rm -f testkey.gid
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Getting Self Credential
+python ./genicli.py --username root --credfile None --outfile root.cred getCredential user planetlab.us.pl.Administrator_Default
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Resolving Self
+python ./genicli.py --username root resolve planetlab.us.pl.account_test
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Getting SA Credential
+python ./genicli.py --username root --outfile rootsa.cred getCredential sa planetlab.us.pl
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX List records in an authority
+python ./genicli.py --username root --credfile rootsa.cred list
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Create a private key
+python ./genicli.py --username testkey createKey
+
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Create a GID for a user
+python ./genicli.py --username root --credfile rootsa.cred --outfile testuser.gid createGid planetlab.us.pl.testuser None testkey.pkey
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Create a GID for a slice
+python ./genicli.py --username root --credfile rootsa.cred --outfile testslice.gid createGid planetlab.us.pl.testslice1 None testkey.pkey
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Register a user
+python ./genicli.py --username root --credfile rootsa.cred --email test1234@test.com register user planetlab.us.pl.testuser testuser.gid
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Resolve the test user
+python ./genicli.py --username root --credfile rootsa.cred resolve planetlab.us.pl.testuser
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Register a slice
+python ./genicli.py --username root --credfile rootsa.cred --email test1234@test.com register slice planetlab.us.pl.testslice1 testslice.gid
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Remove a user
+python ./genicli.py --username root --credfile rootsa.cred remove user planet\
+lab.us.pl.testuser
diff --git a/cmdline/testUser.sh b/cmdline/testUser.sh
new file mode 100755 (executable)
index 0000000..f709139
--- /dev/null
@@ -0,0 +1,14 @@
+rm -f test.cred
+rm -f test.cert
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Getting Credential
+python ./genicli.py --username test --credfile None --outfile test.cred getCredential user planetlab.us.pl.account_test
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX Resolving Self
+python ./genicli.py --username test resolve planetlab.us.pl.account_test
+
+echo XXXXX -------------------------------------------------------------------
+echo XXXXX List records in an authority
+python ./genicli.py --username test list planetlab.us.pl
\ No newline at end of file