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