2 # -*- coding: utf-8 -*-
5 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
6 # This file is part of openmano
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
13 # http://www.apache.org/licenses/LICENSE-2.0
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
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact with: nfvlabs@tid.es
26 openmano python client used to interact with openmano-server
28 __author__
="Alfonso Tierno"
29 __date__
="$09-Mar-2016 09:09:48$"
30 __version__
="0.0.1-r467"
31 version_date
="Mar 2016"
38 if sys
.version_info
.major
== 3:
39 from urllib
.parse
import quote
40 elif sys
.version_info
.major
== 2:
41 from urllib
import quote
43 class OpenmanoException(Exception):
44 '''Common Exception for all openmano client exceptions'''
46 class OpenmanoBadParamsException(OpenmanoException
):
47 '''Bad or missing input parameters'''
49 class OpenmanoResponseException(OpenmanoException
):
50 '''Unexpected response from openmano server'''
52 class OpenmanoNotFoundException(OpenmanoException
):
53 '''Not found at server'''
56 # def __init__(self, message):
57 # print "Error: %s" %message
62 # print "Type 'openmano -h' for help"
64 class openmanoclient():
65 headers_req
= {'Accept': 'application/yaml', 'content-type': 'application/yaml'}
67 def __init__(self
, **kwargs
):
68 self
.username
= kwargs
.get("username")
69 self
.password
= kwargs
.get("password")
70 self
.endpoint_url
= kwargs
.get("endpoint_url")
71 self
.tenant_id
= kwargs
.get("tenant_id")
72 self
.tenant_name
= kwargs
.get("tenant_name")
74 self
.datacenter_id
= kwargs
.get("datacenter_id")
75 self
.datacenter_name
= kwargs
.get("datacenter_name")
76 self
.datacenter
= None
77 self
.logger
= logging
.getLogger('manoclient')
78 if kwargs
.get("debug"):
79 self
.logger
.setLevel(logging
.DEBUG
)
81 def __getitem__(self
, index
):
82 if index
=='tenant_name':
83 return self
.tenant_name
84 elif index
=='tenant_id':
86 elif index
=='datacenter_name':
87 return self
.datacenter_name
88 elif index
=='datacenter_id':
89 return self
.datacenter_id
90 elif index
=='username':
92 elif index
=='password':
94 elif index
=='endpoint_url':
95 return self
.endpoint_url
97 raise KeyError("Invalid key '%s'" %str
(index
))
99 def __setitem__(self
,index
, value
):
100 if index
=='tenant_name':
101 self
.tenant_name
= value
102 elif index
=='tenant_id':
103 self
.tenant_id
= value
104 elif index
=='datacenter_name':
105 self
.datacenter_name
= value
106 elif index
=='datacenter_id':
107 self
.datacenter_id
= value
108 elif index
=='username':
109 self
.username
= value
110 elif index
=='password':
111 self
.password
= value
112 elif index
=='endpoint_url':
113 self
.endpoint_url
= value
115 raise KeyError("Invalid key '%s'" %str
(index
))
116 self
.tenant
= None # force to reload tenant with different credentials
117 self
.datacenter
= None # force to reload datacenter with different credentials
119 def _parse(self
, descriptor
, descriptor_format
, response
=False):
121 if descriptor_format
and descriptor_format
!= "json" and descriptor_format
!= "yaml":
122 raise OpenmanoBadParamsException("'descriptor_format' must be a 'json' or 'yaml' text")
123 if descriptor_format
!= "json":
125 return yaml
.load(descriptor
)
126 except yaml
.YAMLError
as exc
:
128 if hasattr(exc
, 'problem_mark'):
129 mark
= exc
.problem_mark
130 error_pos
= " at line:{} column:{}s".format(mark
.line
+1, mark
.column
+1)
131 error_text
= "yaml format error" + error_pos
132 elif descriptor_format
!= "yaml":
134 return json
.loads(descriptor
)
135 except Exception as e
:
137 error_text
= "json format error" + str(e
)
140 raise OpenmanoResponseException(error_text
)
141 raise OpenmanoBadParamsException(error_text
)
143 def _parse_yaml(self
, descriptor
, response
=False):
145 return yaml
.load(descriptor
)
146 except yaml
.YAMLError
as exc
:
148 if hasattr(exc
, 'problem_mark'):
149 mark
= exc
.problem_mark
150 error_pos
= " at line:{} column:{}s".format(mark
.line
+1, mark
.column
+1)
151 error_text
= "yaml format error" + error_pos
153 raise OpenmanoResponseException(error_text
)
154 raise OpenmanoBadParamsException(error_text
)
157 def _get_item_uuid(self
, item
, item_id
=None, item_name
=None, all_tenants
=False):
158 if all_tenants
== None:
160 elif all_tenants
== False:
161 tenant_text
= "/" + self
.tenant
164 URLrequest
= "{}{}/{}".format(self
.endpoint_url
, tenant_text
, item
)
165 self
.logger
.debug("GET %s", URLrequest
)
166 mano_response
= requests
.get(URLrequest
, headers
=self
.headers_req
)
167 self
.logger
.debug("openmano response: %s", mano_response
.text
)
168 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
171 if not item_id
and not item_name
:
172 raise OpenmanoResponseException("Missing either {0}_name or {0}_id".format(item
[:-1]))
173 for i
in content
[item
]:
174 if item_id
and i
["uuid"] == item_id
:
176 elif item_name
and i
["name"] == item_name
:
182 raise OpenmanoNotFoundException("No {} found with id '{}'".format(item
[:-1], item_id
))
184 #print(item, item_name)
185 raise OpenmanoNotFoundException("No {} found with name '{}'".format(item
[:-1], item_name
) )
187 raise OpenmanoNotFoundException("{} {} found with name '{}'. uuid must be used".format(found
, item
, item_name
))
190 def _get_item(self
, item
, uuid
=None, name
=None, all_tenants
=False):
193 elif all_tenants
==None:
196 tenant_text
= "/"+self
._get
_tenant
()
199 uuid
= self
._get
_item
_uuid
(item
, uuid
, name
, all_tenants
)
201 URLrequest
= "{}{}/{}/{}".format(self
.endpoint_url
, tenant_text
, item
, uuid
)
202 self
.logger
.debug("GET %s", URLrequest
)
203 mano_response
= requests
.get(URLrequest
, headers
=self
.headers_req
)
204 self
.logger
.debug("openmano response: %s", mano_response
.text
)
206 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
207 if mano_response
.status_code
==200:
210 raise OpenmanoResponseException(str(content
))
212 def _get_tenant(self
):
214 self
.tenant
= self
._get
_item
_uuid
("tenants", self
.tenant_id
, self
.tenant_name
, None)
217 def _get_datacenter(self
):
220 if not self
.datacenter
:
221 self
.datacenter
= self
._get
_item
_uuid
("datacenters", self
.datacenter_id
, self
.datacenter_name
, False)
222 return self
.datacenter
224 def _create_item(self
, item
, descriptor
, all_tenants
=False):
227 elif all_tenants
==None:
230 tenant_text
= "/"+self
._get
_tenant
()
231 payload_req
= yaml
.safe_dump(descriptor
)
235 URLrequest
= "{}{}/{}".format(self
.endpoint_url
, tenant_text
, item
)
236 self
.logger
.debug("openmano POST %s %s", URLrequest
, payload_req
)
237 mano_response
= requests
.post(URLrequest
, headers
= self
.headers_req
, data
=payload_req
)
238 self
.logger
.debug("openmano response: %s", mano_response
.text
)
240 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
241 if mano_response
.status_code
==200:
244 raise OpenmanoResponseException(str(content
))
246 def _del_item(self
, item
, uuid
=None, name
=None, all_tenants
=False):
249 elif all_tenants
==None:
252 tenant_text
= "/"+self
._get
_tenant
()
255 uuid
= self
._get
_item
_uuid
(item
, uuid
, name
, all_tenants
)
257 URLrequest
= "{}{}/{}/{}".format(self
.endpoint_url
, tenant_text
, item
, uuid
)
258 self
.logger
.debug("DELETE %s", URLrequest
)
259 mano_response
= requests
.delete(URLrequest
, headers
= self
.headers_req
)
260 self
.logger
.debug("openmano response: %s", mano_response
.text
)
262 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
263 if mano_response
.status_code
==200:
266 raise OpenmanoResponseException(str(content
))
268 def _list_item(self
, item
, all_tenants
=False, filter_dict
=None):
271 elif all_tenants
==None:
274 tenant_text
= "/"+self
._get
_tenant
()
276 URLrequest
= "{}{}/{}".format(self
.endpoint_url
, tenant_text
, item
)
279 for k
in filter_dict
:
280 URLrequest
+= separator
+ quote(str(k
)) + "=" + quote(str(filter_dict
[k
]))
282 self
.logger
.debug("openmano GET %s", URLrequest
)
283 mano_response
= requests
.get(URLrequest
, headers
=self
.headers_req
)
284 self
.logger
.debug("openmano response: %s", mano_response
.text
)
286 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
287 if mano_response
.status_code
==200:
290 raise OpenmanoResponseException(str(content
))
292 def _edit_item(self
, item
, descriptor
, uuid
=None, name
=None, all_tenants
=False):
295 elif all_tenants
==None:
298 tenant_text
= "/"+self
._get
_tenant
()
302 uuid
= self
._get
_item
_uuid
("tenants", uuid
, name
, all_tenants
)
304 payload_req
= yaml
.safe_dump(descriptor
)
308 URLrequest
= "{}{}/{}/{}".format(self
.endpoint_url
, tenant_text
, item
, uuid
)
309 self
.logger
.debug("openmano PUT %s %s", URLrequest
, payload_req
)
310 mano_response
= requests
.put(URLrequest
, headers
= self
.headers_req
, data
=payload_req
)
311 self
.logger
.debug("openmano response: %s", mano_response
.text
)
313 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
314 if mano_response
.status_code
==200:
317 raise OpenmanoResponseException(str(content
))
320 def list_tenants(self
, **kwargs
):
321 '''Obtain a list of tenants
322 Params: can be filtered by 'uuid','name','description'
323 Return: Raises an exception on error
324 Obtain a dictionary with format {'tenants':[{tenant1_info},{tenant2_info},...]}}
326 return self
._list
_item
("tenants", all_tenants
=None, filter_dict
=kwargs
)
328 def get_tenant(self
, uuid
=None, name
=None):
329 '''Obtain the information of a tenant
330 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
331 Return: Raises an exception on error, not found, found several
332 Obtain a dictionary with format {'tenant':{tenant_info}}
334 return self
._get
_item
("tenants", uuid
, name
, all_tenants
=None)
336 def delete_tenant(self
, uuid
=None, name
=None):
338 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
339 Return: Raises an exception on error, not found, found several
340 Obtain a dictionary with format {'result': text indicating deleted}
342 return self
._del
_item
("tenants", uuid
, name
, all_tenants
=None)
344 def create_tenant(self
, descriptor
=None, descriptor_format
=None, name
=None, description
=None):
346 Params: must supply a descriptor or/and just a name
347 descriptor: with format {'tenant':{new_tenant_info}}
348 newtenant_info must contain 'name', and optionally 'description'
349 must be a dictionary or a json/yaml text.
350 name: the tenant name. Overwrite descriptor name if any
351 description: tenant descriptor.. Overwrite descriptor description if any
352 Return: Raises an exception on error
353 Obtain a dictionary with format {'tenant':{new_tenant_info}}
355 if isinstance(descriptor
, str):
356 descriptor
= self
._parse
(descriptor
, descriptor_format
)
360 descriptor
={"tenant": {"name": name
}}
362 raise OpenmanoBadParamsException("Missing descriptor")
364 if 'tenant' not in descriptor
or len(descriptor
)!=1:
365 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
367 descriptor
['tenant']['name'] = name
369 descriptor
['tenant']['description'] = description
371 return self
._create
_item
("tenants", descriptor
, all_tenants
=None)
373 def edit_tenant(self
, uuid
=None, name
=None, descriptor
=None, descriptor_format
=None, new_name
=None, new_description
=None):
374 '''Edit the parameters of a tenant
375 Params: must supply a descriptor or/and a new_name or new_description
376 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
377 descriptor: with format {'tenant':{params to change info}}
378 must be a dictionary or a json/yaml text.
379 name: the tenant name. Overwrite descriptor name if any
380 description: tenant descriptor.. Overwrite descriptor description if any
381 Return: Raises an exception on error, not found or found several
382 Obtain a dictionary with format {'tenant':{newtenant_info}}
385 if isinstance(descriptor
, str):
386 descriptor
= self
.parse(descriptor
, descriptor_format
)
389 elif new_name
or new_description
:
390 descriptor
={"tenant": {}}
392 raise OpenmanoBadParamsException("Missing descriptor")
394 if 'tenant' not in descriptor
or len(descriptor
)!=1:
395 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
397 descriptor
['tenant']['name'] = new_name
399 descriptor
['tenant']['description'] = new_description
401 return self
._edit
_item
("tenants", descriptor
, uuid
, name
, all_tenants
=None)
405 def list_datacenters(self
, all_tenants
=False, **kwargs
):
406 '''Obtain a list of datacenters, that are the VIM information at openmano
407 Params: can be filtered by 'uuid','name','vim_url','type'
408 Return: Raises an exception on error
409 Obtain a dictionary with format {'datacenters':[{datacenter1_info},{datacenter2_info},...]}}
411 return self
._list
_item
("datacenters", all_tenants
, filter_dict
=kwargs
)
413 def get_datacenter(self
, uuid
=None, name
=None, all_tenants
=False):
414 '''Obtain the information of a datacenter
415 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
416 Return: Raises an exception on error, not found, found several
417 Obtain a dictionary with format {'datacenter':{datacenter_info}}
419 return self
._get
_item
("datacenters", uuid
, name
, all_tenants
)
421 def delete_datacenter(self
, uuid
=None, name
=None):
422 '''Delete a datacenter
423 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
424 Return: Raises an exception on error, not found, found several, not free
425 Obtain a dictionary with format {'result': text indicating deleted}
427 return self
._del
_item
("datacenters", uuid
, name
, all_tenants
=True)
429 def create_datacenter(self
, descriptor
=None, descriptor_format
=None, name
=None, vim_url
=None, **kwargs
):
430 #, type="openvim", public=False, description=None):
431 '''Creates a datacenter
432 Params: must supply a descriptor or/and just a name and vim_url
433 descriptor: with format {'datacenter':{new_datacenter_info}}
434 newdatacenter_info must contain 'name', 'vim_url', and optionally 'description'
435 must be a dictionary or a json/yaml text.
436 name: the datacenter name. Overwrite descriptor name if any
437 vim_url: the datacenter URL. Overwrite descriptor vim_url if any
438 vim_url_admin: the datacenter URL for administrative issues. Overwrite descriptor vim_url if any
439 vim_type: the datacenter type, can be openstack or openvim. Overwrite descriptor type if any
440 public: boolean, by default not public
441 description: datacenter description. Overwrite descriptor description if any
442 config: dictionary with extra configuration for the concrete datacenter
443 Return: Raises an exception on error
444 Obtain a dictionary with format {'datacenter':{new_datacenter_info}}
446 if isinstance(descriptor
, str):
447 descriptor
= self
.parse(descriptor
, descriptor_format
)
450 elif name
and vim_url
:
451 descriptor
={"datacenter": {"name": name
, "vim_url": vim_url
}}
453 raise OpenmanoBadParamsException("Missing descriptor, or name and vim_url")
455 if 'datacenter' not in descriptor
or len(descriptor
)!=1:
456 raise OpenmanoBadParamsException("Descriptor must contain only one 'datacenter' field")
458 descriptor
['datacenter']['name'] = name
460 descriptor
['datacenter']['vim_url'] = vim_url
462 descriptor
['datacenter'][param
] = kwargs
[param
]
464 return self
._create
_item
("datacenters", descriptor
, all_tenants
=None)
466 def edit_datacenter(self
, uuid
=None, name
=None, descriptor
=None, descriptor_format
=None, all_tenants
=False, **kwargs
):
467 '''Edit the parameters of a datacenter
468 Params: must supply a descriptor or/and a parameter to change
469 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
470 descriptor: with format {'datacenter':{params to change info}}
471 must be a dictionary or a json/yaml text.
472 parameters to change can be supplyied by the descriptor or as parameters:
473 new_name: the datacenter name
474 vim_url: the datacenter URL
475 vim_url_admin: the datacenter URL for administrative issues
476 vim_type: the datacenter type, can be openstack or openvim.
477 public: boolean, available to other tenants
478 description: datacenter description
479 Return: Raises an exception on error, not found or found several
480 Obtain a dictionary with format {'datacenter':{new_datacenter_info}}
483 if isinstance(descriptor
, str):
484 descriptor
= self
.parse(descriptor
, descriptor_format
)
488 descriptor
={"datacenter": {}}
490 raise OpenmanoBadParamsException("Missing descriptor")
492 if 'datacenter' not in descriptor
or len(descriptor
)!=1:
493 raise OpenmanoBadParamsException("Descriptor must contain only one 'datacenter' field")
495 if param
=='new_name':
496 descriptor
['datacenter']['name'] = kwargs
[param
]
498 descriptor
['datacenter'][param
] = kwargs
[param
]
499 return self
._edit
_item
("datacenters", descriptor
, uuid
, name
, all_tenants
=None)
501 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):
503 uuid
= self
._get
_item
_uuid
("datacenters", uuid
, name
, all_tenants
=True)
504 tenant_text
= "/"+self
._get
_tenant
()
506 if isinstance(descriptor
, str):
507 descriptor
= self
.parse(descriptor
, descriptor_format
)
510 elif vim_user
or vim_password
or vim_tenant_name
or vim_tenant_id
:
511 descriptor
={"datacenter": {}}
513 raise OpenmanoBadParamsException("Missing descriptor or params")
515 if vim_user
or vim_password
or vim_tenant_name
or vim_tenant_id
:
519 descriptor
['datacenter']['vim_user'] = vim_user
521 descriptor
['datacenter']['vim_password'] = vim_password
523 descriptor
['datacenter']['vim_tenant_name'] = vim_tenant_name
525 descriptor
['datacenter']['vim_tenant'] = vim_tenant_id
526 except (KeyError, TypeError) as e
:
527 if str(e
)=='datacenter': error_pos
= "missing field 'datacenter'"
528 else: error_pos
="wrong format"
529 raise OpenmanoBadParamsException("Wrong datacenter descriptor: " + error_pos
)
531 payload_req
= yaml
.safe_dump(descriptor
)
533 URLrequest
= "{}{}/datacenters/{}".format(self
.endpoint_url
, tenant_text
, uuid
)
534 self
.logger
.debug("openmano POST %s %s", URLrequest
, payload_req
)
535 mano_response
= requests
.post(URLrequest
, headers
= self
.headers_req
, data
=payload_req
)
536 self
.logger
.debug("openmano response: %s", mano_response
.text
)
538 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
539 if mano_response
.status_code
==200:
542 raise OpenmanoResponseException(str(content
))
544 def detach_datacenter(self
, uuid
=None, name
=None):
547 uuid
= self
._get
_item
_uuid
("datacenters", uuid
, name
, all_tenants
=False)
548 tenant_text
= "/"+self
._get
_tenant
()
549 URLrequest
= "{}{}/datacenters/{}".format(self
.endpoint_url
, tenant_text
, uuid
)
550 self
.logger
.debug("openmano DELETE %s", URLrequest
)
551 mano_response
= requests
.delete(URLrequest
, headers
= self
.headers_req
)
552 self
.logger
.debug("openmano response: %s", mano_response
.text
)
554 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
555 if mano_response
.status_code
==200:
558 raise OpenmanoResponseException(str(content
))
561 def list_vnfs(self
, all_tenants
=False, **kwargs
):
562 '''Obtain a list of vnfs
563 Params: can be filtered by 'uuid','name','description','public', "tenant_id"
564 Return: Raises an exception on error
565 Obtain a dictionary with format {'vnfs':[{vnf1_info},{vnf2_info},...]}}
567 return self
._list
_item
("vnfs", all_tenants
, kwargs
)
569 def get_vnf(self
, uuid
=None, name
=None, all_tenants
=False):
570 '''Obtain the information of a vnf
571 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
572 Return: Raises an exception on error, not found, found several
573 Obtain a dictionary with format {'vnf':{vnf_info}}
575 return self
._get
_item
("vnfs", uuid
, name
, all_tenants
)
577 def delete_vnf(self
, uuid
=None, name
=None, all_tenants
=False):
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, not free
581 Obtain a dictionary with format {'result': text indicating deleted}
583 return self
._del
_item
("vnfs", uuid
, name
, all_tenants
)
585 def create_vnf(self
, descriptor
=None, descriptor_format
=None, **kwargs
):
587 Params: must supply a descriptor
588 descriptor: with format {'vnf':{new_vnf_info}}
589 must be a dictionary or a json/yaml text.
590 must be a dictionary or a json/yaml text.
591 Other parameters can be:
592 name: the vnf name. Overwrite descriptor name if any
593 image_path: Can be a string or a string list. Overwrite the image_path at descriptor
594 description: vnf descriptor.. Overwrite descriptor description if any
595 public: boolean, available to other tenants
596 class: user text for vnf classification
597 tenant_id: Propietary tenant
599 Return: Raises an exception on error
600 Obtain a dictionary with format {'vnf':{new_vnf_info}}
602 if isinstance(descriptor
, str):
603 descriptor
= self
.parse(descriptor
, descriptor_format
)
607 raise OpenmanoBadParamsException("Missing descriptor")
609 if 'vnf' not in descriptor
or len(descriptor
)>2:
610 raise OpenmanoBadParamsException("Descriptor must contain only one 'vnf' field, and an optional version")
612 if param
== 'image_path':
615 if isinstance(kwargs
[param
], str):
616 descriptor
['vnf']['VNFC'][0]['VNFC image']=kwargs
[param
]
617 elif isinstance(kwargs
[param
], tuple) or isinstance(kwargs
[param
], list):
619 for image_path_
in kwargs
[param
]:
620 #print "image-path", image_path_
621 descriptor
['vnf']['VNFC'][index
]['VNFC image']=image_path_
624 raise OpenmanoBadParamsException("Wrong image_path type. Expected text or a text list")
625 except (KeyError, TypeError) as e
:
626 if str(e
)=='vnf': error_pos
= "missing field 'vnf'"
627 elif str(e
)=='VNFC': error_pos
= "missing field 'vnf':'VNFC'"
628 elif str(e
)==str(index
): error_pos
= "field 'vnf':'VNFC' must be an array"
629 elif str(e
)=='VNFC image': error_pos
= "missing field 'vnf':'VNFC'['VNFC image']"
630 else: error_pos
="wrong format"
631 raise OpenmanoBadParamsException("Wrong VNF descriptor: " + error_pos
)
633 descriptor
['vnf'][param
] = kwargs
[param
]
634 return self
._create
_item
("vnfs", descriptor
)
636 # def edit_vnf(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, **kwargs):
637 # '''Edit the parameters of a vnf
638 # Params: must supply a descriptor or/and a parameters 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 {'vnf':{params to change info}}
641 # parameters to change can be supplyied by the descriptor or as parameters:
642 # new_name: the vnf name
643 # vim_url: the vnf URL
644 # vim_url_admin: the vnf URL for administrative issues
645 # vim_type: the vnf type, can be openstack or openvim.
646 # public: boolean, available to other tenants
647 # description: vnf description
648 # Return: Raises an exception on error, not found or found several
649 # Obtain a dictionary with format {'vnf':{new_vnf_info}}
652 # if isinstance(descriptor, str):
653 # descriptor = self.parse(descriptor, descriptor_format)
657 # descriptor={"vnf": {}}
659 # raise OpenmanoBadParamsException("Missing descriptor")
661 # if 'vnf' not in descriptor or len(descriptor)>2:
662 # raise OpenmanoBadParamsException("Descriptor must contain only one 'vnf' field")
663 # for param in kwargs:
664 # if param=='new_name':
665 # descriptor['vnf']['name'] = kwargs[param]
667 # descriptor['vnf'][param] = kwargs[param]
668 # return self._edit_item("vnfs", descriptor, uuid, name, all_tenants=None)
671 def list_scenarios(self
, all_tenants
=False, **kwargs
):
672 '''Obtain a list of scenarios
673 Params: can be filtered by 'uuid','name','description','public', "tenant_id"
674 Return: Raises an exception on error
675 Obtain a dictionary with format {'scenarios':[{scenario1_info},{scenario2_info},...]}}
677 return self
._list
_item
("scenarios", all_tenants
, kwargs
)
679 def get_scenario(self
, uuid
=None, name
=None, all_tenants
=False):
680 '''Obtain the information of a scenario
681 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
682 Return: Raises an exception on error, not found, found several
683 Obtain a dictionary with format {'scenario':{scenario_info}}
685 return self
._get
_item
("scenarios", uuid
, name
, all_tenants
)
687 def delete_scenario(self
, uuid
=None, name
=None, all_tenants
=False):
689 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
690 Return: Raises an exception on error, not found, found several, not free
691 Obtain a dictionary with format {'result': text indicating deleted}
693 return self
._del
_item
("scenarios", uuid
, name
, all_tenants
)
695 def create_scenario(self
, descriptor
=None, descriptor_format
=None, **kwargs
):
696 '''Creates a scenario
697 Params: must supply a descriptor
698 descriptor: with format {'scenario':{new_scenario_info}}
699 must be a dictionary or a json/yaml text.
700 Other parameters can be:
701 name: the scenario name. Overwrite descriptor name if any
702 description: scenario descriptor.. Overwrite descriptor description if any
703 public: boolean, available to other tenants
704 tenant_id. Propietary tenant
705 Return: Raises an exception on error
706 Obtain a dictionary with format {'scenario':{new_scenario_info}}
708 if isinstance(descriptor
, str):
709 descriptor
= self
.parse(descriptor
, descriptor_format
)
713 raise OpenmanoBadParamsException("Missing descriptor")
715 if 'scenario' not in descriptor
or len(descriptor
)>2:
716 raise OpenmanoBadParamsException("Descriptor must contain only one 'scenario' field, and an optional version")
718 descriptor
['scenario'][param
] = kwargs
[param
]
719 return self
._create
_item
("scenarios", descriptor
)
721 def edit_scenario(self
, uuid
=None, name
=None, descriptor
=None, descriptor_format
=None, all_tenants
=False, **kwargs
):
722 '''Edit the parameters of a scenario
723 Params: must supply a descriptor or/and a parameters to change
724 uuid or/and name. If only name is supplied, there must be only one or an exception is raised
725 descriptor: with format {'scenario':{params to change info}}
726 must be a dictionary or a json/yaml text.
727 parameters to change can be supplyied by the descriptor or as parameters:
728 new_name: the scenario name
729 public: boolean, available to other tenants
730 description: scenario description
731 tenant_id. Propietary tenant
732 Return: Raises an exception on error, not found or found several
733 Obtain a dictionary with format {'scenario':{new_scenario_info}}
736 if isinstance(descriptor
, str):
737 descriptor
= self
.parse(descriptor
, descriptor_format
)
741 descriptor
={"scenario": {}}
743 raise OpenmanoBadParamsException("Missing descriptor")
745 if 'scenario' not in descriptor
or len(descriptor
)>2:
746 raise OpenmanoBadParamsException("Descriptor must contain only one 'scenario' field")
748 if param
=='new_name':
749 descriptor
['scenario']['name'] = kwargs
[param
]
751 descriptor
['scenario'][param
] = kwargs
[param
]
752 return self
._edit
_item
("scenarios", descriptor
, uuid
, name
, all_tenants
=None)
756 def list_instances(self
, all_tenants
=False, **kwargs
):
757 '''Obtain a list of instances
758 Params: can be filtered by 'uuid','name','description','scenario_id', "tenant_id"
759 Return: Raises an exception on error
760 Obtain a dictionary with format {'instances':[{instance1_info},{instance2_info},...]}}
762 return self
._list
_item
("instances", all_tenants
, kwargs
)
764 def get_instance(self
, uuid
=None, name
=None, all_tenants
=False):
765 '''Obtain the information of a instance
766 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
767 Return: Raises an exception on error, not found, found several
768 Obtain a dictionary with format {'instance':{instance_info}}
770 return self
._get
_item
("instances", uuid
, name
, all_tenants
)
772 def delete_instance(self
, uuid
=None, name
=None, all_tenants
=False):
774 Params: uuid or/and name. If only name is supplied, there must be only one or an exception is raised
775 Return: Raises an exception on error, not found, found several, not free
776 Obtain a dictionary with format {'result': text indicating deleted}
778 return self
._del
_item
("instances", uuid
, name
, all_tenants
)
780 def create_instance(self
, descriptor
=None, descriptor_format
=None, name
=None, **kwargs
):
781 '''Creates a instance
782 Params: must supply a descriptor or/and a name and scenario
783 descriptor: with format {'instance':{new_instance_info}}
784 must be a dictionary or a json/yaml text.
785 name: the instance name. Overwrite descriptor name if any
786 Other parameters can be:
787 description: instance descriptor.. Overwrite descriptor description if any
788 datacenter_name, datacenter_id: datacenter where to be deployed
789 scenario_name, scenario_id: Scenario this instance is based on
790 Return: Raises an exception on error
791 Obtain a dictionary with format {'instance':{new_instance_info}}
793 if isinstance(descriptor
, str):
794 descriptor
= self
.parse(descriptor
, descriptor_format
)
797 elif name
and ("scenario_name" in kwargs
or "scenario_id" in kwargs
):
798 descriptor
= {"instance":{"name": name
}}
800 raise OpenmanoBadParamsException("Missing descriptor")
802 if 'instance' not in descriptor
or len(descriptor
)>2:
803 raise OpenmanoBadParamsException("Descriptor must contain only one 'instance' field, and an optional version")
805 descriptor
['instance']["name"] = name
806 if "scenario_name" in kwargs
or "scenario_id" in kwargs
:
807 descriptor
['instance']["scenario"] = self
._get
_item
_uuid
("scenarios", kwargs
.get("scenario_id"), kwargs
.get("scenario_name"))
808 if "datacenter_name" in kwargs
or "datacenter_id" in kwargs
:
809 descriptor
['instance']["datacenter"] = self
._get
_item
_uuid
("datacenters", kwargs
.get("datacenter_id"), kwargs
.get("datacenter_name"))
810 if "description" in kwargs
:
811 descriptor
['instance']["description"] = kwargs
.get("description")
812 #for param in kwargs:
813 # descriptor['instance'][param] = kwargs[param]
814 if "datacenter" not in descriptor
['instance']:
815 descriptor
['instance']["datacenter"] = self
._get
_datacenter
()
816 return self
._create
_item
("instances", descriptor
)
819 def vim_action(self
, action
, item
, uuid
=None, all_tenants
=False, **kwargs
):
820 '''Perform an action over a vim
822 action: can be 'list', 'get'/'show', 'delete' or 'create'
823 item: can be 'tenants' or 'networks'
824 uuid: uuid of the tenant/net to show or to delete. Ignore otherwise
826 datacenter_name, datacenter_id: datacenters to act on, if missing uses classes store datacenter
827 descriptor, descriptor_format: descriptor needed on creation, can be a dict or a yaml/json str
828 must be a dictionary or a json/yaml text.
829 name: for created tenant/net Overwrite descriptor name if any
830 description: tenant descriptor. Overwrite descriptor description if any
832 Return: Raises an exception on error
833 Obtain a dictionary with format {'tenant':{new_tenant_info}}
835 if item
not in ("tenants", "networks"):
836 raise OpenmanoBadParamsException("Unknown value for item '{}', must be 'tenants' or 'nets'".format(str(item
)))
841 tenant_text
= "/"+self
._get
_tenant
()
843 if "datacenter_id" in kwargs
or "datacenter_name" in kwargs
:
844 datacenter
= self
._get
_item
_uuid
("datacenters", kwargs
.get("datacenter_id"), kwargs
.get("datacenter_name"), all_tenants
=all_tenants
)
846 datacenter
= self
._get
_datacenter
()
849 URLrequest
= "{}{}/vim/{}/{}".format(self
.endpoint_url
, tenant_text
, datacenter
, item
)
850 self
.logger
.debug("GET %s", URLrequest
)
851 mano_response
= requests
.get(URLrequest
, headers
=self
.headers_req
)
852 self
.logger
.debug("openmano response: %s", mano_response
.text
)
853 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
854 if mano_response
.status_code
==200:
857 raise OpenmanoResponseException(str(content
))
858 elif action
=="get" or action
=="show":
859 URLrequest
= "{}{}/vim/{}/{}/{}".format(self
.endpoint_url
, tenant_text
, datacenter
, item
, uuid
)
860 self
.logger
.debug("GET %s", URLrequest
)
861 mano_response
= requests
.get(URLrequest
, headers
=self
.headers_req
)
862 self
.logger
.debug("openmano response: %s", mano_response
.text
)
863 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
864 if mano_response
.status_code
==200:
867 raise OpenmanoResponseException(str(content
))
868 elif action
=="delete":
869 URLrequest
= "{}{}/vim/{}/{}/{}".format(self
.endpoint_url
, tenant_text
, datacenter
, item
, uuid
)
870 self
.logger
.debug("DELETE %s", URLrequest
)
871 mano_response
= requests
.delete(URLrequest
, headers
=self
.headers_req
)
872 self
.logger
.debug("openmano response: %s", mano_response
.text
)
873 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
874 if mano_response
.status_code
==200:
877 raise OpenmanoResponseException(str(content
))
878 elif action
=="create":
879 if "descriptor" in kwargs
:
880 if isinstance(kwargs
["descriptor"], str):
881 descriptor
= self
._parse
(kwargs
["descriptor"], kwargs
.get("descriptor_format") )
883 descriptor
= kwargs
["descriptor"]
884 elif "name" in kwargs
:
885 descriptor
={item
[:-1]: {"name": kwargs
["name"]}}
887 raise OpenmanoResponseException("Missing descriptor")
889 if item
[:-1] not in descriptor
or len(descriptor
)!=1:
890 raise OpenmanoBadParamsException("Descriptor must contain only one 'tenant' field")
892 descriptor
[ item
[:-1] ]['name'] = kwargs
["name"]
893 if "description" in kwargs
:
894 descriptor
[ item
[:-1] ]['description'] = kwargs
["description"]
895 payload_req
= yaml
.safe_dump(descriptor
)
897 URLrequest
= "{}{}/vim/{}/{}".format(self
.endpoint_url
, tenant_text
, datacenter
, item
)
898 self
.logger
.debug("openmano POST %s %s", URLrequest
, payload_req
)
899 mano_response
= requests
.post(URLrequest
, headers
= self
.headers_req
, data
=payload_req
)
900 self
.logger
.debug("openmano response: %s", mano_response
.text
)
901 content
= self
._parse
_yaml
(mano_response
.text
, response
=True)
902 if mano_response
.status_code
==200:
905 raise OpenmanoResponseException(str(content
))
907 raise OpenmanoBadParamsException("Unknown value for action '{}".format(str(action
)))