Merge branch 'master' into Azure
[osm/RO.git] / osm_ro / openmanoclient.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 ##
5 # Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
6 # This file is part of openmano
7 # All Rights Reserved.
8 #
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
12 #
13 # http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
19 # under the License.
20 #
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact with: nfvlabs@tid.es
23 ##
24
25 """
26 openmano python client used to interact with openmano-server
27 """
28
29 import requests
30 import json
31 import yaml
32 import logging
33 import sys
34
35 __author__ = "Alfonso Tierno, Pablo Montes"
36 __date__ = "$09-Mar-2016 09:09:48$"
37 __version__ = "0.1.0-r470"
38 version_date = "Oct 2017"
39
40 if sys.version_info.major == 3:
41 from urllib.parse import quote
42 elif sys.version_info.major == 2:
43 from urllib import quote
44
45 class OpenmanoException(Exception):
46 '''Common Exception for all openmano client exceptions'''
47
48 class OpenmanoBadParamsException(OpenmanoException):
49 '''Bad or missing input parameters'''
50
51 class OpenmanoResponseException(OpenmanoException):
52 '''Unexpected response from openmano server'''
53
54 class OpenmanoNotFoundException(OpenmanoException):
55 '''Not found at server'''
56
57 # class vnf():
58 # def __init__(self, message):
59 # print "Error: %s" %message
60 # print
61 # self.print_usage()
62 # #self.print_help()
63 # print
64 # print "Type 'openmano -h' for help"
65
66 class openmanoclient():
67 headers_req = {'Accept': 'application/yaml', 'content-type': 'application/yaml'}
68
69 def __init__(self, **kwargs):
70 self.username = kwargs.get("username")
71 self.password = kwargs.get("password")
72 self.endpoint_url = kwargs.get("endpoint_url")
73 self.tenant_id = kwargs.get("tenant_id")
74 self.tenant_name = kwargs.get("tenant_name")
75 self.tenant = None
76 self.datacenter_id = kwargs.get("datacenter_id")
77 self.datacenter_name = kwargs.get("datacenter_name")
78 self.datacenter = None
79 self.logger = logging.getLogger(kwargs.get('logger','manoclient'))
80 if kwargs.get("debug"):
81 self.logger.setLevel(logging.DEBUG)
82
83 def __getitem__(self, index):
84 if index=='tenant_name':
85 return self.tenant_name
86 elif index=='tenant_id':
87 return self.tenant_id
88 elif index=='datacenter_name':
89 return self.datacenter_name
90 elif index=='datacenter_id':
91 return self.datacenter_id
92 elif index=='username':
93 return self.username
94 elif index=='password':
95 return self.password
96 elif index=='endpoint_url':
97 return self.endpoint_url
98 else:
99 raise KeyError("Invalid key '%s'" %str(index))
100
101 def __setitem__(self,index, value):
102 if index=='tenant_name':
103 self.tenant_name = value
104 elif index=='tenant_id':
105 self.tenant_id = value
106 elif index=='datacenter_name':
107 self.datacenter_name = value
108 elif index=='datacenter_id':
109 self.datacenter_id = value
110 elif index=='username':
111 self.username = value
112 elif index=='password':
113 self.password = value
114 elif index=='endpoint_url':
115 self.endpoint_url = value
116 else:
117 raise KeyError("Invalid key '%s'" %str(index))
118 self.tenant = None # force to reload tenant with different credentials
119 self.datacenter = None # force to reload datacenter with different credentials
120
121 def _parse(self, descriptor, descriptor_format, response=False):
122 #try yaml
123 if descriptor_format and descriptor_format != "json" and descriptor_format != "yaml":
124 raise OpenmanoBadParamsException("'descriptor_format' must be a 'json' or 'yaml' text")
125 if descriptor_format != "json":
126 try:
127 return yaml.load(descriptor)
128 except yaml.YAMLError as exc:
129 error_pos = ""
130 if hasattr(exc, 'problem_mark'):
131 mark = exc.problem_mark
132 error_pos = " at line:{} column:{}s".format(mark.line+1, mark.column+1)
133 error_text = "yaml format error" + error_pos
134 elif descriptor_format != "yaml":
135 try:
136 return json.loads(descriptor)
137 except Exception as e:
138 if response:
139 error_text = "json format error" + str(e)
140
141 if response:
142 raise OpenmanoResponseException(error_text)
143 raise OpenmanoBadParamsException(error_text)
144
145 def _parse_yaml(self, descriptor, response=False):
146 try:
147 return yaml.load(descriptor)
148 except yaml.YAMLError as exc:
149 error_pos = ""
150 if hasattr(exc, 'problem_mark'):
151 mark = exc.problem_mark
152 error_pos = " at line:{} column:{}s".format(mark.line+1, mark.column+1)
153 error_text = "yaml format error" + error_pos
154 if response:
155 raise OpenmanoResponseException(error_text)
156 raise OpenmanoBadParamsException(error_text)
157
158
159 def _get_item_uuid(self, item, item_id=None, item_name=None, all_tenants=False):
160 if all_tenants == None:
161 tenant_text = ""
162 elif all_tenants == False:
163 tenant_text = "/" + self.tenant
164 else:
165 tenant_text = "/any"
166 URLrequest = "{}{}/{}".format(self.endpoint_url, tenant_text, item)
167 self.logger.debug("GET %s", URLrequest )
168 mano_response = requests.get(URLrequest, headers=self.headers_req)
169 self.logger.debug("openmano response: %s", mano_response.text )
170 content = self._parse_yaml(mano_response.text, response=True)
171 #print content
172 found = 0
173 if not item_id and not item_name:
174 raise OpenmanoResponseException("Missing either {0}_name or {0}_id".format(item[:-1]))
175 for i in content[item]:
176 if item_id and i["uuid"] == item_id:
177 return item_id
178 elif item_name and i["name"] == item_name:
179 uuid = i["uuid"]
180 found += 1
181
182 if found == 0:
183 if item_id:
184 raise OpenmanoNotFoundException("No {} found with id '{}'".format(item[:-1], item_id))
185 else:
186 #print(item, item_name)
187 raise OpenmanoNotFoundException("No {} found with name '{}'".format(item[:-1], item_name) )
188 elif found > 1:
189 raise OpenmanoNotFoundException("{} {} found with name '{}'. uuid must be used".format(found, item, item_name))
190 return uuid
191
192 def _get_item(self, item, uuid=None, name=None, all_tenants=False):
193 if all_tenants:
194 tenant_text = "/any"
195 elif all_tenants==None:
196 tenant_text = ""
197 else:
198 tenant_text = "/"+self._get_tenant()
199 if not uuid:
200 #check that exist
201 uuid = self._get_item_uuid(item, uuid, name, all_tenants)
202
203 URLrequest = "{}{}/{}/{}".format(self.endpoint_url, tenant_text, item, uuid)
204 self.logger.debug("GET %s", URLrequest )
205 mano_response = requests.get(URLrequest, headers=self.headers_req)
206 self.logger.debug("openmano response: %s", mano_response.text )
207
208 content = self._parse_yaml(mano_response.text, response=True)
209 if mano_response.status_code==200:
210 return content
211 else:
212 raise OpenmanoResponseException(str(content))
213
214 def _get_tenant(self):
215 if not self.tenant:
216 self.tenant = self._get_item_uuid("tenants", self.tenant_id, self.tenant_name, None)
217 return self.tenant
218
219 def _get_datacenter(self):
220 if not self.tenant:
221 self._get_tenant()
222 if not self.datacenter:
223 self.datacenter = self._get_item_uuid("datacenters", self.datacenter_id, self.datacenter_name, False)
224 return self.datacenter
225
226 def _create_item(self, item, descriptor, all_tenants=False, api_version=None):
227 if all_tenants:
228 tenant_text = "/any"
229 elif all_tenants is None:
230 tenant_text = ""
231 else:
232 tenant_text = "/"+self._get_tenant()
233 payload_req = yaml.safe_dump(descriptor)
234
235 api_version_text = ""
236 if api_version:
237 api_version_text = "/v3"
238
239 #print payload_req
240
241 URLrequest = "{}{apiver}{tenant}/{item}".format(self.endpoint_url, apiver=api_version_text, tenant=tenant_text,
242 item=item)
243 self.logger.debug("openmano POST %s %s", URLrequest, payload_req)
244 mano_response = requests.post(URLrequest, headers=self.headers_req, data=payload_req)
245 self.logger.debug("openmano response: %s", mano_response.text)
246
247 content = self._parse_yaml(mano_response.text, response=True)
248 if mano_response.status_code == 200:
249 return content
250 else:
251 raise OpenmanoResponseException(str(content))
252
253 def _del_item(self, item, uuid=None, name=None, all_tenants=False):
254 if all_tenants:
255 tenant_text = "/any"
256 elif all_tenants==None:
257 tenant_text = ""
258 else:
259 tenant_text = "/"+self._get_tenant()
260 if not uuid:
261 #check that exist
262 uuid = self._get_item_uuid(item, uuid, name, all_tenants)
263
264 URLrequest = "{}{}/{}/{}".format(self.endpoint_url, tenant_text, item, uuid)
265 self.logger.debug("DELETE %s", URLrequest )
266 mano_response = requests.delete(URLrequest, headers = self.headers_req)
267 self.logger.debug("openmano response: %s", mano_response.text )
268
269 content = self._parse_yaml(mano_response.text, response=True)
270 if mano_response.status_code==200:
271 return content
272 else:
273 raise OpenmanoResponseException(str(content))
274
275 def _list_item(self, item, all_tenants=False, filter_dict=None):
276 if all_tenants:
277 tenant_text = "/any"
278 elif all_tenants==None:
279 tenant_text = ""
280 else:
281 tenant_text = "/"+self._get_tenant()
282
283 URLrequest = "{}{}/{}".format(self.endpoint_url, tenant_text, item)
284 separator="?"
285 if filter_dict:
286 for k in filter_dict:
287 URLrequest += separator + quote(str(k)) + "=" + quote(str(filter_dict[k]))
288 separator = "&"
289 self.logger.debug("openmano GET %s", URLrequest)
290 mano_response = requests.get(URLrequest, headers=self.headers_req)
291 self.logger.debug("openmano response: %s", mano_response.text )
292
293 content = self._parse_yaml(mano_response.text, response=True)
294 if mano_response.status_code==200:
295 return content
296 else:
297 raise OpenmanoResponseException(str(content))
298
299 def _edit_item(self, item, descriptor, uuid=None, name=None, all_tenants=False):
300 if all_tenants:
301 tenant_text = "/any"
302 elif all_tenants==None:
303 tenant_text = ""
304 else:
305 tenant_text = "/"+self._get_tenant()
306
307 if not uuid:
308 #check that exist
309 uuid = self._get_item_uuid("tenants", uuid, name, all_tenants)
310
311 payload_req = yaml.safe_dump(descriptor)
312
313 #print payload_req
314
315 URLrequest = "{}{}/{}/{}".format(self.endpoint_url, tenant_text, item, uuid)
316 self.logger.debug("openmano PUT %s %s", URLrequest, payload_req)
317 mano_response = requests.put(URLrequest, headers = self.headers_req, data=payload_req)
318 self.logger.debug("openmano response: %s", mano_response.text )
319
320 content = self._parse_yaml(mano_response.text, response=True)
321 if mano_response.status_code==200:
322 return content
323 else:
324 raise OpenmanoResponseException(str(content))
325
326 #TENANTS
327 def list_tenants(self, **kwargs):
328 '''Obtain a list of tenants
329 Params: can be filtered by 'uuid','name','description'
330 Return: Raises an exception on error
331 Obtain a dictionary with format {'tenants':[{tenant1_info},{tenant2_info},...]}}
332 '''
333 return self._list_item("tenants", all_tenants=None, filter_dict=kwargs)
334
335 def get_tenant(self, uuid=None, name=None):
336 '''Obtain the information of a tenant
337 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
338 Return: Raises an exception on error, not found, found several
339 Obtain a dictionary with format {'tenant':{tenant_info}}
340 '''
341 return self._get_item("tenants", uuid, name, all_tenants=None)
342
343 def delete_tenant(self, uuid=None, name=None):
344 '''Delete a tenant
345 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
346 Return: Raises an exception on error, not found, found several
347 Obtain a dictionary with format {'result': text indicating deleted}
348 '''
349 return self._del_item("tenants", uuid, name, all_tenants=None)
350
351 def create_tenant(self, descriptor=None, descriptor_format=None, name=None, description=None):
352 '''Creates a tenant
353 Params: must supply a descriptor or/and just a name
354 descriptor: with format {'tenant':{new_tenant_info}}
355 newtenant_info must contain 'name', and optionally 'description'
356 must be a dictionary or a json/yaml text.
357 name: the tenant name. Overwrite descriptor name if any
358 description: tenant descriptor.. Overwrite descriptor description if any
359 Return: Raises an exception on error
360 Obtain a dictionary with format {'tenant':{new_tenant_info}}
361 '''
362 if isinstance(descriptor, str):
363 descriptor = self._parse(descriptor, descriptor_format)
364 elif descriptor:
365 pass
366 elif name:
367 descriptor={"tenant": {"name": name}}
368 else:
369 raise OpenmanoBadParamsException("Missing descriptor")
370
371 if 'tenant' not in descriptor or len(descriptor)!=1:
372 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
373 if name:
374 descriptor['tenant']['name'] = name
375 if description:
376 descriptor['tenant']['description'] = description
377
378 return self._create_item("tenants", descriptor, all_tenants=None)
379
380 def edit_tenant(self, uuid=None, name=None, descriptor=None, descriptor_format=None, new_name=None, new_description=None):
381 '''Edit the parameters of a tenant
382 Params: must supply a descriptor or/and a new_name or new_description
383 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
384 descriptor: with format {'tenant':{params to change info}}
385 must be a dictionary or a json/yaml text.
386 name: the tenant name. Overwrite descriptor name if any
387 description: tenant descriptor.. Overwrite descriptor description if any
388 Return: Raises an exception on error, not found or found several
389 Obtain a dictionary with format {'tenant':{newtenant_info}}
390 '''
391
392 if isinstance(descriptor, str):
393 descriptor = self.parse(descriptor, descriptor_format)
394 elif descriptor:
395 pass
396 elif new_name or new_description:
397 descriptor={"tenant": {}}
398 else:
399 raise OpenmanoBadParamsException("Missing descriptor")
400
401 if 'tenant' not in descriptor or len(descriptor)!=1:
402 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
403 if new_name:
404 descriptor['tenant']['name'] = new_name
405 if new_description:
406 descriptor['tenant']['description'] = new_description
407
408 return self._edit_item("tenants", descriptor, uuid, name, all_tenants=None)
409
410 #DATACENTERS
411
412 def list_datacenters(self, all_tenants=False, **kwargs):
413 '''Obtain a list of datacenters, that are the VIM information at openmano
414 Params: can be filtered by 'uuid','name','vim_url','type'
415 Return: Raises an exception on error
416 Obtain a dictionary with format {'datacenters':[{datacenter1_info},{datacenter2_info},...]}}
417 '''
418 return self._list_item("datacenters", all_tenants, filter_dict=kwargs)
419
420 def get_datacenter(self, uuid=None, name=None, all_tenants=False):
421 '''Obtain the information of a datacenter
422 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
423 Return: Raises an exception on error, not found, found several
424 Obtain a dictionary with format {'datacenter':{datacenter_info}}
425 '''
426 return self._get_item("datacenters", uuid, name, all_tenants)
427
428 def delete_datacenter(self, uuid=None, name=None):
429 '''Delete a datacenter
430 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
431 Return: Raises an exception on error, not found, found several, not free
432 Obtain a dictionary with format {'result': text indicating deleted}
433 '''
434 if not uuid:
435 # check that exist
436 uuid = self._get_item_uuid("datacenters", uuid, name, all_tenants=True)
437 return self._del_item("datacenters", uuid, name, all_tenants=None)
438
439 def create_datacenter(self, descriptor=None, descriptor_format=None, name=None, vim_url=None, **kwargs):
440 #, type="openvim", public=False, description=None):
441 '''Creates a datacenter
442 Params: must supply a descriptor or/and just a name and vim_url
443 descriptor: with format {'datacenter':{new_datacenter_info}}
444 newdatacenter_info must contain 'name', 'vim_url', and optionally 'description'
445 must be a dictionary or a json/yaml text.
446 name: the datacenter name. Overwrite descriptor name if any
447 vim_url: the datacenter URL. Overwrite descriptor vim_url if any
448 vim_url_admin: the datacenter URL for administrative issues. Overwrite descriptor vim_url if any
449 vim_type: the datacenter type, can be openstack or openvim. Overwrite descriptor type if any
450 public: boolean, by default not public
451 description: datacenter description. Overwrite descriptor description if any
452 config: dictionary with extra configuration for the concrete datacenter
453 Return: Raises an exception on error
454 Obtain a dictionary with format {'datacenter':{new_datacenter_info}}
455 '''
456 if isinstance(descriptor, str):
457 descriptor = self.parse(descriptor, descriptor_format)
458 elif descriptor:
459 pass
460 elif name and vim_url:
461 descriptor={"datacenter": {"name": name, "vim_url": vim_url}}
462 else:
463 raise OpenmanoBadParamsException("Missing descriptor, or name and vim_url")
464
465 if 'datacenter' not in descriptor or len(descriptor)!=1:
466 raise OpenmanoBadParamsException("Descriptor must contain only one 'datacenter' field")
467 if name:
468 descriptor['datacenter']['name'] = name
469 if vim_url:
470 descriptor['datacenter']['vim_url'] = vim_url
471 for param in kwargs:
472 descriptor['datacenter'][param] = kwargs[param]
473
474 return self._create_item("datacenters", descriptor, all_tenants=None)
475
476 def edit_datacenter(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, **kwargs):
477 '''Edit the parameters of a datacenter
478 Params: must supply a descriptor or/and a parameter to change
479 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
480 descriptor: with format {'datacenter':{params to change info}}
481 must be a dictionary or a json/yaml text.
482 parameters to change can be supplyied by the descriptor or as parameters:
483 new_name: the datacenter name
484 vim_url: the datacenter URL
485 vim_url_admin: the datacenter URL for administrative issues
486 vim_type: the datacenter type, can be openstack or openvim.
487 public: boolean, available to other tenants
488 description: datacenter description
489 Return: Raises an exception on error, not found or found several
490 Obtain a dictionary with format {'datacenter':{new_datacenter_info}}
491 '''
492
493 if isinstance(descriptor, str):
494 descriptor = self.parse(descriptor, descriptor_format)
495 elif descriptor:
496 pass
497 elif kwargs:
498 descriptor={"datacenter": {}}
499 else:
500 raise OpenmanoBadParamsException("Missing descriptor")
501
502 if 'datacenter' not in descriptor or len(descriptor)!=1:
503 raise OpenmanoBadParamsException("Descriptor must contain only one 'datacenter' field")
504 for param in kwargs:
505 if param=='new_name':
506 descriptor['datacenter']['name'] = kwargs[param]
507 else:
508 descriptor['datacenter'][param] = kwargs[param]
509 return self._edit_item("datacenters", descriptor, uuid, name, all_tenants=None)
510
511 def attach_datacenter(self, uuid=None, name=None, descriptor=None, descriptor_format=None, vim_user=None, vim_password=None, vim_tenant_name=None, vim_tenant_id=None):
512 #check that exist
513 uuid = self._get_item_uuid("datacenters", uuid, name, all_tenants=True)
514 tenant_text = "/"+self._get_tenant()
515
516 if isinstance(descriptor, str):
517 descriptor = self.parse(descriptor, descriptor_format)
518 elif descriptor:
519 pass
520 elif vim_user or vim_password or vim_tenant_name or vim_tenant_id:
521 descriptor={"datacenter": {}}
522 else:
523 raise OpenmanoBadParamsException("Missing descriptor or params")
524
525 if vim_user or vim_password or vim_tenant_name or vim_tenant_id:
526 #print args.name
527 try:
528 if vim_user:
529 descriptor['datacenter']['vim_user'] = vim_user
530 if vim_password:
531 descriptor['datacenter']['vim_password'] = vim_password
532 if vim_tenant_name:
533 descriptor['datacenter']['vim_tenant_name'] = vim_tenant_name
534 if vim_tenant_id:
535 descriptor['datacenter']['vim_tenant'] = vim_tenant_id
536 except (KeyError, TypeError) as e:
537 if str(e)=='datacenter': error_pos= "missing field 'datacenter'"
538 else: error_pos="wrong format"
539 raise OpenmanoBadParamsException("Wrong datacenter descriptor: " + error_pos)
540
541 payload_req = yaml.safe_dump(descriptor)
542 #print payload_req
543 URLrequest = "{}{}/datacenters/{}".format(self.endpoint_url, tenant_text, uuid)
544 self.logger.debug("openmano POST %s %s", URLrequest, payload_req)
545 mano_response = requests.post(URLrequest, headers = self.headers_req, data=payload_req)
546 self.logger.debug("openmano response: %s", mano_response.text )
547
548 content = self._parse_yaml(mano_response.text, response=True)
549 if mano_response.status_code==200:
550 return content
551 else:
552 raise OpenmanoResponseException(str(content))
553
554 def detach_datacenter(self, uuid=None, name=None):
555 if not uuid:
556 #check that exist
557 uuid = self._get_item_uuid("datacenters", uuid, name, all_tenants=False)
558 tenant_text = "/"+self._get_tenant()
559 URLrequest = "{}{}/datacenters/{}".format(self.endpoint_url, tenant_text, uuid)
560 self.logger.debug("openmano DELETE %s", URLrequest)
561 mano_response = requests.delete(URLrequest, headers = self.headers_req)
562 self.logger.debug("openmano response: %s", mano_response.text )
563
564 content = self._parse_yaml(mano_response.text, response=True)
565 if mano_response.status_code==200:
566 return content
567 else:
568 raise OpenmanoResponseException(str(content))
569
570 # WIMS
571
572 def list_wims(self, all_tenants=False, **kwargs):
573 '''Obtain a list of wims, that are the WIM information at openmano
574 Params: can be filtered by 'uuid','name','wim_url','type'
575 Return: Raises an exception on error
576 Obtain a dictionary with format {'wims':[{wim1_info},{wim2_info},...]}}
577 '''
578 return self._list_item("wims", all_tenants, filter_dict=kwargs)
579
580 def get_wim(self, uuid=None, name=None, all_tenants=False):
581 '''Obtain the information of a wim
582 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
583 Return: Raises an exception on error, not found, found several
584 Obtain a dictionary with format {'wim':{wim_info}}
585 '''
586 return self._get_item("wims", uuid, name, all_tenants)
587
588 def delete_wim(self, uuid=None, name=None):
589 '''Delete a wim
590 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
591 Return: Raises an exception on error, not found, found several, not free
592 Obtain a dictionary with format {'result': text indicating deleted}
593 '''
594 if not uuid:
595 # check that exist
596 uuid = self._get_item_uuid("wims", uuid, name, all_tenants=True)
597 return self._del_item("wims", uuid, name, all_tenants=None)
598
599 def create_wim(self, descriptor=None, descriptor_format=None, name=None, wim_url=None, **kwargs):
600 # , type="openvim", public=False, description=None):
601 '''Creates a wim
602 Params: must supply a descriptor or/and just a name and a wim_url
603 descriptor: with format {'wim':{new_wim_info}}
604 new_wim_info must contain 'name', 'wim_url', and optionally 'description'
605 must be a dictionary or a json/yaml text.
606 name: the wim name. Overwrite descriptor name if any
607 wim_url: the wim URL. Overwrite descriptor vim_url if any
608 wim_type: the WIM type, can be tapi, odl, onos. Overwrite descriptor type if any
609 public: boolean, by default not public
610 description: wim description. Overwrite descriptor description if any
611 config: dictionary with extra configuration for the concrete wim
612 Return: Raises an exception on error
613 Obtain a dictionary with format {'wim:{new_wim_info}}
614 '''
615 if isinstance(descriptor, str):
616 descriptor = self.parse(descriptor, descriptor_format)
617 elif descriptor:
618 pass
619 elif name and wim_url:
620 descriptor = {"wim": {"name": name, "wim_url": wim_url}}
621 else:
622 raise OpenmanoBadParamsException("Missing descriptor, or name and wim_url")
623
624 if 'wim' not in descriptor or len(descriptor) != 1:
625 raise OpenmanoBadParamsException("Descriptor must contain only one 'wim' field")
626 if name:
627 descriptor['wim']['name'] = name
628 if wim_url:
629 descriptor['wim']['wim_url'] = wim_url
630 for param in kwargs:
631 descriptor['wim'][param] = kwargs[param]
632
633 return self._create_item("wims", descriptor, all_tenants=None)
634
635 def edit_wim(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False,
636 **kwargs):
637 '''Edit the parameters of a wim
638 Params: must supply a descriptor or/and a parameter to change
639 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
640 descriptor: with format {'wim':{params to change info}}
641 must be a dictionary or a json/yaml text.
642 parameters to change can be supplied by the descriptor or as parameters:
643 new_name: the wim name
644 wim_url: the wim URL
645 wim_type: the wim type, can be tapi, onos, odl
646 public: boolean, available to other tenants
647 description: wim description
648 Return: Raises an exception on error, not found or found several
649 Obtain a dictionary with format {'wim':{new_wim_info}}
650 '''
651 if isinstance(descriptor, str):
652 descriptor = self.parse(descriptor, descriptor_format)
653 elif descriptor:
654 pass
655 elif kwargs:
656 descriptor = {"wim": {}}
657 else:
658 raise OpenmanoBadParamsException("Missing descriptor")
659
660 if 'wim' not in descriptor or len(descriptor) != 1:
661 raise OpenmanoBadParamsException("Descriptor must contain only one 'wim' field")
662 for param in kwargs:
663 if param == 'new_name':
664 descriptor['wim']['name'] = kwargs[param]
665 else:
666 descriptor['wim'][param] = kwargs[param]
667 return self._edit_item("wims", descriptor, uuid, name, all_tenants=None)
668
669 def attach_wim(self, uuid=None, name=None, descriptor=None, descriptor_format=None, wim_user=None,
670 wim_password=None, wim_tenant_name=None, wim_tenant_id=None):
671 # check that exist
672 uuid = self._get_item_uuid("wims", uuid, name, all_tenants=True)
673 tenant_text = "/" + self._get_tenant()
674
675 if isinstance(descriptor, str):
676 descriptor = self.parse(descriptor, descriptor_format)
677 elif descriptor:
678 pass
679 elif wim_user or wim_password or wim_tenant_name or wim_tenant_id:
680 descriptor = {"wim": {}}
681 else:
682 raise OpenmanoBadParamsException("Missing descriptor or params")
683
684 if wim_user or wim_password or wim_tenant_name or wim_tenant_id:
685 # print args.name
686 try:
687 if wim_user:
688 descriptor['wim']['wim_user'] = wim_user
689 if wim_password:
690 descriptor['wim']['wim_password'] = wim_password
691 if wim_tenant_name:
692 descriptor['wim']['wim_tenant_name'] = wim_tenant_name
693 if wim_tenant_id:
694 descriptor['wim']['wim_tenant'] = wim_tenant_id
695 except (KeyError, TypeError) as e:
696 if str(e) == 'wim':
697 error_pos = "missing field 'wim'"
698 else:
699 error_pos = "wrong format"
700 raise OpenmanoBadParamsException("Wrong wim descriptor: " + error_pos)
701
702 payload_req = yaml.safe_dump(descriptor)
703 # print payload_req
704 URLrequest = "{}{}/wims/{}".format(self.endpoint_url, tenant_text, uuid)
705 self.logger.debug("openmano POST %s %s", URLrequest, payload_req)
706 mano_response = requests.post(URLrequest, headers=self.headers_req, data=payload_req)
707 self.logger.debug("openmano response: %s", mano_response.text)
708
709 content = self._parse_yaml(mano_response.text, response=True)
710 if mano_response.status_code == 200:
711 return content
712 else:
713 raise OpenmanoResponseException(str(content))
714
715 def detach_wim(self, uuid=None, name=None):
716 if not uuid:
717 # check that exist
718 uuid = self._get_item_uuid("wims", uuid, name, all_tenants=False)
719 tenant_text = "/" + self._get_tenant()
720 URLrequest = "{}{}/wims/{}".format(self.endpoint_url, tenant_text, uuid)
721 self.logger.debug("openmano DELETE %s", URLrequest)
722 mano_response = requests.delete(URLrequest, headers=self.headers_req)
723 self.logger.debug("openmano response: %s", mano_response.text)
724
725 content = self._parse_yaml(mano_response.text, response=True)
726 if mano_response.status_code == 200:
727 return content
728 else:
729 raise OpenmanoResponseException(str(content))
730
731 #VNFS
732 def list_vnfs(self, all_tenants=False, **kwargs):
733 '''Obtain a list of vnfs
734 Params: can be filtered by 'uuid','name','description','public', "tenant_id"
735 Return: Raises an exception on error
736 Obtain a dictionary with format {'vnfs':[{vnf1_info},{vnf2_info},...]}}
737 '''
738 return self._list_item("vnfs", all_tenants, kwargs)
739
740 def get_vnf(self, uuid=None, name=None, all_tenants=False):
741 '''Obtain the information of a vnf
742 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
743 Return: Raises an exception on error, not found, found several
744 Obtain a dictionary with format {'vnf':{vnf_info}}
745 '''
746 return self._get_item("vnfs", uuid, name, all_tenants)
747
748 def delete_vnf(self, uuid=None, name=None, all_tenants=False):
749 '''Delete a vnf
750 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
751 Return: Raises an exception on error, not found, found several, not free
752 Obtain a dictionary with format {'result': text indicating deleted}
753 '''
754 return self._del_item("vnfs", uuid, name, all_tenants)
755
756 def create_vnf(self, descriptor=None, descriptor_format=None, **kwargs):
757 '''Creates a vnf
758 Params: must supply a descriptor
759 descriptor: with format {'vnf':{new_vnf_info}}
760 must be a dictionary or a json/yaml text.
761 must be a dictionary or a json/yaml text.
762 Other parameters can be:
763 #TODO, revise
764 name: the vnf name. Overwrite descriptor name if any
765 image_path: Can be a string or a string list. Overwrite the image_path at descriptor
766 description: vnf descriptor.. Overwrite descriptor description if any
767 public: boolean, available to other tenants
768 class: user text for vnf classification
769 tenant_id: Propietary tenant
770 ...
771 Return: Raises an exception on error
772 Obtain a dictionary with format {'vnf':{new_vnf_info}}
773 '''
774 if isinstance(descriptor, str):
775 descriptor = self.parse(descriptor, descriptor_format)
776 elif descriptor:
777 pass
778 else:
779 raise OpenmanoBadParamsException("Missing descriptor")
780
781 try:
782 if "vnfd:vnfd-catalog" in descriptor or "vnfd-catalog" in descriptor:
783 api_version = "v3"
784 token = "vnfd"
785 vnfd_catalog = descriptor.get("vnfd:vnfd-catalog")
786 if not vnfd_catalog:
787 vnfd_catalog = descriptor.get("vnfd-catalog")
788 vnfds = vnfd_catalog.get("vnfd:vnfd")
789 if not vnfds:
790 vnfds = vnfd_catalog.get("vnfd")
791 vnfd = vnfds[0]
792 vdu_list = vnfd["vdu"]
793 elif "vnf" in descriptor: # old API
794 api_version = None
795 token = "vnfs"
796 vnfd = descriptor['vnf']
797 vdu_list = vnfd["VNFC"]
798 else:
799 raise OpenmanoBadParamsException("Invalid VNF Descriptor must contain only one 'vnf' field or vnd-catalog")
800 except (KeyError, TypeError) as e:
801 raise OpenmanoBadParamsException("Invalid VNF Descriptor. Missing field {}".format(e))
802
803 if kwargs:
804 try:
805 if kwargs.get('name'):
806 vnfd['name'] = kwargs['name']
807 if kwargs.get('description'):
808 vnfd['description'] = kwargs['description']
809 if kwargs.get('image_path'):
810 error_param = 'image_path'
811 image_list = kwargs['image_path'].split(",")
812 image_item = image_list.pop(0)
813 # print "image-path", image_path_
814 for vdu in vdu_list:
815 if api_version == "v3":
816 if vdu.get("image"):
817 if image_item:
818 vdu['image'] = image_item
819 if "image-checksum" in vdu:
820 del vdu["image-checksum"]
821 if image_list:
822 image_item = image_list.pop(0)
823 for vol in vdu.get("volumes", ()): # image name in volumes
824 if image_item:
825 vol["image"] = image_item
826 if "image-checksum" in vol:
827 del vol["image-checksum"]
828 if image_list:
829 image_item = image_list.pop(0)
830 else:
831 if image_item:
832 vdu['VNFC image'] = image_item
833 if "image name" in vdu:
834 del vdu["image name"]
835 if "image checksum" in vdu:
836 del vdu["image checksum"]
837 if image_list:
838 image_item = image_list.pop(0)
839 for vol in vdu.get('devices', ()):
840 if vol['type'] != 'disk':
841 continue
842 if image_item:
843 vol['image'] = image_item
844 if "image name" in vol:
845 del vol["image name"]
846 if "image checksum" in vol:
847 del vol["image checksum"]
848 if image_list:
849 image_item = image_list.pop(0)
850 if kwargs.get('image_name'): # image name precedes if both are supplied
851 error_param = 'image_name'
852 image_list = kwargs['image_name'].split(",")
853 image_item = image_list.pop(0)
854 for vdu in vdu_list:
855 if api_version == "v3":
856 if vdu.get("image"):
857 if image_item:
858 vdu['image'] = image_item
859 if "image-checksum" in vdu:
860 del vdu["image-checksum"]
861 if image_list:
862 image_item = image_list.pop(0)
863 for vol in vdu.get("volumes", ()): # image name in volumes
864 if image_item:
865 vol["image"] = image_item
866 if "image-checksum" in vol:
867 del vol["image-checksum"]
868 if image_list:
869 image_item = image_list.pop(0)
870 else:
871 if image_item:
872 vdu['image name'] = image_item
873 if "VNFC image" in vdu:
874 del vdu["VNFC image"]
875 if image_list:
876 image_item = image_list.pop(0)
877 for vol in vdu.get('devices', ()):
878 if vol['type'] != 'disk':
879 continue
880 if image_item:
881 vol['image name'] = image_item
882 if "image" in vol:
883 del vol["image"]
884 if "image checksum" in vol:
885 del vol["image checksum"]
886 if image_list:
887 image_item = image_list.pop(0)
888
889 if kwargs.get('image_checksum'):
890 error_param = 'image_checksum'
891 image_list = kwargs['image_checksum'].split(",")
892 image_item = image_list.pop(0)
893 for vdu in vdu_list:
894 if api_version == "v3":
895 if vdu.get("image"):
896 if image_item:
897 vdu['image-checksum'] = image_item
898 if image_list:
899 image_item = image_list.pop(0)
900 for vol in vdu.get("volumes", ()): # image name in volumes
901 if image_item:
902 vol["mage-checksum"] = image_item
903 if image_list:
904 image_item = image_list.pop(0)
905 else:
906 if image_item:
907 vdu['image checksum'] = image_item
908 if "VNFC image" in vdu:
909 del vdu["VNFC image"]
910 if image_list:
911 image_item = image_list.pop(0)
912 for vol in vdu.get('devices', ()):
913 if vol['type'] != 'disk':
914 continue
915 if image_item:
916 vol['image checksum'] = image_item
917 if "image" in vol:
918 del vol["image"]
919 if image_list:
920 image_item = image_list.pop(0)
921 except IndexError:
922 raise OpenmanoBadParamsException("{} contains more items than {} at descriptor".format(
923 error_param, "vnfd-catalog:vnfd:vdu" if api_version else "vnf:VNFC"))
924 except (KeyError, TypeError) as e:
925 raise OpenmanoBadParamsException("Invalid VNF Descriptor. Missing field {}".format(e))
926 return self._create_item(token, descriptor, api_version=api_version)
927
928 # def edit_vnf(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, **kwargs):
929 # '''Edit the parameters of a vnf
930 # Params: must supply a descriptor or/and a parameters to change
931 # uuid or/and name. If only name is supplied, there must be only one or an exception is raised
932 # descriptor: with format {'vnf':{params to change info}}
933 # parameters to change can be supplyied by the descriptor or as parameters:
934 # new_name: the vnf name
935 # vim_url: the vnf URL
936 # vim_url_admin: the vnf URL for administrative issues
937 # vim_type: the vnf type, can be openstack or openvim.
938 # public: boolean, available to other tenants
939 # description: vnf description
940 # Return: Raises an exception on error, not found or found several
941 # Obtain a dictionary with format {'vnf':{new_vnf_info}}
942 # '''
943 #
944 # if isinstance(descriptor, str):
945 # descriptor = self.parse(descriptor, descriptor_format)
946 # elif descriptor:
947 # pass
948 # elif kwargs:
949 # descriptor={"vnf": {}}
950 # else:
951 # raise OpenmanoBadParamsException("Missing descriptor")
952 #
953 # if 'vnf' not in descriptor or len(descriptor)>2:
954 # raise OpenmanoBadParamsException("Descriptor must contain only one 'vnf' field")
955 # for param in kwargs:
956 # if param=='new_name':
957 # descriptor['vnf']['name'] = kwargs[param]
958 # else:
959 # descriptor['vnf'][param] = kwargs[param]
960 # return self._edit_item("vnfs", descriptor, uuid, name, all_tenants=None)
961
962 #SCENARIOS
963 def list_scenarios(self, all_tenants=False, **kwargs):
964 '''Obtain a list of scenarios
965 Params: can be filtered by 'uuid','name','description','public', "tenant_id"
966 Return: Raises an exception on error
967 Obtain a dictionary with format {'scenarios':[{scenario1_info},{scenario2_info},...]}}
968 '''
969 return self._list_item("scenarios", all_tenants, kwargs)
970
971 def get_scenario(self, uuid=None, name=None, all_tenants=False):
972 '''Obtain the information of a scenario
973 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
974 Return: Raises an exception on error, not found, found several
975 Obtain a dictionary with format {'scenario':{scenario_info}}
976 '''
977 return self._get_item("scenarios", uuid, name, all_tenants)
978
979 def delete_scenario(self, uuid=None, name=None, all_tenants=False):
980 '''Delete a scenario
981 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
982 Return: Raises an exception on error, not found, found several, not free
983 Obtain a dictionary with format {'result': text indicating deleted}
984 '''
985 return self._del_item("scenarios", uuid, name, all_tenants)
986
987 def create_scenario(self, descriptor=None, descriptor_format=None, **kwargs):
988 """Creates a scenario
989 Params: must supply a descriptor
990 descriptor: with format {'scenario':{new_scenario_info}}
991 must be a dictionary or a json/yaml text.
992 Other parameters can be:
993 name: the scenario name. Overwrite descriptor name if any
994 description: scenario descriptor.. Overwrite descriptor description if any
995 public: boolean, available to other tenants
996 tenant_id. Propietary tenant
997 Return: Raises an exception on error
998 Obtain a dictionary with format {'scenario':{new_scenario_info}}
999 """
1000 if isinstance(descriptor, str):
1001 descriptor = self.parse(descriptor, descriptor_format)
1002 elif descriptor:
1003 pass
1004 else:
1005 raise OpenmanoBadParamsException("Missing descriptor")
1006
1007 try:
1008 if "nsd:nsd-catalog" in descriptor or "nsd-catalog" in descriptor:
1009 api_version = "v3"
1010 token = "nsd"
1011 nsd_catalog = descriptor.get("nsd:nsd-catalog")
1012 if not nsd_catalog:
1013 nsd_catalog = descriptor.get("nsd-catalog")
1014 nsds = nsd_catalog.get("nsd:nsd")
1015 if not nsds:
1016 nsds = nsd_catalog.get("nsd")
1017 nsd = nsds[0]
1018 elif "scenario" in descriptor: # old API
1019 api_version = None
1020 token = "scenarios"
1021 nsd = descriptor['scenario']
1022 else:
1023 raise OpenmanoBadParamsException("Invalid NS Descriptor must contain only one 'scenario' field or nsd-catalog")
1024 except (KeyError, TypeError) as e:
1025 raise OpenmanoBadParamsException("Invalid NS Descriptor. Missing field {}".format(e))
1026
1027 for param in kwargs:
1028 nsd[param] = kwargs[param]
1029 return self._create_item(token, descriptor, api_version=api_version)
1030
1031 def edit_scenario(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, **kwargs):
1032 '''Edit the parameters of a scenario
1033 Params: must supply a descriptor or/and a parameters to change
1034 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
1035 descriptor: with format {'scenario':{params to change info}}
1036 must be a dictionary or a json/yaml text.
1037 parameters to change can be supplyied by the descriptor or as parameters:
1038 new_name: the scenario name
1039 public: boolean, available to other tenants
1040 description: scenario description
1041 tenant_id. Propietary tenant
1042 Return: Raises an exception on error, not found or found several
1043 Obtain a dictionary with format {'scenario':{new_scenario_info}}
1044 '''
1045
1046 if isinstance(descriptor, str):
1047 descriptor = self.parse(descriptor, descriptor_format)
1048 elif descriptor:
1049 pass
1050 elif kwargs:
1051 descriptor={"scenario": {}}
1052 else:
1053 raise OpenmanoBadParamsException("Missing descriptor")
1054
1055 if 'scenario' not in descriptor or len(descriptor)>2:
1056 raise OpenmanoBadParamsException("Descriptor must contain only one 'scenario' field")
1057 for param in kwargs:
1058 if param=='new_name':
1059 descriptor['scenario']['name'] = kwargs[param]
1060 else:
1061 descriptor['scenario'][param] = kwargs[param]
1062 return self._edit_item("scenarios", descriptor, uuid, name, all_tenants=None)
1063
1064
1065 #INSTANCE-SCENARIOS
1066 def list_instances(self, all_tenants=False, **kwargs):
1067 '''Obtain a list of instances
1068 Params: can be filtered by 'uuid','name','description','scenario_id', "tenant_id"
1069 Return: Raises an exception on error
1070 Obtain a dictionary with format {'instances':[{instance1_info},{instance2_info},...]}}
1071 '''
1072 return self._list_item("instances", all_tenants, kwargs)
1073
1074 def get_instance(self, uuid=None, name=None, all_tenants=False):
1075 '''Obtain the information of a instance
1076 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
1077 Return: Raises an exception on error, not found, found several
1078 Obtain a dictionary with format {'instance':{instance_info}}
1079 '''
1080 return self._get_item("instances", uuid, name, all_tenants)
1081
1082 def delete_instance(self, uuid=None, name=None, all_tenants=False):
1083 '''Delete a instance
1084 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
1085 Return: Raises an exception on error, not found, found several, not free
1086 Obtain a dictionary with format {'result': text indicating deleted}
1087 '''
1088 return self._del_item("instances", uuid, name, all_tenants)
1089
1090 def create_instance(self, descriptor=None, descriptor_format=None, name=None, **kwargs):
1091 '''Creates a instance
1092 Params: must supply a descriptor or/and a name and scenario
1093 descriptor: with format {'instance':{new_instance_info}}
1094 must be a dictionary or a json/yaml text.
1095 name: the instance name. Overwrite descriptor name if any
1096 Other parameters can be:
1097 description: instance descriptor.. Overwrite descriptor description if any
1098 datacenter_name, datacenter_id: datacenter where to be deployed
1099 scenario_name, scenario_id: Scenario this instance is based on
1100 Return: Raises an exception on error
1101 Obtain a dictionary with format {'instance':{new_instance_info}}
1102 '''
1103 if isinstance(descriptor, str):
1104 descriptor = self.parse(descriptor, descriptor_format)
1105 elif descriptor:
1106 pass
1107 elif name and ("scenario_name" in kwargs or "scenario_id" in kwargs):
1108 descriptor = {"instance": {"name": name}}
1109 else:
1110 raise OpenmanoBadParamsException("Missing descriptor")
1111
1112 if 'instance' not in descriptor or len(descriptor)>2:
1113 raise OpenmanoBadParamsException("Descriptor must contain only one 'instance' field, and an optional version")
1114 if name:
1115 descriptor['instance']["name"] = name
1116 if "scenario_name" in kwargs or "scenario_id" in kwargs:
1117 descriptor['instance']["scenario"] = self._get_item_uuid("scenarios", kwargs.get("scenario_id"), kwargs.get("scenario_name"))
1118 if "datacenter_name" in kwargs or "datacenter_id" in kwargs:
1119 descriptor['instance']["datacenter"] = self._get_item_uuid("datacenters", kwargs.get("datacenter_id"), kwargs.get("datacenter_name"))
1120 if "description" in kwargs:
1121 descriptor['instance']["description"] = kwargs.get("description")
1122 #for param in kwargs:
1123 # descriptor['instance'][param] = kwargs[param]
1124 if "datacenter" not in descriptor['instance']:
1125 descriptor['instance']["datacenter"] = self._get_datacenter()
1126 return self._create_item("instances", descriptor)
1127
1128 #VIM ACTIONS
1129 def vim_action(self, action, item, uuid=None, all_tenants=False, **kwargs):
1130 '''Perform an action over a vim
1131 Params:
1132 action: can be 'list', 'get'/'show', 'delete' or 'create'
1133 item: can be 'tenants' or 'networks'
1134 uuid: uuid of the tenant/net to show or to delete. Ignore otherwise
1135 other parameters:
1136 datacenter_name, datacenter_id: datacenters to act on, if missing uses classes store datacenter
1137 descriptor, descriptor_format: descriptor needed on creation, can be a dict or a yaml/json str
1138 must be a dictionary or a json/yaml text.
1139 name: for created tenant/net Overwrite descriptor name if any
1140 description: tenant descriptor. Overwrite descriptor description if any
1141
1142 Return: Raises an exception on error
1143 Obtain a dictionary with format {'tenant':{new_tenant_info}}
1144 '''
1145 if item not in ("tenants", "networks", "images"):
1146 raise OpenmanoBadParamsException("Unknown value for item '{}', must be 'tenants', 'nets' or "
1147 "images".format(str(item)))
1148
1149 image_actions = ['list','get','show','delete']
1150 if item == "images" and action not in image_actions:
1151 raise OpenmanoBadParamsException("Only available actions for item '{}' are {}\n"
1152 "Requested action was '{}'".format(item, ', '.join(image_actions), action))
1153 if all_tenants:
1154 tenant_text = "/any"
1155 else:
1156 tenant_text = "/"+self._get_tenant()
1157
1158 if "datacenter_id" in kwargs or "datacenter_name" in kwargs:
1159 datacenter = self._get_item_uuid("datacenters", kwargs.get("datacenter_id"), kwargs.get("datacenter_name"), all_tenants=all_tenants)
1160 else:
1161 datacenter = self._get_datacenter()
1162
1163 if action=="list":
1164 URLrequest = "{}{}/vim/{}/{}".format(self.endpoint_url, tenant_text, datacenter, item)
1165 self.logger.debug("GET %s", URLrequest )
1166 mano_response = requests.get(URLrequest, headers=self.headers_req)
1167 self.logger.debug("openmano response: %s", mano_response.text )
1168 content = self._parse_yaml(mano_response.text, response=True)
1169 if mano_response.status_code==200:
1170 return content
1171 else:
1172 raise OpenmanoResponseException(str(content))
1173 elif action=="get" or action=="show":
1174 URLrequest = "{}{}/vim/{}/{}/{}".format(self.endpoint_url, tenant_text, datacenter, item, uuid)
1175 self.logger.debug("GET %s", URLrequest )
1176 mano_response = requests.get(URLrequest, headers=self.headers_req)
1177 self.logger.debug("openmano response: %s", mano_response.text )
1178 content = self._parse_yaml(mano_response.text, response=True)
1179 if mano_response.status_code==200:
1180 return content
1181 else:
1182 raise OpenmanoResponseException(str(content))
1183 elif action=="delete":
1184 URLrequest = "{}{}/vim/{}/{}/{}".format(self.endpoint_url, tenant_text, datacenter, item, uuid)
1185 self.logger.debug("DELETE %s", URLrequest )
1186 mano_response = requests.delete(URLrequest, headers=self.headers_req)
1187 self.logger.debug("openmano response: %s", mano_response.text )
1188 content = self._parse_yaml(mano_response.text, response=True)
1189 if mano_response.status_code==200:
1190 return content
1191 else:
1192 raise OpenmanoResponseException(str(content))
1193 elif action=="create":
1194 if "descriptor" in kwargs:
1195 if isinstance(kwargs["descriptor"], str):
1196 descriptor = self._parse(kwargs["descriptor"], kwargs.get("descriptor_format") )
1197 else:
1198 descriptor = kwargs["descriptor"]
1199 elif "name" in kwargs:
1200 descriptor={item[:-1]: {"name": kwargs["name"]}}
1201 else:
1202 raise OpenmanoResponseException("Missing descriptor")
1203
1204 if item[:-1] not in descriptor or len(descriptor)!=1:
1205 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
1206 if "name" in kwargs:
1207 descriptor[ item[:-1] ]['name'] = kwargs["name"]
1208 if "description" in kwargs:
1209 descriptor[ item[:-1] ]['description'] = kwargs["description"]
1210 payload_req = yaml.safe_dump(descriptor)
1211 #print payload_req
1212 URLrequest = "{}{}/vim/{}/{}".format(self.endpoint_url, tenant_text, datacenter, item)
1213 self.logger.debug("openmano POST %s %s", URLrequest, payload_req)
1214 mano_response = requests.post(URLrequest, headers = self.headers_req, data=payload_req)
1215 self.logger.debug("openmano response: %s", mano_response.text )
1216 content = self._parse_yaml(mano_response.text, response=True)
1217 if mano_response.status_code==200:
1218 return content
1219 else:
1220 raise OpenmanoResponseException(str(content))
1221 else:
1222 raise OpenmanoBadParamsException("Unknown value for action '{}".format(str(action)))
1223