[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / openecomp-be / tools / migration / 1607_to_1610.py
1 #!/usr/bin/python
2 import os
3 import sys,json,datetime,time,types,httplib,re
4 import mimetypes
5
6 DEFAULT_HOST = "127.0.0.1"
7 OPENECOMP_BE = "127.0.0.1"
8
9 HOST = DEFAULT_HOST
10 DEFAULT_PORT = "8080"
11 DEFAULT_USERNAME = "cs0008"
12 DEFAULT_PASSWORD = "cs0008"
13
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)
20
21 def main(argv):
22     username=DEFAULT_USERNAME
23     password=DEFAULT_PASSWORD
24     host=DEFAULT_HOST
25
26     if not argv:
27         print "Going to use default values"
28     else:
29         if argv[0].lower() == 'h' or argv[0].lower() == '-h':
30                 printHelp()
31                 return
32
33         if argv[0] == '-ip':
34                 host=argv[1]
35         else:
36                 if argv[0].lower() == '-a' and '/' not in argv[1]:
37                         print '\n>>> Error: Credentials required (username/password)\n'
38                         printHelp()
39                         return
40
41                 else:
42                         creds = argv[1].split('/')
43                         username = creds[0]
44                         password = creds[1] # not used
45
46                 try:
47                         cmdIp=argv[2]
48                         host=argv[3]
49                 except IndexError:
50                         host=DEFAULT_HOST
51         print "Going to use user defined values"
52     Service.server(host)
53
54     webHandler=WebHandler(host=host, port=DEFAULT_PORT)
55     response, headers = webHandler.rest(url=VSP_LIST_PATH, method='GET', data=None, userId=username)
56     jResult = json.loads(response)
57     jSrvices = jResult["results"]
58     reportFileName = 'upgradereport.csv'  #datetime.now()
59     reportFile = open(reportFileName, 'w')
60     reportFile.write(Service.header())
61
62     for jService in jSrvices:
63         serviceName = jService["name"]
64         vendorName = jService["vendorName"]
65         vspId = jService["id"]
66         status = jService["status"]
67         if status != "Locked":
68             lockingUser = "None"
69         else:
70             lockingUser = jService["lockingUser"]
71
72         service = Service(serviceName=serviceName, vspId=vspId, vendorName=vendorName, lockingUser=lockingUser )
73         print service
74         # Will try to GET the service
75         res = service.Get()
76         if res == 500:
77            serviceMigration(service, status, username)
78         else:
79            print "Service {0} was tested and does not need a migration".format(serviceName)
80
81         reportFile.write(service.line())
82     reportFile.close()
83
84
85 def serviceMigration(service, serviceStatus, username):
86         print "Service {0} was tested and it needs a migration".format(service.serviceName)
87         print "Service {0} - Migration start"
88         if serviceStatus == "Locked":
89            print "Service {0} is locked - forcing checkin".format(service.serviceName)
90            service.Checkin()
91         print "Doing new checkout"
92         service.Checkout(username)
93
94         zipName = service.DownloadHeat()
95         if not zipName:
96             print "no heat found"
97             service.uploadStatus = "no heat found"
98         else:
99             uploadResponse = service.UploadHeat(zipName)
100             uploadResults = json.loads(uploadResponse)
101             if uploadResults['status'] == 'Success' and uploadResults['errors'].__len__() == 0:
102                 service.uploadStatus = "Heat uploaded successfully"
103             else:
104                 service.uploadStatus = "Heat uploaded with errors"
105         print "Doing new checkin"
106         service.Checkin()
107
108         print "Service {0} - Migration end"
109
110
111 def  printHelp():
112     print("Upgrade script Help:")
113     print("==================================")
114     print("1607_to_1610 -h                            --> get help")
115     print("1607_to_1610 -a <username>/<password> [-ip {ip}]")
116     print("Example: 1607_to_1610 -a root/secret")
117
118 class Service(object):
119     def __init__(self, serviceName, vspId ,vendorName, lockingUser):
120         self.serviceName = serviceName
121         self.vspId = vspId
122         self.vendorName = vendorName
123         self.lockingUser = lockingUser
124         self.webHandler = WebHandler(host=Service.serveraddress, port=DEFAULT_PORT) # Schema?
125         self.uploadStatus = "not started"
126
127     def __repr__(self):
128         return 'Name: {0}, Id: {1}, Vendor: {2}, locked by: {3}, status {4}'.format(self.serviceName, self.vspId ,self.vendorName, self.lockingUser, self.uploadStatus)
129     @classmethod
130     def header(cls):
131         return 'Name,Id,Vendor,locked-by,status\n'
132
133     @classmethod
134     def server(cls, address):
135         cls.serveraddress=address
136
137     def line(self):
138         return '{0},{1},{2},{3},{4}\n'.format(self.serviceName, self.vspId ,self.vendorName, self.lockingUser, self.uploadStatus)
139
140     def Checkout(self, userId):
141         # /v1.0/vendor-software-products/{vspId}/actions
142         urlpath=VSP_ACTIONS_PATH.format(vspId=self.vspId)
143         response, headers = self.webHandler.rest( url=urlpath, method='PUT', data={"action": "Checkout"}, userId=userId)
144         self.lockingUser=userId #we will later use this user to checkin
145         return response
146
147     def Checkin(self):
148         # /v1.0/vendor-software-products/{vspId}/actions
149         urlpath = VSP_ACTIONS_PATH.format(vspId=self.vspId)
150         response, headers = self.webHandler.rest(url=urlpath, method='PUT', data={"action": "Checkin"}, userId=self.lockingUser)
151         return response
152
153     def Get(self):
154         # /v1.0/vendor-software-products/{vspId}
155         urlpath = VSP_GET_URL.format(vspId=self.vspId)
156         try:
157             response, headers = self.webHandler.rest(url=urlpath, method='GET', data=None, userId=self.lockingUser)
158         except HttpError as e:
159             print e.message
160             response = e.status
161         return response
162
163     def UploadHeat(self, zipName):
164             #/v1.0/vendor-software-products/{vspId}/upload
165             urlpath = VSP_UPLOAD_PATH.format(vspId=self.vspId)
166             try:
167                 fields = []
168                 with open(zipName, 'rb') as fin:
169                     buffer = fin.read()
170                     fin.close()
171                 files = [('upload', 'heatfile.zip', buffer)]
172                 response = self.webHandler.post_multipart('HTTP', urlpath, fields, files, self.lockingUser)
173
174                 return response
175             finally:
176                 print "done upload"
177
178     def DownloadHeat(self):
179         urlpath=VSP_DOWNLOAD_PATH.format(vspId=self.vspId)
180         try:
181             response, headers = self.webHandler.rest(url=urlpath, method='Get', data=None, userId=self.lockingUser, accept='application/octet-stream')
182         except HttpError as e:
183             if e.status == 404:
184                 return ""
185
186         for (key, value) in headers:
187             if key.lower() == "content-disposition":
188                 file_name = value[value.index('=')+1:]
189                 break
190         heatsDir= os.path.join(os.path.dirname(__file__), 'heats')
191         if not os.path.exists(heatsDir):
192             os.makedirs(heatsDir)
193         file_name = os.path.join(heatsDir, file_name)
194         with open(file_name, "wb") as fout:
195             fout.write(response)
196             fout.close()
197
198         return file_name
199
200
201
202 class WebHandler(object):
203     def __init__(self, host, port):
204         self.host = host
205         self.port = port
206
207     def rest(self, url, method, data, userId, accept='application/json', content_type='application/json'):
208         connection = httplib.HTTPConnection(host=self.host, port=self.port)
209
210         try:
211             headers = {'Content-Type':content_type ,'Accept':accept}
212             headers['USER_ID'] = userId
213
214             connection.request(method=method, headers=headers, body=json.dumps(data), url=url)
215             response = connection.getresponse()
216             if response.status not in range(200, 300):
217                 raise HttpError(status= response.status, message=response.reason)
218
219             return response.read(), response.getheaders()
220         finally:
221             connection.close()
222
223     def post_multipart(self, scheme, selector, fields, files, userId):
224         """
225         Post fields and files to an http host as multipart/form-data.
226         fields is a sequence of (name, value) elements for regular form fields.
227         files is a sequence of (name, filename, value) elements for data to be uploaded as files
228         Return the server's response page.
229         """
230         content_type, body = self.encode_multipart_form_data(fields, files)
231         if scheme and scheme.lower() == "http":
232             h = httplib.HTTP(self.host, self.port)
233         else:
234             h = httplib.HTTPS(self.host, self.port)
235         h.putrequest('POST', selector)
236         h.putheader('content-type', content_type)
237         h.putheader('content-length', str(len(body)))
238         h.putheader('Accept', 'application/json')
239         h.putheader('USER_ID', userId)
240
241         h.endheaders()
242         h.send(body)
243         errcode, errmsg, headers = h.getreply()
244         print errcode, errmsg, headers
245         return h.file.read()
246
247     def encode_multipart_form_data(self, fields, files):
248         LIMIT = '----------lImIt_of_THE_fIle_eW_$'
249         CRLF = '\r\n'
250         L = []
251         for (key, value) in fields:
252             L.append('--' + LIMIT)
253             L.append('Content-Disposition: form-data; name="%s"' % key)
254             L.append('')
255             L.append(value)
256         for (key, filename, value) in files:
257             L.append('--' + LIMIT)
258             L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
259             L.append('Content-Type: %s' % self.get_content_type(filename))
260             L.append('')
261             L.append(value)
262         L.append('--' + LIMIT + '--')
263         L.append('')
264         body = CRLF.join(L)
265         content_type = 'multipart/form-data; boundary=%s' % LIMIT
266         return content_type, body
267
268     def get_content_type(self, filename):
269         return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
270
271 class HttpError(Exception):
272     def __init__(self, status, message):
273         self.status = status
274         self.message=message
275     def __str__(self):
276         return repr(self.value, self.message)
277
278 if __name__ == "__main__":
279     main(sys.argv[1:])
280
281