3 import sys, json, datetime, time, types, httplib, re
6 DEFAULT_HOST = "127.0.0.1"
7 OPENECOMP_BE = "127.0.0.1"
11 DEFAULT_USERNAME = "cs0008"
12 DEFAULT_PASSWORD = "cs0008"
14 ONBOARD_BASE_PATH = "/onboarding-api/v1.0"
15 VSP_LIST_PATH = "{0}/vendor-software-products".format(ONBOARD_BASE_PATH)
16 VSP_ACTIONS_PATH = "{0}/vendor-software-products/{{vspId}}/actions".format(ONBOARD_BASE_PATH)
17 VSP_UPLOAD_PATH = "{0}/vendor-software-products/{{vspId}}/upload".format(ONBOARD_BASE_PATH)
18 VSP_DOWNLOAD_PATH = "{0}/vendor-software-products/{{vspId}}/downloadHeat".format(ONBOARD_BASE_PATH)
19 VSP_GET_URL = "{0}/vendor-software-products/{{vspId}}".format(ONBOARD_BASE_PATH)
23 username = DEFAULT_USERNAME
24 password = DEFAULT_PASSWORD
28 print("Going to use default values")
30 if argv[0].lower() == 'h' or argv[0].lower() == '-h':
37 if argv[0].lower() == '-a' and '/' not in argv[1]:
38 print('\n>>> Error: Credentials required (username/password)\n')
43 creds = argv[1].split('/')
45 password = creds[1] # not used
52 print("Going to use user defined values")
55 webHandler = WebHandler(host=host, port=DEFAULT_PORT)
56 response, headers = webHandler.rest(url=VSP_LIST_PATH, method='GET', data=None, userId=username)
57 jResult = json.loads(response)
58 jSrvices = jResult["results"]
59 reportFileName = 'upgradereport.csv' # datetime.now()
60 reportFile = open(reportFileName, 'w')
61 reportFile.write(Service.header())
63 for jService in jSrvices:
64 serviceName = jService["name"]
65 vendorName = jService["vendorName"]
66 vspId = jService["id"]
67 status = jService["status"]
68 if status != "Locked":
71 lockingUser = jService["lockingUser"]
73 service = Service(serviceName=serviceName, vspId=vspId, vendorName=vendorName, lockingUser=lockingUser)
75 # Will try to GET the service
78 serviceMigration(service, status, username)
80 print("Service {0} was tested and does not need a migration".format(serviceName))
82 reportFile.write(service.line())
86 def serviceMigration(service, serviceStatus, username):
87 print("Service {0} was tested and it needs a migration".format(service.serviceName))
88 print("Service {0} - Migration start")
89 if serviceStatus == "Locked":
90 print("Service {0} is locked - forcing checkin".format(service.serviceName))
92 print("Doing new checkout")
93 service.Checkout(username)
95 zipName = service.DownloadHeat()
97 print("no heat found")
98 service.uploadStatus = "no heat found"
100 uploadResponse = service.UploadHeat(zipName)
101 uploadResults = json.loads(uploadResponse)
102 if uploadResults['status'] == 'Success' and uploadResults['errors'].__len__() == 0:
103 service.uploadStatus = "Heat uploaded successfully"
105 service.uploadStatus = "Heat uploaded with errors"
106 print("Doing new checkin")
109 print("Service {0} - Migration end")
113 print("Upgrade script Help:")
114 print("==================================")
115 print("1607_to_1610 -h --> get help")
116 print("1607_to_1610 -a <username>/<password> [-ip {ip}]")
117 print("Example: 1607_to_1610 -a root/secret")
120 class Service(object):
121 def __init__(self, serviceName, vspId, vendorName, lockingUser):
122 self.serviceName = serviceName
124 self.vendorName = vendorName
125 self.lockingUser = lockingUser
126 self.webHandler = WebHandler(host=Service.serveraddress, port=DEFAULT_PORT) # Schema?
127 self.uploadStatus = "not started"
130 return 'Name: {0}, Id: {1}, Vendor: {2}, locked by: {3}, status {4}'.format(self.serviceName, self.vspId,
131 self.vendorName, self.lockingUser,
136 return 'Name,Id,Vendor,locked-by,status\n'
139 def server(cls, address):
140 cls.serveraddress = address
143 return '{0},{1},{2},{3},{4}\n'.format(self.serviceName, self.vspId, self.vendorName, self.lockingUser,
146 def Checkout(self, userId):
147 # /v1.0/vendor-software-products/{vspId}/actions
148 urlpath = VSP_ACTIONS_PATH.format(vspId=self.vspId)
149 response, headers = self.webHandler.rest(url=urlpath, method='PUT', data={"action": "Checkout"}, userId=userId)
150 self.lockingUser = userId # we will later use this user to checkin
154 # /v1.0/vendor-software-products/{vspId}/actions
155 urlpath = VSP_ACTIONS_PATH.format(vspId=self.vspId)
156 response, headers = self.webHandler.rest(url=urlpath, method='PUT', data={"action": "Checkin"},
157 userId=self.lockingUser)
161 # /v1.0/vendor-software-products/{vspId}
162 urlpath = VSP_GET_URL.format(vspId=self.vspId)
164 response, headers = self.webHandler.rest(url=urlpath, method='GET', data=None, userId=self.lockingUser)
165 except HttpError as e:
170 def UploadHeat(self, zipName):
171 # /v1.0/vendor-software-products/{vspId}/upload
172 urlpath = VSP_UPLOAD_PATH.format(vspId=self.vspId)
175 with open(zipName, 'rb') as fin:
178 files = [('upload', 'heatfile.zip', buffer)]
179 response = self.webHandler.post_multipart('HTTP', urlpath, fields, files, self.lockingUser)
185 def DownloadHeat(self):
186 urlpath = VSP_DOWNLOAD_PATH.format(vspId=self.vspId)
188 response, headers = self.webHandler.rest(url=urlpath, method='Get', data=None, userId=self.lockingUser,
189 accept='application/octet-stream')
190 except HttpError as e:
194 for (key, value) in headers:
195 if key.lower() == "content-disposition":
196 file_name = value[value.index('=') + 1:]
198 heatsDir = os.path.join(os.path.dirname(__file__), 'heats')
199 if not os.path.exists(heatsDir):
200 os.makedirs(heatsDir)
201 file_name = os.path.join(heatsDir, file_name)
202 with open(file_name, "wb") as fout:
209 class WebHandler(object):
210 def __init__(self, host, port):
214 def rest(self, url, method, data, userId, accept='application/json', content_type='application/json'):
215 connection = httplib.HTTPConnection(host=self.host, port=self.port)
218 headers = {'Content-Type': content_type, 'Accept': accept}
219 headers['USER_ID'] = userId
221 connection.request(method=method, headers=headers, body=json.dumps(data), url=url)
222 response = connection.getresponse()
223 if response.status not in range(200, 300):
224 raise HttpError(status=response.status, message=response.reason)
226 return response.read(), response.getheaders()
230 def post_multipart(self, scheme, selector, fields, files, userId):
232 Post fields and files to an http host as multipart/form-data.
233 fields is a sequence of (name, value) elements for regular form fields.
234 files is a sequence of (name, filename, value) elements for data to be uploaded as files
235 Return the server's response page.
237 content_type, body = self.encode_multipart_form_data(fields, files)
238 if scheme and scheme.lower() == "http":
239 h = httplib.HTTP(self.host, self.port)
241 h = httplib.HTTPS(self.host, self.port)
242 h.putrequest('POST', selector)
243 h.putheader('content-type', content_type)
244 h.putheader('content-length', str(len(body)))
245 h.putheader('Accept', 'application/json')
246 h.putheader('USER_ID', userId)
250 errcode, errmsg, headers = h.getreply()
251 print(errcode, errmsg, headers)
254 def encode_multipart_form_data(self, fields, files):
255 LIMIT = '----------lImIt_of_THE_fIle_eW_$'
258 for (key, value) in fields:
259 L.append('--' + LIMIT)
260 L.append('Content-Disposition: form-data; name="%s"' % key)
263 for (key, filename, value) in files:
264 L.append('--' + LIMIT)
265 L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
266 L.append('Content-Type: %s' % self.get_content_type(filename))
269 L.append('--' + LIMIT + '--')
272 content_type = 'multipart/form-data; boundary=%s' % LIMIT
273 return content_type, body
275 def get_content_type(self, filename):
276 return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
279 class HttpError(Exception):
280 def __init__(self, status, message):
282 self.message = message
285 return repr(self.value, self.message)
288 if __name__ == "__main__":