- add -s, --session option to specify session key
[plcapi.git] / plcsh
1 #!/usr/bin/python
2 #
3 # Interactive shell for testing PLCAPI
4 #
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2005 The Trustees of Princeton University
7 #
8 # $Id: plcsh,v 1.4 2007/01/17 22:14:38 mlhuang Exp $
9 #
10
11 import os
12 import sys
13 from socket import gethostname
14 from optparse import OptionParser
15 from getpass import getpass
16 from traceback import print_exc
17
18 sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
19 from PLC.Shell import Shell
20
21 parser = OptionParser(add_help_option = False)
22 parser.add_option("-f", "--config", help = "PLC configuration file")
23 parser.add_option("-h", "--url", help = "API URL")
24 parser.add_option("-c", "--cacert", help = "API SSL certificate")
25 parser.add_option("-m", "--method", help = "API authentication method")
26 parser.add_option("-s", "--session", help = "API session key")
27 parser.add_option("-u", "--user", help = "API user name")
28 parser.add_option("-p", "--password", help = "API password")
29 parser.add_option("-r", "--role", help = "API role")
30 parser.add_option("-x", "--xmlrpc", action = "store_true", default = False, help = "Use XML-RPC interface")
31 parser.add_option("--help", action = "help", help = "show this help message and exit")
32 (options, args) = parser.parse_args()
33
34 # If user is specified but password is not
35 if options.user is not None and options.password is None:
36     try:
37         options.password = getpass()
38     except (EOFError, KeyboardInterrupt):
39         print
40         sys.exit(0)
41
42 # Initialize a single global instance (scripts may re-initialize
43 # this instance and/or create additional instances).
44 try:
45     shell = Shell(globals = globals(),
46                   config = options.config,
47                   url = options.url, xmlrpc = options.xmlrpc, cacert = options.cacert,
48                   method = options.method, role = options.role,
49                   user = options.user, password = options.password,
50                   session = options.session)
51     # Register a few more globals for backward compatibility
52     auth = shell.auth
53     api = shell.api
54     config = shell.config
55 except Exception, err:
56     print "Error:", err
57     print
58     parser.print_help()
59     sys.exit(1)
60
61 # If called by a script
62 if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
63     # Pop us off the argument stack
64     sys.argv.pop(0)
65     execfile(sys.argv[0])
66
67 # Otherwise, run an interactive shell environment
68 else:
69     if shell.server is None:
70         print "PlanetLab Central Direct API Access"
71         prompt = ""
72     elif shell.auth['AuthMethod'] == "anonymous":
73         prompt = "[anonymous]"
74         print "Connected anonymously"
75     elif shell.auth['AuthMethod'] == "session":
76         # XXX No way to tell node and user sessions apart from the
77         # client point of view.
78         prompt = "[%s]" % gethostname()
79         print "%s connected using session authentication" % gethostname()
80     else:
81         prompt = "[%s]" % shell.auth['Username']
82         print "%s connected using %s authentication" % \
83               (shell.auth['Username'], shell.auth['AuthMethod'])
84
85     # Readline and tab completion support
86     import atexit
87     import readline
88     import rlcompleter
89
90     print 'Type "system.listMethods()" or "help(method)" for more information.'
91     # Load command history
92     history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
93     try:
94         file(history_path, 'a').close()
95         readline.read_history_file(history_path)
96         atexit.register(readline.write_history_file, history_path)
97     except IOError:
98         pass
99
100     # Enable tab completion
101     readline.parse_and_bind("tab: complete")
102
103     try:
104         while True:
105             command = ""
106             while True:
107                 # Get line
108                 try:
109                     if command == "":
110                         sep = ">>> "
111                     else:
112                         sep = "... "
113                     line = raw_input(prompt + sep)
114                 # Ctrl-C
115                 except KeyboardInterrupt:
116                     command = ""
117                     print
118                     break
119
120                 # Build up multi-line command
121                 command += line
122
123                 # Blank line or first line does not end in :
124                 if line == "" or (command == line and line[-1] != ':'):
125                     break
126
127                 command += os.linesep
128
129             # Blank line
130             if command == "":
131                 continue
132             # Quit
133             elif command in ["q", "quit", "exit"]:
134                 break
135
136             try:
137                 try:
138                     # Try evaluating as an expression and printing the result
139                     result = eval(command)
140                     if result is not None:
141                         print result
142                 except SyntaxError:
143                     # Fall back to executing as a statement
144                     exec command
145             except Exception, err:
146                 print_exc()
147
148     except EOFError:
149         print
150         pass