2 # -------------------------------------------------------------------------
3 # Copyright (C) 2020 Wipro Limited.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # -------------------------------------------------------------------------
19 from conductor.common import rest
20 from conductor.data.plugins.inventory_provider.utils import csar
21 from conductor.i18n import _LE
23 from oslo_config import cfg
24 from oslo_log import log
29 LOG = log.getLogger(__name__)
34 cfg.StrOpt('table_prefix',
36 help='Data Store table prefix.'),
37 cfg.StrOpt('server_url',
38 default='https://controller:8443/sdc',
39 help='Base URL for SDC, up to and not including '
40 'the version, and without a trailing slash.'),
41 cfg.StrOpt('sdc_rest_timeout',
43 help='Timeout for SDC Rest Call'),
44 cfg.StrOpt('sdc_retries',
46 help='Number of retry for SDC Rest Call'),
47 cfg.StrOpt('server_url_version',
49 help='The version of SDC in v# format.'),
50 # TODO(larry): follow-up with ONAP people on this (SDC basic auth username and password?)
51 cfg.StrOpt('certificate_file',
52 default='certificate.pem',
53 help='SSL/TLS certificate file in pem format. '
54 'This certificate must be registered with the A&AI '
56 cfg.StrOpt('certificate_key_file',
57 default='certificate_key.pem',
58 help='Private Certificate Key file in pem format.'),
59 cfg.StrOpt('certificate_authority_bundle_file',
61 help='Certificate Authority Bundle file in pem format. '
62 'Must contain the appropriate trust chain for the '
64 cfg.StrOpt('username',
66 help='Username for SDC.'),
67 cfg.StrOpt('password',
69 help='Password for SDC.'),
70 cfg.StrOpt('temp_path',
72 help="path to store nst templates")
75 CONF.register_opts(SDC_OPTS, group='sdc')
79 """SDC Inventory Provider"""
86 self.base = self.conf.sdc.server_url.rstrip('/')
87 self.version = self.conf.sdc.server_url_version.rstrip('/')
88 self.cert = self.conf.sdc.certificate_file
89 self.key = self.conf.sdc.certificate_key_file
90 self.verify = self.conf.sdc.certificate_authority_bundle_file
91 self.timeout = self.conf.sdc.sdc_rest_timeout
92 self.retries = self.conf.sdc.sdc_retries
93 self.username = self.conf.sdc.username
94 self.password = self.conf.sdc.password
95 self._init_python_request()
99 """Perform any late initialization."""
100 # Initialize the Python requests
101 # self._init_python_request()
103 def _sdc_versioned_path(self, path):
104 """Return a URL path with the SDC version prepended"""
105 return '/{}/{}'.format(self.version, path.lstrip('/'))
107 def _request(self, method='get', path='/', data=None,
108 context=None, value=None):
109 """Performs HTTP request."""
111 'X-FromAppId': 'AAI',
112 'X-TransactionId': str(uuid.uuid4()),
113 'X-ECOMP-InstanceID': 'AAI',
120 "content_type": "application/octet-stream"
123 # TODO(jdandrea): Move timing/response logging into the rest helper?
124 start_time = time.time()
125 response = self.rest.request(**kwargs)
126 elapsed = time.time() - start_time
127 LOG.debug("Total time for SDC request "
128 "({0:}: {1:}): {2:.3f} sec".format(context, value, elapsed))
131 LOG.error(_LE("No response from SDC ({}: {})").
132 format(context, value))
133 elif response.status_code != 200:
134 LOG.error(_LE("SDC request ({}: {}) returned HTTP "
135 "status {} {}, link: {}{}").
136 format(context, value,
137 response.status_code, response.reason,
141 def _init_python_request(self):
144 "server_url": self.base,
145 "retries": self.retries,
146 "username": self.username,
147 "password": self.password,
148 "read_timeout": self.timeout,
149 "ca_bundle_file": self.verify,
151 self.rest = rest.REST(**kwargs)
153 def update_candidates(self, candidates):
154 absfilepath = self.conf.sdc.temp_path
156 for candidate in candidates:
157 model_ver_obj = candidate.model_ver_info
158 model_name = model_ver_obj['model_name']
159 self.model_version_id = candidate.candidate_id
160 response = self.get_nst_template(self.model_version_id)
161 filepath = os.path.join(absfilepath, "{}.csar".format(self.model_version_id))
162 if not os.path.exists(absfilepath):
163 os.makedirs(absfilepath)
164 f = open(filepath, "wb")
165 file_res = response.content
167 obj = csar.SDCCSAR(filepath, model_name)
168 nst_temp_prop = obj.validate()
169 nst_properties = self.get_nst_prop_dict(nst_temp_prop)
170 candidate.profile_info = nst_properties
171 finalcandidate = candidate.convert_nested_dict_to_dict()
172 candidateslist.append(finalcandidate)
173 return candidateslist
175 def update_candidates_nsst(self, candidates):
176 absfilepath = self.conf.sdc.temp_path
178 for candidate in candidates:
179 model_ver_obj = candidate.model_ver_info
180 model_name = model_ver_obj['model_name']
181 self.model_version_id = candidate.candidate_id
182 response = self.get_nsst_template(self.model_version_id)
183 filepath = os.path.join(absfilepath, "{}.csar".format(self.model_version_id))
184 if not os.path.exists(absfilepath):
185 os.makedirs(absfilepath)
186 f = open(filepath, "wb")
187 file_res = response.content
189 obj = csar.SDCCSAR(filepath, model_name)
190 nsst_temp_prop = obj.validate()
191 nsst_properties = self.get_nsst_prop_dict(nsst_temp_prop)
192 candidate.profile_info = nsst_properties
193 finalcandidate = candidate.convert_nested_dict_to_dict()
194 candidateslist.append(finalcandidate)
195 return candidateslist
197 def get_nst_prop_dict(self, nst_properties):
198 properties_dict = dict()
199 for key in list(nst_properties):
200 temp_dict = nst_properties[key]
201 for temp_key in list(temp_dict):
202 if "default" in temp_key:
203 properties_dict[key] = temp_dict[temp_key]
204 return properties_dict
206 def get_nsst_prop_dict(self, nsst_properties):
207 properties_dict = dict()
208 for key in list(nsst_properties):
209 temp_dict = nsst_properties[key]
210 for temp_key in list(temp_dict):
211 if "default" in temp_key:
212 properties_dict[key] = temp_dict[temp_key]
213 return properties_dict
215 def get_nst_template(self, ver_id):
216 raw_path = "/catalog/services/{}/toscaModel".format(ver_id)
217 path = self._sdc_versioned_path(raw_path)
218 sdc_response = self._request('get', path, data=None)
219 if sdc_response is None or sdc_response.status_code != 200:
224 def get_nsst_template(self, ver_id):
225 raw_path = "/catalog/services/{}/toscaModel".format(ver_id)
226 path = self._sdc_versioned_path(raw_path)
227 sdc_response = self._request('get', path, data=None)
228 if sdc_response is None or sdc_response.status_code != 200: