3 # Copyright (c) 2004-2020 University of Utah and the Flux Group.
7 # This file is part of the Emulab network testbed software.
9 # This file is free software: you can redistribute it and/or modify it
10 # under the terms of the GNU Affero General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or (at
12 # your option) any later version.
14 # This file is distributed in the hope that it will be useful, but WITHOUT
15 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
17 # License for more details.
19 # You should have received a copy of the GNU Affero General Public License
20 # along with this file. If not, see <http://www.gnu.org/licenses/>.
29 import xmlrpc.client as xmlrpc_client
36 XMLRPC_SERVER = "boss.emulab.net"
38 SERVER_PATH = "/usr/testbed"
39 URI = "https://" + XMLRPC_SERVER + ":" + str(XMLRPC_PORT) + SERVER_PATH
44 RESPONSE_FORBIDDEN = 3
45 RESPONSE_BADVERSION = 4
46 RESPONSE_SERVERERROR = 5
48 RESPONSE_REFUSED = 7 # Emulab is down, try again later.
51 # User supplied login ID, password, and certificate
53 LOGIN_ID = os.environ['USER']
54 PEM_PWORD = os.environ['PWORD']
55 CERT_PATH = os.environ['CERT']
57 logging.error('Missing Powder credential environment variable(s)')
61 def do_method(method, params):
62 ctx = ssl.SSLContext()
63 ctx.set_ciphers('ALL:@SECLEVEL=0')
64 ctx.load_cert_chain(CERT_PATH, password=PEM_PWORD)
65 ctx.check_hostname = False
66 ctx.verify_mode = ssl.CERT_NONE
68 # Get a handle on the server,
69 server = xmlrpc_client.ServerProxy(URI, context=ctx, verbose=DEBUG)
71 # Get a pointer to the function we want to invoke.
72 meth = getattr(server, "portal." + method)
73 meth_args = [PACKAGE_VERSION, params]
77 response = meth(*meth_args)
78 except xmlrpc_client.Fault as e:
82 rval = response["code"]
84 # If the code indicates failure, look for a "value". Use that as the
85 # return value instead of the code.
86 if rval != RESPONSE_SUCCESS:
88 rval = response["value"]
93 def start_experiment(experiment_name, project_name, profile_name):
95 "name": experiment_name,
97 "profile": ','.join([project_name, profile_name])
99 rval, response = do_method("startExperiment", params)
100 return rval, response
103 def terminate_experiment(project_name, experiment_name):
105 "experiment": ','.join([project_name, experiment_name])
107 rval, response = do_method("terminateExperiment", params)
108 return rval, response
111 def get_experiment_status(project_name, experiment_name):
113 "experiment": ','.join([project_name, experiment_name])
115 rval, response = do_method("experimentStatus", params)
116 return rval, response
119 def get_experiment_manifests(project_name, experiment_name):
121 "experiment": ','.join([project_name, experiment_name])
123 rval, response = do_method("experimentManifests", params)
124 return rval, response