c839f611e842bd8583f2b7d7f76c2233610c2957
[multicloud/framework.git] / multivimbroker / multivimbroker / pub / utils / restcall.py
1 # Copyright (c) 2017 Wind River Systems, Inc.
2 # Copyright (c) 2017-2018 VMware, Inc.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #       http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
13 import sys
14 import traceback
15 import logging
16 import urllib2
17 import uuid
18 import httplib2
19
20 from multivimbroker.pub.config.config import AAI_SCHEMA_VERSION
21 from multivimbroker.pub.config.config import AAI_SERVICE_URL
22 from multivimbroker.pub.config.config import AAI_USERNAME
23 from multivimbroker.pub.config.config import AAI_PASSWORD
24 from multivimbroker.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
25
26 rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
27 HTTP_200_OK, HTTP_201_CREATED = '200', '201'
28 HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '204', '202'
29 status_ok_list = [HTTP_200_OK, HTTP_201_CREATED,
30                   HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED]
31 HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN = '404', '403'
32 HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '401', '400'
33
34 logger = logging.getLogger(__name__)
35
36
37 def call_multipart_req(base_url, user, passwd, auth_type, resource, method,
38                        content, headers=None):
39     callid = str(uuid.uuid1())
40 #    logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
41 #    callid, base_url, user, passwd, auth_type, resource, method, content))
42     ret = None
43     resp = ""
44     full_url = ""
45
46     try:
47         full_url = combine_url(base_url, resource)
48         logger.debug("request=%s)" % full_url)
49         requestObj = urllib2.Request(full_url, content,
50                                      headers)
51         resp = urllib2.urlopen(requestObj)
52         if resp.code in status_ok_list:
53             ret = [0, resp.read(), resp.code, resp]
54         else:
55             ret = [1, resp.read(), resp.code, resp]
56     except urllib2.URLError as err:
57         ret = [2, str(err), resp.code, resp]
58     except Exception:
59         logger.error(traceback.format_exc())
60         logger.error("[%s]ret=%s" % (callid, str(sys.exc_info())))
61         res_info = str(sys.exc_info())
62         ret = [3, res_info, 500, resp]
63     return ret
64
65
66 def call_req(base_url, user, passwd, auth_type, resource, method,
67              content='', headers=None):
68     callid = str(uuid.uuid1())
69 #    logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
70 #    callid, base_url, user, passwd, auth_type, resource, method, content))
71     ret = None
72     resp_status = ''
73     resp = ""
74     full_url = ""
75
76     try:
77         full_url = combine_url(base_url, resource)
78         if headers is None:
79             headers = {}
80             headers['content-type'] = 'application/json'
81
82         if user:
83             headers['Authorization'] = 'Basic ' + \
84                 ('%s:%s' % (user, passwd)).encode("base64")
85         ca_certs = None
86         for retry_times in range(3):
87             http = httplib2.Http(
88                 ca_certs=ca_certs,
89                 disable_ssl_certificate_validation=(
90                     auth_type == rest_no_auth))
91             http.follow_all_redirects = True
92             try:
93                 logger.debug("request=%s)" % full_url)
94                 resp, resp_content = http.request(
95                     full_url, method=method.upper(),
96                     body=content, headers=headers)
97                 resp_status, resp_body = resp['status'], resp_content.decode(
98                     'UTF-8')
99
100                 if resp_status in status_ok_list:
101                     ret = [0, resp_body, resp_status, resp]
102                 else:
103                     ret = [1, resp_body, resp_status, resp]
104                 break
105             except Exception as ex:
106                 if 'httplib.ResponseNotReady' in str(sys.exc_info()):
107                     logger.error(traceback.format_exc())
108                     ret = [1, "Unable to connect to %s" %
109                            full_url, resp_status, resp]
110                     continue
111                 raise ex
112     except urllib2.URLError as err:
113         ret = [2, str(err), resp_status, resp]
114     except Exception:
115         logger.error(traceback.format_exc())
116         logger.error("[%s]ret=%s" % (callid, str(sys.exc_info())))
117         res_info = str(sys.exc_info())
118         if 'httplib.ResponseNotReady' in res_info:
119             res_info = "The URL[%s] request \
120             failed or is not responding." % full_url
121         ret = [3, res_info, resp_status, resp]
122
123 #    logger.debug("[%s]ret=%s" % (callid, str(ret)))
124     return ret
125
126
127 def req_by_msb(resource, method, content='', headers=None):
128     base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT)
129     return call_req(base_url, "", "",
130                     rest_no_auth, resource, method, content, headers)
131
132
133 def req_by_msb_multipart(resource, method, content, headers=None):
134     base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT)
135     return call_multipart_req(base_url, "", "",
136                               rest_no_auth, resource, method, content, headers)
137
138
139 def get_res_from_aai(resource, content=''):
140     headers = {
141         'X-FromAppId': 'MultiCloud',
142         'X-TransactionId': '9001',
143         'content-type': 'application/json',
144         'accept': 'application/json'
145     }
146     base_url = "%s/%s" % (AAI_SERVICE_URL, AAI_SCHEMA_VERSION)
147     return call_req(base_url, AAI_USERNAME, AAI_PASSWORD, rest_no_auth,
148                     resource, "GET", content, headers)
149
150
151 def combine_url(base_url, resource):
152     full_url = None
153     if base_url.endswith('/') and resource.startswith('/'):
154         full_url = base_url[:-1] + resource
155     elif base_url.endswith('/') and not resource.startswith('/'):
156         full_url = base_url + resource
157     elif not base_url.endswith('/') and resource.startswith('/'):
158         full_url = base_url + resource
159     else:
160         full_url = base_url + '/' + resource
161     return full_url