Skip to content

Commit 7791aa9

Browse files
Sadanand HegdeSadanand Hegde
authored andcommitted
Initial commit
1 parent 5dd804e commit 7791aa9

File tree

3 files changed

+273
-0
lines changed

3 files changed

+273
-0
lines changed

Sandbox.py

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
import requests
2+
import json
3+
import sys
4+
5+
6+
class Sandbox:
7+
"""
8+
Sandbox Python API wrapper
9+
"""
10+
11+
def __init__(self, config_file):
12+
quali_config = json.load(open(config_file, 'r'))
13+
self.server_address = 'http://{}:{}/api'.format(quali_config['server_name'], quali_config['server_port'])
14+
self.username = quali_config['username']
15+
self.password = quali_config['password']
16+
self.domain = quali_config['domain']
17+
self.auth_code = ''
18+
self.headers = ''
19+
20+
def _request_and_parse(self, request_type, url_str, json_dict={}, data_dict={}):
21+
"""
22+
23+
:param request_type:
24+
:param url_str:
25+
:param json_dict:
26+
:param data_dict:
27+
:return:
28+
"""
29+
30+
response = ''
31+
if request_type.lower() == 'put':
32+
response = requests.put(url_str, json=json_dict, headers=self.headers)
33+
34+
elif request_type.lower() == 'get':
35+
response = requests.get(url_str, json=json_dict, headers=self.headers)
36+
37+
elif request_type.lower() == 'post':
38+
response = requests.post(url_str, json=json_dict, headers=self.headers, data=json.dumps(data_dict))
39+
40+
if not response.ok:
41+
sys.exit('Error code: {}\nError text: {}\nP{} failed, exiting'.format(response.status_code,
42+
json.loads(response.text)[
43+
'message'], url_str))
44+
return response
45+
46+
def login(self):
47+
"""Login and set some internal variables
48+
"""
49+
url_str = self.server_address + '/login'
50+
json_dict = {'username': self.username, 'password': self.password, 'domain': self.domain}
51+
response = self._request_and_parse('put', url_str, json_dict)
52+
self.auth_code = "Basic " + response.content[1:-1]
53+
self.headers = {"Authorization": self.auth_code, "Content-Type": "application/json"}
54+
55+
def get_blueprints(self):
56+
"""Get all blueprints details
57+
:return: <dict> Dict of blueprints and their ids
58+
"""
59+
url_str = '{}{}'.format(self.server_address, '/v1/blueprints')
60+
response = self._request_and_parse('get', url_str)
61+
62+
# parse the output
63+
parsed_response = json.loads(response.content)
64+
blueprint_names = [blueprint['name'].encode('utf-8') for blueprint in parsed_response]
65+
blueprint_ids = [blueprint['id'].encode('utf-8') for blueprint in parsed_response]
66+
blueprint_dict = dict(zip(blueprint_names, blueprint_ids))
67+
68+
# return a dictionary of blueprints names and their ids
69+
return blueprint_dict
70+
71+
def get_blueprint_id(self, blueprint_name):
72+
"""Return blueprint id, given blueprint name
73+
:param blueprint_name: Name of the blueprint
74+
:return: blueprint_id
75+
"""
76+
77+
# Get all blueprints and see if blueprint_name exists in the list
78+
blueprints = self.get_blueprints()
79+
if blueprint_name not in blueprints.iterkeys():
80+
raise Exception(
81+
'Blueprint "{}" not found, exiting'.format(blueprint_name))
82+
83+
# If exists, return name of blueprint
84+
return blueprints[blueprint_name]
85+
86+
def get_blueprint_details(self, blueprint_id):
87+
"""Returns a dict of the blueprint, given the blueprint id
88+
:param blueprint_id: blueprint_id
89+
:return: dict of name, estimated_setup_duration, description of the blueprint
90+
"""
91+
url_str = '{}{}{}'.format(self.server_address, '/v1/blueprints/', blueprint_id)
92+
response = self._request_and_parse('get', url_str)
93+
parsed_blueprint_details = json.loads(response.content)
94+
return_dict = {'name': parsed_blueprint_details['name'],
95+
'estimated_setup_duration': parsed_blueprint_details['estimated_setup_duration'],
96+
'description': parsed_blueprint_details['description']}
97+
return return_dict
98+
99+
def get_blueprint_details_by_name(self, blueprint_name):
100+
"""Create a sandbox from the provided blueprint name
101+
:param blueprint_name: blueprint name
102+
:return: dict of name, estimated_setup_duration, description of the blueprint
103+
"""
104+
blueprint_id = self.get_blueprint_id(blueprint_name)
105+
return self.get_blueprint_details(blueprint_id)
106+
107+
def start_sandbox(self, blueprint_id, duration, sandbox_name=''):
108+
"""Create a sandbox from the provided blueprint id
109+
:param blueprint_id: blueprint_id
110+
:param duration: duration in minutes
111+
:param sandbox_name: name of the sandbox, same as blueprint if name=''
112+
:return: if success sandbox_id, else False
113+
"""
114+
115+
# Do some parameter validation
116+
try:
117+
int(duration)
118+
except ValueError:
119+
raise Exception('Duration "{}" has to be integer'.format(duration))
120+
121+
duration = 'PT{}M'.format(duration)
122+
if sandbox_name == '':
123+
sandbox_name = self.get_blueprint_details(blueprint_id)['name']
124+
125+
url_str = '{}{}{}/{}'.format(self.server_address, '/v1/blueprints/', blueprint_id, 'start')
126+
data_dict = {"duration": duration, "name": sandbox_name}
127+
response = self._request_and_parse('post', url_str, data_dict=data_dict)
128+
if response.ok:
129+
return json.loads(response.content)['id']
130+
else:
131+
return response.ok
132+
133+
def start_sandbox_by_name(self, blueprint_name, duration, sandbox_name=''):
134+
"""Create a sandbox from the provided blueprint name
135+
:param blueprint_name: blueprint_name
136+
:param duration: duration in minutes
137+
:param sandbox_name: sandbox name
138+
:return: if success sandbox_id, else False
139+
"""
140+
blueprint_id = self.get_blueprint_id(blueprint_name)
141+
if sandbox_name == '':
142+
sandbox_name = blueprint_name
143+
return self.start_sandbox(blueprint_id, duration, sandbox_name)
144+
145+
def get_sandboxes(self):
146+
"""Returns a dictionary of all sandboxes name and their ids
147+
:return: A dict of sandbox ids and names
148+
"""
149+
url_str = '{}{}'.format(self.server_address, '/v1/sandboxes')
150+
response = self._request_and_parse('get', url_str)
151+
152+
# parse the output
153+
parsed_response = json.loads(response.content)
154+
sandbox_names = [sandbox['name'].encode('utf-8') for sandbox in parsed_response]
155+
sandbox_ids = [sandbox['id'].encode('utf-8') for sandbox in parsed_response]
156+
sandbox_dict = dict(zip(sandbox_ids, sandbox_names))
157+
158+
# return a dictionary of sandboxes names and their ids
159+
return sandbox_dict
160+
161+
def get_sandbox_details(self, sandbox_id):
162+
"""Returns a dictionary of the sandbox, its name, type and state
163+
:param sandbox_id: <str> Sandbox id
164+
:return: dictionary of sandbox name, type and state
165+
"""
166+
167+
# Get info from cloudshell
168+
url_str = '{}{}{}'.format(self.server_address, '/v1/sandboxes/', sandbox_id)
169+
response = self._request_and_parse('get', url_str)
170+
171+
# parse the information
172+
parsed_blueprint_details = json.loads(response.content)
173+
174+
# prepare a dictionary to return
175+
return_dict = {'name': parsed_blueprint_details['name'],
176+
'type': parsed_blueprint_details['type'],
177+
'state': parsed_blueprint_details['state']}
178+
return return_dict
179+
180+
def get_sandboxes_details_by_name(self, sandbox_name):
181+
"""
182+
:param sandbox_name: Sandbox name
183+
:return: dictionary of sandbox name, type and state
184+
"""
185+
return_dict = {}
186+
sandbox_ids = self.get_sandbox_ids(sandbox_name)
187+
for sandbox_id in sandbox_ids:
188+
return_dict[sandbox_id] = self.get_sandbox_details(sandbox_id)
189+
return return_dict
190+
191+
def get_sandbox_ids(self, sandbox_name):
192+
"""Returns the sandbox id, given sandbox name
193+
:param sandbox_name: Sandbox name
194+
:return: Sandbox id
195+
"""
196+
sandboxes = self.get_sandboxes()
197+
if sandbox_name not in sandboxes.itervalues():
198+
raise Exception(
199+
'Sandbox "{}" not found, exiting'.format(sandbox_name))
200+
201+
sandbox_ids = [k for k, v in sandboxes.iteritems() if v == sandbox_name]
202+
return sandbox_ids
203+
204+
def stop_sandbox(self, sandbox_id):
205+
"""Stop the sandbox given sandbox id
206+
:param sandbox_id: Sandbox id
207+
:return: True if success, False if not
208+
"""
209+
210+
url_str = '{}{}{}/{}'.format(self.server_address, '/v1/sandboxes/', sandbox_id, 'stop')
211+
response = self._request_and_parse('post', url_str)
212+
return response.ok
213+
214+
def stop_sandboxes_by_name(self, sandbox_name):
215+
"""Stop the sandbox given sandbox name
216+
:param sandbox_name: Sandbox name
217+
:return: True if success, False if not
218+
"""
219+
sandbox_ids = self.get_sandbox_ids(sandbox_name)
220+
for sandbox_id in sandbox_ids:
221+
self.stop_sandbox(sandbox_id)
222+
223+
224+
def main():
225+
usage = """Usage:
226+
# Init vars
227+
blueprint_name = 'Sandbox Python API Test'
228+
sandbox_name = 'Sandbox Python API Test'
229+
config_file = 'quali_config.json'
230+
231+
my_sandbox = Sandbox(config_file=config_file)
232+
233+
my_sandbox.login()
234+
235+
print my_sandbox.get_blueprints()
236+
blueprint_id = my_sandbox.get_blueprint_id(blueprint_name=blueprint_name)
237+
print "Blueprint Id:", blueprint_id
238+
print my_sandbox.get_blueprint_details(blueprint_id=blueprint_id)
239+
print my_sandbox.get_blueprint_details_by_name(blueprint_name=blueprint_name)
240+
241+
print my_sandbox.start_sandbox(blueprint_id=blueprint_id, duration='20', sandbox_name='')
242+
print my_sandbox.start_sandbox_by_name(blueprint_name=blueprint_name, duration='20', sandbox_name='')
243+
print my_sandbox.get_sandboxes()
244+
sandbox_id = my_sandbox.get_sandbox_ids(sandbox_name=sandbox_name)
245+
print sandbox_id
246+
print my_sandbox.get_sandbox_details(sandbox_id=sandbox_id[0])
247+
print my_sandbox.get_sandboxes_details_by_name(sandbox_name=sandbox_name)
248+
print my_sandbox.stop_sandbox(sandbox_id=sandbox_id[0])
249+
print my_sandbox.stop_sandboxes_by_name(sandbox_name=sandbox_name)
250+
"""
251+
252+
print usage
253+
254+
255+
if __name__ == '__main__':
256+
main()
257+
258+
259+
# # Contents of quali_config.json
260+
# {
261+
# "server_name": "localhost",
262+
# "server_port": "82",
263+
# "username": "USERNAME",
264+
# "password": "PASSWORD",
265+
# "domain": "DOMAIN"
266+
# }

__init__.py

Whitespace-only changes.

quali_config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"server_name": "localhost",
3+
"server_port": "82",
4+
"username": "admin",
5+
"password": "admin",
6+
"domain": "Global"
7+
}

0 commit comments

Comments
 (0)