2 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
3 # This file is part of openmano
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
18 # For those usages not covered by the Apache License, Version 2.0 please
19 # contact with: nfvlabs@tid.es
23 vimconnector implements all the methods to interact with openvim using the openvim API.
25 __author__
="Alfonso Tierno, Gerardo Garcia"
26 __date__
="$26-aug-2014 11:09:29$"
33 from .openmano_schemas
import id_schema
, name_schema
, nameshort_schema
, description_schema
, \
34 vlan1000_schema
, integer0_schema
35 from jsonschema
import validate
as js_v
, exceptions
as js_e
37 '''contain the openvim virtual machine status to openmano status'''
38 vmStatus2manoFormat
={'ACTIVE':'ACTIVE',
40 'SUSPENDED': 'SUSPENDED',
41 'INACTIVE':'INACTIVE',
43 'ERROR':'ERROR','DELETED':'DELETED'
45 netStatus2manoFormat
={'ACTIVE':'ACTIVE','INACTIVE':'INACTIVE','BUILD':'BUILD','ERROR':'ERROR','DELETED':'DELETED', 'DOWN':'DOWN'
63 "required": ["id","name"]
71 "required": ["id","name"]
79 "required": ["id","name"]
81 new_host_response_schema
= {
82 "title":"host response information schema",
83 "$schema": "http://json-schema.org/draft-04/schema#",
89 "additionalProperties": False
92 get_images_response_schema
= {
93 "title":"openvim images response information schema",
94 "$schema": "http://json-schema.org/draft-04/schema#",
99 "items": image_schema
,
102 "required": ["images"],
103 "additionalProperties": False
107 get_flavors_response_schema
= {
108 "title":"openvim flavors response information schema",
109 "$schema": "http://json-schema.org/draft-04/schema#",
114 "items": flavor_schema
,
117 "required": ["flavors"],
118 "additionalProperties": False
122 get_hosts_response_schema
= {
123 "title":"openvim hosts response information schema",
124 "$schema": "http://json-schema.org/draft-04/schema#",
129 "items": host_schema
,
132 "required": ["hosts"],
133 "additionalProperties": False
136 get_host_detail_response_schema
= new_host_response_schema
# TODO: Content is not parsed yet
138 get_server_response_schema
= {
139 "title":"openvim server response information schema",
140 "$schema": "http://json-schema.org/draft-04/schema#",
145 "items": server_schema
,
148 "required": ["servers"],
149 "additionalProperties": False
152 new_tenant_response_schema
= {
153 "title":"tenant response information schema",
154 "$schema": "http://json-schema.org/draft-04/schema#",
161 "name": nameshort_schema
,
162 "description":description_schema
,
163 "enabled":{"type" : "boolean"}
168 "required": ["tenant"],
169 "additionalProperties": False
172 new_network_response_schema
= {
173 "title":"network response information schema",
174 "$schema": "http://json-schema.org/draft-04/schema#",
182 "type":{"type":"string", "enum":["bridge_man","bridge_data","data", "ptp"]},
183 "shared":{"type":"boolean"},
184 "tenant_id":id_schema
,
185 "admin_state_up":{"type":"boolean"},
186 "vlan":vlan1000_schema
191 "required": ["network"],
192 "additionalProperties": False
196 # get_network_response_schema = {
197 # "title":"get network response information schema",
198 # "$schema": "http://json-schema.org/draft-04/schema#",
205 # "name":name_schema,
206 # "type":{"type":"string", "enum":["bridge_man","bridge_data","data", "ptp"]},
207 # "shared":{"type":"boolean"},
208 # "tenant_id":id_schema,
209 # "admin_state_up":{"type":"boolean"},
210 # "vlan":vlan1000_schema
215 # "required": ["network"],
216 # "additionalProperties": False
220 new_port_response_schema
= {
221 "title":"port response information schema",
222 "$schema": "http://json-schema.org/draft-04/schema#",
233 "required": ["port"],
234 "additionalProperties": False
237 get_flavor_response_schema
= {
238 "title":"openvim flavors response information schema",
239 "$schema": "http://json-schema.org/draft-04/schema#",
247 #"extended": {"type":"object"},
249 "required": ["id", "name"],
252 "required": ["flavor"],
253 "additionalProperties": False
256 new_flavor_response_schema
= {
257 "title":"flavor response information schema",
258 "$schema": "http://json-schema.org/draft-04/schema#",
269 "required": ["flavor"],
270 "additionalProperties": False
273 get_image_response_schema
= {
274 "title":"openvim images response information schema",
275 "$schema": "http://json-schema.org/draft-04/schema#",
284 "required": ["id", "name"],
287 "required": ["image"],
288 "additionalProperties": False
290 new_image_response_schema
= {
291 "title":"image response information schema",
292 "$schema": "http://json-schema.org/draft-04/schema#",
303 "required": ["image"],
304 "additionalProperties": False
307 new_vminstance_response_schema
= {
308 "title":"server response information schema",
309 "$schema": "http://json-schema.org/draft-04/schema#",
320 "required": ["server"],
321 "additionalProperties": False
324 get_processor_rankings_response_schema
= {
325 "title":"processor rankings information schema",
326 "$schema": "http://json-schema.org/draft-04/schema#",
334 "model": description_schema
,
335 "value": integer0_schema
337 "additionalProperties": False,
338 "required": ["model","value"]
341 "additionalProperties": False,
342 "required": ["rankings"]
346 class vimconnector(vimconn
.vimconnector
):
347 def __init__(self
, uuid
, name
, tenant_id
, tenant_name
, url
, url_admin
=None, user
=None, passwd
=None,log_level
="DEBUG",config
={}):
348 vimconn
.vimconnector
.__init
__(self
, uuid
, name
, tenant_id
, tenant_name
, url
, url_admin
, user
, passwd
, log_level
, config
)
350 self
.headers_req
= {'content-type': 'application/json'}
351 self
.logger
= logging
.getLogger('mano.vim.openvim')
353 self
.tenant
= tenant_id
355 def __setitem__(self
,index
, value
):
356 '''Set individuals parameters
357 Throw TypeError, KeyError
359 if index
=='tenant_id':
361 elif index
=='tenant_name':
363 vimconn
.vimconnector
.__setitem
__(self
,index
, value
)
365 def _get_my_tenant(self
):
366 '''Obtain uuid of my tenant from name
371 url
= self
.url
+'/tenants?name='+ self
.tenant_name
372 self
.logger
.info("Getting VIM tenant_id GET %s", url
)
373 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
374 self
._check
_http
_request
_response
(vim_response
)
376 tenant_list
= vim_response
.json()["tenants"]
377 if len(tenant_list
) == 0:
378 raise vimconn
.vimconnNotFoundException("No tenant found for name '%s'" % str(self
.tenant_name
))
379 elif len(tenant_list
) > 1:
380 raise vimconn
.vimconnConflictException ("More that one tenant found for name '%s'" % str(self
.tenant_name
))
381 self
.tenant
= tenant_list
[0]["id"]
383 except Exception as e
:
384 raise vimconn
.vimconnUnexpectedResponse("Get VIM tenant {} '{}'".format(type(e
).__name
__, str(e
)))
386 def _format_jsonerror(self
,http_response
):
387 #DEPRECATED, to delete in the future
389 data
= http_response
.json()
390 return data
["error"]["description"]
392 return http_response
.text
394 def _format_in(self
, http_response
, schema
):
395 #DEPRECATED, to delete in the future
397 client_data
= http_response
.json()
398 js_v(client_data
, schema
)
399 #print "Input data: ", str(client_data)
400 return True, client_data
401 except js_e
.ValidationError
as exc
:
402 print("validate_in error, jsonschema exception {} at {}",exc
.message
, exc
.path
)
403 return False, ("validate_in error, jsonschema exception ", exc
.message
, "at", exc
.path
)
405 def _remove_extra_items(self
, data
, schema
):
407 if type(data
) is tuple or type(data
) is list:
409 a
= self
._remove
_extra
_items
(d
, schema
['items'])
410 if a
is not None: deleted
.append(a
)
411 elif type(data
) is dict:
412 #for k in data.keys():
414 if 'properties' not in schema
or k
not in schema
['properties'].keys():
418 a
= self
._remove
_extra
_items
(data
[k
], schema
['properties'][k
])
419 if a
is not None: deleted
.append({k
:a
})
420 if len(deleted
) == 0: return None
421 elif len(deleted
) == 1: return deleted
[0]
424 def _format_request_exception(self
, request_exception
):
425 '''Transform a request exception into a vimconn exception'''
426 if isinstance(request_exception
, js_e
.ValidationError
):
427 raise vimconn
.vimconnUnexpectedResponse("jsonschema exception '{}' at '{}'".format(request_exception
.message
, request_exception
.path
))
428 elif isinstance(request_exception
, requests
.exceptions
.HTTPError
):
429 raise vimconn
.vimconnUnexpectedResponse(type(request_exception
).__name
__ + ": " + str(request_exception
))
431 raise vimconn
.vimconnConnectionException(type(request_exception
).__name
__ + ": " + str(request_exception
))
433 def _check_http_request_response(self
, request_response
):
434 '''Raise a vimconn exception if the response is not Ok'''
435 if request_response
.status_code
>= 200 and request_response
.status_code
< 300:
437 if request_response
.status_code
== vimconn
.HTTP_Unauthorized
:
438 raise vimconn
.vimconnAuthException(request_response
.text
)
439 elif request_response
.status_code
== vimconn
.HTTP_Not_Found
:
440 raise vimconn
.vimconnNotFoundException(request_response
.text
)
441 elif request_response
.status_code
== vimconn
.HTTP_Conflict
:
442 raise vimconn
.vimconnConflictException(request_response
.text
)
444 raise vimconn
.vimconnUnexpectedResponse("VIM HTTP_response {}, {}".format(request_response
.status_code
, str(request_response
.text
)))
446 def new_tenant(self
,tenant_name
,tenant_description
):
447 '''Adds a new tenant to VIM with this name and description, returns the tenant identifier'''
448 #print "VIMConnector: Adding a new tenant to VIM"
449 payload_dict
= {"tenant": {"name":tenant_name
,"description": tenant_description
, "enabled": True}}
450 payload_req
= json
.dumps(payload_dict
)
452 url
= self
.url_admin
+'/tenants'
453 self
.logger
.info("Adding a new tenant %s", url
)
454 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=payload_req
)
455 self
._check
_http
_request
_response
(vim_response
)
456 self
.logger
.debug(vim_response
.text
)
457 #print json.dumps(vim_response.json(), indent=4)
458 response
= vim_response
.json()
459 js_v(response
, new_tenant_response_schema
)
460 #r = self._remove_extra_items(response, new_tenant_response_schema)
462 # self.logger.warn("Warning: remove extra items %s", str(r))
463 tenant_id
= response
['tenant']['id']
465 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
466 self
._format
_request
_exception
(e
)
468 def delete_tenant(self
,tenant_id
):
469 '''Delete a tenant from VIM. Returns the old tenant identifier'''
471 url
= self
.url_admin
+'/tenants/'+tenant_id
472 self
.logger
.info("Delete a tenant DELETE %s", url
)
473 vim_response
= requests
.delete(url
, headers
= self
.headers_req
)
474 self
._check
_http
_request
_response
(vim_response
)
475 self
.logger
.debug(vim_response
.text
)
476 #print json.dumps(vim_response.json(), indent=4)
478 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
479 self
._format
_request
_exception
(e
)
481 def get_tenant_list(self
, filter_dict
={}):
482 '''Obtain tenants of VIM
483 filter_dict can contain the following keys:
484 name: filter by tenant name
485 id: filter by tenant uuid/id
487 Returns the tenant list of dictionaries: [{'name':'<name>, 'id':'<id>, ...}, ...]
491 for k
,v
in filter_dict
.items():
492 filterquery
.append(str(k
)+'='+str(v
))
493 if len(filterquery
)>0:
494 filterquery_text
='?'+ '&'.join(filterquery
)
496 url
= self
.url
+'/tenants'+filterquery_text
497 self
.logger
.info("get_tenant_list GET %s", url
)
498 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
499 self
._check
_http
_request
_response
(vim_response
)
500 self
.logger
.debug(vim_response
.text
)
501 #print json.dumps(vim_response.json(), indent=4)
502 return vim_response
.json()["tenants"]
503 except requests
.exceptions
.RequestException
as e
:
504 self
._format
_request
_exception
(e
)
506 def new_network(self
,net_name
,net_type
, shared
=False, **vim_specific
):
507 '''Adds a tenant network to VIM'''
508 '''Returns the network identifier'''
510 self
._get
_my
_tenant
()
511 if net_type
=="bridge":
512 net_type
="bridge_data"
513 payload_req
= {"name": net_name
, "type": net_type
, "tenant_id": self
.tenant
, "shared": shared
}
514 payload_req
.update(vim_specific
)
515 url
= self
.url
+'/networks'
516 self
.logger
.info("Adding a new network POST: %s DATA: %s", url
, str(payload_req
))
518 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=json
.dumps({"network": payload_req
}) )
519 self
._check
_http
_request
_response
(vim_response
)
520 self
.logger
.debug(vim_response
.text
)
521 #print json.dumps(vim_response.json(), indent=4)
522 response
= vim_response
.json()
523 js_v(response
, new_network_response_schema
)
524 #r = self._remove_extra_items(response, new_network_response_schema)
526 # self.logger.warn("Warning: remove extra items %s", str(r))
527 network_id
= response
['network']['id']
529 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
530 self
._format
_request
_exception
(e
)
532 def get_network_list(self
, filter_dict
={}):
533 '''Obtain tenant networks of VIM
539 admin_state_up: boolean
541 Returns the network list of dictionaries
544 if 'tenant_id' not in filter_dict
:
545 filter_dict
["tenant_id"] = self
._get
_my
_tenant
()
546 elif not filter_dict
["tenant_id"]:
547 del filter_dict
["tenant_id"]
550 for k
,v
in filter_dict
.items():
551 filterquery
.append(str(k
)+'='+str(v
))
552 if len(filterquery
)>0:
553 filterquery_text
='?'+ '&'.join(filterquery
)
554 url
= self
.url
+'/networks'+filterquery_text
555 self
.logger
.info("Getting network list GET %s", url
)
556 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
557 self
._check
_http
_request
_response
(vim_response
)
558 self
.logger
.debug(vim_response
.text
)
559 #print json.dumps(vim_response.json(), indent=4)
560 response
= vim_response
.json()
561 return response
['networks']
562 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
563 self
._format
_request
_exception
(e
)
565 def get_network(self
, net_id
):
566 '''Obtain network details of network id'''
568 url
= self
.url
+'/networks/'+net_id
569 self
.logger
.info("Getting network GET %s", url
)
570 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
571 self
._check
_http
_request
_response
(vim_response
)
572 self
.logger
.debug(vim_response
.text
)
573 #print json.dumps(vim_response.json(), indent=4)
574 response
= vim_response
.json()
575 return response
['network']
576 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
577 self
._format
_request
_exception
(e
)
579 def delete_network(self
, net_id
):
580 '''Deletes a tenant network from VIM'''
581 '''Returns the network identifier'''
583 self
._get
_my
_tenant
()
584 url
= self
.url
+'/networks/'+net_id
585 self
.logger
.info("Deleting VIM network DELETE %s", url
)
586 vim_response
= requests
.delete(url
, headers
=self
.headers_req
)
587 self
._check
_http
_request
_response
(vim_response
)
588 #self.logger.debug(vim_response.text)
589 #print json.dumps(vim_response.json(), indent=4)
591 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
592 self
._format
_request
_exception
(e
)
595 def get_flavor_list(self
):
596 '''Obtain flavor details from the VIM'''
598 self
._get
_my
_tenant
()
599 url
= self
.url
+'/'+self
.tenant
+'/flavors'
600 self
.logger
.info("Getting flavor GET %s", url
)
601 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
602 self
._check
_http
_request
_response
(vim_response
)
603 self
.logger
.debug(vim_response
.text
)
604 #print json.dumps(vim_response.json(), indent=4)
605 response
= vim_response
.json()
606 js_v(response
, get_flavors_response_schema
)
607 r
= self
._remove
_extra
_items
(response
, get_flavors_response_schema
)
609 self
.logger
.warn("Warning: remove extra items %s", str(r
))
610 return response
['flavors']
611 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
612 self
._format
_request
_exception
(e
)
615 def get_flavor(self
, flavor_id
):
616 '''Obtain flavor details from the VIM'''
618 self
._get
_my
_tenant
()
619 url
= self
.url
+'/'+self
.tenant
+'/flavors/'+flavor_id
620 self
.logger
.info("Getting flavor GET %s", url
)
621 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
622 self
._check
_http
_request
_response
(vim_response
)
623 self
.logger
.debug(vim_response
.text
)
624 #print json.dumps(vim_response.json(), indent=4)
625 response
= vim_response
.json()
626 js_v(response
, get_flavor_response_schema
)
627 #r = self._remove_extra_items(response, get_flavor_response_schema)
629 # self.logger.warn("Warning: remove extra items %s", str(r))
630 return response
['flavor']
631 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
632 self
._format
_request
_exception
(e
)
634 def new_flavor(self
, flavor_data
):
635 '''Adds a tenant flavor to VIM'''
636 '''Returns the flavor identifier'''
638 self
._get
_my
_tenant
()
639 payload_req
= json
.dumps({'flavor': flavor_data
})
640 url
= self
.url
+'/'+self
.tenant
+'/flavors'
641 self
.logger
.info("Adding a new VIM flavor POST %s", url
)
642 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=payload_req
)
643 self
._check
_http
_request
_response
(vim_response
)
644 self
.logger
.debug(vim_response
.text
)
645 #print json.dumps(vim_response.json(), indent=4)
646 response
= vim_response
.json()
647 js_v(response
, new_flavor_response_schema
)
648 r
= self
._remove
_extra
_items
(response
, new_flavor_response_schema
)
650 self
.logger
.warn("Warning: remove extra items %s", str(r
))
651 flavor_id
= response
['flavor']['id']
653 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
654 self
._format
_request
_exception
(e
)
656 def delete_flavor(self
,flavor_id
):
657 '''Deletes a tenant flavor from VIM'''
658 '''Returns the old flavor_id'''
660 self
._get
_my
_tenant
()
661 url
= self
.url
+'/'+self
.tenant
+'/flavors/'+flavor_id
662 self
.logger
.info("Deleting VIM flavor DELETE %s", url
)
663 vim_response
= requests
.delete(url
, headers
=self
.headers_req
)
664 self
._check
_http
_request
_response
(vim_response
)
665 #self.logger.debug(vim_response.text)
666 #print json.dumps(vim_response.json(), indent=4)
668 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
669 self
._format
_request
_exception
(e
)
671 def get_image_list(self
):
672 '''Obtain image details from the VIM'''
674 self
._get
_my
_tenant
()
675 url
= self
.url
+'/'+self
.tenant
+'/images'
676 self
.logger
.info("Getting image GET %s", url
)
677 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
678 self
._check
_http
_request
_response
(vim_response
)
679 self
.logger
.debug(vim_response
.text
)
680 #print json.dumps(vim_response.json(), indent=4)
681 response
= vim_response
.json()
682 js_v(response
, get_images_response_schema
)
683 #r = self._remove_extra_items(response, get_images_response_schema)
685 # self.logger.warn("Warning: remove extra items %s", str(r))
686 return response
['images']
687 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
688 self
._format
_request
_exception
(e
)
690 def get_image(self
, image_id
):
691 '''Obtain image details from the VIM'''
693 self
._get
_my
_tenant
()
694 url
= self
.url
+'/'+self
.tenant
+'/images/'+image_id
695 self
.logger
.info("Getting image GET %s", url
)
696 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
697 self
._check
_http
_request
_response
(vim_response
)
698 self
.logger
.debug(vim_response
.text
)
699 #print json.dumps(vim_response.json(), indent=4)
700 response
= vim_response
.json()
701 js_v(response
, get_image_response_schema
)
702 #r = self._remove_extra_items(response, get_image_response_schema)
704 # self.logger.warn("Warning: remove extra items %s", str(r))
705 return response
['image']
706 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
707 self
._format
_request
_exception
(e
)
709 def new_image(self
,image_dict
):
710 ''' Adds a tenant image to VIM, returns image_id'''
712 self
._get
_my
_tenant
()
713 new_image_dict
={'name': image_dict
['name']}
714 if image_dict
.get('description'):
715 new_image_dict
['description'] = image_dict
['description']
716 if image_dict
.get('metadata'):
717 new_image_dict
['metadata'] = yaml
.load(image_dict
['metadata'])
718 if image_dict
.get('location'):
719 new_image_dict
['path'] = image_dict
['location']
720 payload_req
= json
.dumps({"image":new_image_dict
})
721 url
=self
.url
+ '/' + self
.tenant
+ '/images'
722 self
.logger
.info("Adding a new VIM image POST %s", url
)
723 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=payload_req
)
724 self
._check
_http
_request
_response
(vim_response
)
725 self
.logger
.debug(vim_response
.text
)
726 #print json.dumps(vim_response.json(), indent=4)
727 response
= vim_response
.json()
728 js_v(response
, new_image_response_schema
)
729 r
= self
._remove
_extra
_items
(response
, new_image_response_schema
)
731 self
.logger
.warn("Warning: remove extra items %s", str(r
))
732 image_id
= response
['image']['id']
734 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
735 self
._format
_request
_exception
(e
)
737 def delete_image(self
, image_id
):
738 '''Deletes a tenant image from VIM'''
739 '''Returns the deleted image_id'''
741 self
._get
_my
_tenant
()
742 url
= self
.url
+ '/'+ self
.tenant
+'/images/'+image_id
743 self
.logger
.info("Deleting VIM image DELETE %s", url
)
744 vim_response
= requests
.delete(url
, headers
=self
.headers_req
)
745 self
._check
_http
_request
_response
(vim_response
)
746 #self.logger.debug(vim_response.text)
747 #print json.dumps(vim_response.json(), indent=4)
749 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
750 self
._format
_request
_exception
(e
)
753 def get_image_id_from_path(self
, path
):
754 '''Get the image id from image path in the VIM database'''
756 self
._get
_my
_tenant
()
757 url
=self
.url
+ '/' + self
.tenant
+ '/images?path='+path
758 self
.logger
.info("Getting images GET %s", url
)
759 vim_response
= requests
.get(url
)
760 self
._check
_http
_request
_response
(vim_response
)
761 self
.logger
.debug(vim_response
.text
)
762 #print json.dumps(vim_response.json(), indent=4)
763 response
= vim_response
.json()
764 js_v(response
, get_images_response_schema
)
765 #r = self._remove_extra_items(response, get_images_response_schema)
767 # self.logger.warn("Warning: remove extra items %s", str(r))
768 if len(response
['images'])==0:
769 raise vimconn
.vimconnNotFoundException("Image not found at VIM with path '%s'", path
)
770 elif len(response
['images'])>1:
771 raise vimconn
.vimconnConflictException("More than one image found at VIM with path '%s'", path
)
772 return response
['images'][0]['id']
773 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
774 self
._format
_request
_exception
(e
)
776 def new_vminstancefromJSON(self
, vm_data
):
777 '''Adds a VM instance to VIM'''
778 '''Returns the instance identifier'''
780 self
._get
_my
_tenant
()
781 except Exception as e
:
782 return -vimconn
.HTTP_Not_Found
, str(e
)
783 print("VIMConnector: Adding a new VM instance from JSON to VIM")
784 payload_req
= vm_data
786 vim_response
= requests
.post(self
.url
+'/'+self
.tenant
+'/servers', headers
= self
.headers_req
, data
=payload_req
)
787 except requests
.exceptions
.RequestException
as e
:
788 print("new_vminstancefromJSON Exception: ", e
.args
)
789 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
791 #print vim_response.status_code
792 if vim_response
.status_code
== 200:
793 #print vim_response.json()
794 #print json.dumps(vim_response.json(), indent=4)
795 res
,http_content
= self
._format
_in
(vim_response
, new_image_response_schema
)
798 r
= self
._remove
_extra
_items
(http_content
, new_image_response_schema
)
799 if r
is not None: print("Warning: remove extra items {}", r
)
801 vminstance_id
= http_content
['server']['id']
802 print("Tenant image id: ",vminstance_id
)
803 return vim_response
.status_code
,vminstance_id
804 else: return -vimconn
.HTTP_Bad_Request
,http_content
806 #print vim_response.text
807 jsonerror
= self
._format
_jsonerror
(vim_response
)
808 text
= 'Error in VIM "%s": not possible to add new vm instance. HTTP Response: %d. Error: %s' % (self
.url
, vim_response
.status_code
, jsonerror
)
810 return -vim_response
.status_code
,text
812 def new_vminstance(self
,name
,description
,start
,image_id
,flavor_id
,net_list
):
813 '''Adds a VM instance to VIM
815 start: indicates if VM must start or boot in pause mode. Ignored
816 image_id,flavor_id: image and flavor uuid
817 net_list: list of interfaces, each one is a dictionary with:
819 net_id: network uuid to connect
820 vpci: virtual vcpi to assign
821 model: interface model, virtio, e2000, ...
823 use: 'data', 'bridge', 'mgmt'
824 type: 'virtual', 'PF', 'VF', 'VFnotShared'
825 vim_id: filled/added by this function
826 #TODO ip, security groups
827 Returns the instance identifier
830 self
._get
_my
_tenant
()
832 # for k,v in net_dict.items():
834 # net_list.append('{"name":"' + k + '", "uuid":"' + v + '"}')
835 # net_list_string = ', '.join(net_list)
838 if not net
.get("net_id"):
840 net_dict
={'uuid': net
["net_id"]}
841 if net
.get("type"): net_dict
["type"] = net
["type"]
842 if net
.get("name"): net_dict
["name"] = net
["name"]
843 if net
.get("vpci"): net_dict
["vpci"] = net
["vpci"]
844 if net
.get("model"): net_dict
["model"] = net
["model"]
845 if net
.get("mac_address"): net_dict
["mac_address"] = net
["mac_address"]
846 virtio_net_list
.append(net_dict
)
847 payload_dict
={ "name": name
,
848 "description": description
,
849 "imageRef": image_id
,
850 "flavorRef": flavor_id
,
851 "networks": virtio_net_list
854 payload_dict
["start"] = start
855 payload_req
= json
.dumps({"server": payload_dict
})
856 url
= self
.url
+'/'+self
.tenant
+'/servers'
857 self
.logger
.info("Adding a new vm POST %s DATA %s", url
, payload_req
)
858 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=payload_req
)
859 self
._check
_http
_request
_response
(vim_response
)
860 self
.logger
.debug(vim_response
.text
)
861 #print json.dumps(vim_response.json(), indent=4)
862 response
= vim_response
.json()
863 js_v(response
, new_vminstance_response_schema
)
864 #r = self._remove_extra_items(response, new_vminstance_response_schema)
866 # self.logger.warn("Warning: remove extra items %s", str(r))
867 vminstance_id
= response
['server']['id']
869 #connect data plane interfaces to network
871 if net
["type"]=="virtual":
872 if not net
.get("net_id"):
874 for iface
in response
['server']['networks']:
876 if net
["name"]==iface
["name"]:
877 net
["vim_id"] = iface
['iface_id']
879 elif "net_id" in net
:
880 if net
["net_id"]==iface
["net_id"]:
881 net
["vim_id"] = iface
['iface_id']
884 for numa
in response
['server'].get('extended',{}).get('numas',() ):
885 for iface
in numa
.get('interfaces',() ):
886 if net
['name'] == iface
['name']:
887 net
['vim_id'] = iface
['iface_id']
888 #Code bellow is not needed, current openvim connect dataplane interfaces
889 #if net.get("net_id"):
890 ##connect dataplane interface
891 # result, port_id = self.connect_port_network(iface['iface_id'], net["net_id"])
893 # error_text = "Error attaching port %s to network %s: %s." % (iface['iface_id'], net["net_id"], port_id)
894 # print "new_vminstance: " + error_text
895 # self.delete_vminstance(vminstance_id)
896 # return result, error_text
900 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
901 self
._format
_request
_exception
(e
)
904 def get_vminstance_list(self
):
905 '''Obtain VM instance list from the VIM'''
907 self
._get
_my
_tenant
()
908 url
= self
.url
+'/'+self
.tenant
+'/servers'
909 self
.logger
.info("Getting servers GET %s", url
)
910 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
911 self
._check
_http
_request
_response
(vim_response
)
912 self
.logger
.debug(vim_response
.text
)
913 #print json.dumps(vim_response.json(), indent=4)
914 response
= vim_response
.json()
915 js_v(response
, get_server_response_schema
)
916 r
= self
._remove
_extra
_items
(response
, get_server_response_schema
)
918 self
.logger
.warn("Warning: remove extra items %s", str(r
))
919 return response
['servers']
920 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
921 self
._format
_request
_exception
(e
)
924 def get_vminstance(self
, vm_id
):
925 '''Returns the VM instance information from VIM'''
927 self
._get
_my
_tenant
()
928 url
= self
.url
+'/'+self
.tenant
+'/servers/'+vm_id
929 self
.logger
.info("Getting vm GET %s", url
)
930 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
931 self
._check
_http
_request
_response
(vim_response
)
932 self
.logger
.debug(vim_response
.text
)
933 #print json.dumps(vim_response.json(), indent=4)
934 response
= vim_response
.json()
935 js_v(response
, new_vminstance_response_schema
)
936 #r = self._remove_extra_items(response, new_vminstance_response_schema)
938 # self.logger.warn("Warning: remove extra items %s", str(r))
939 return response
['server']
940 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
941 self
._format
_request
_exception
(e
)
943 def delete_vminstance(self
, vm_id
):
944 '''Removes a VM instance from VIM, returns the deleted vm_id'''
946 self
._get
_my
_tenant
()
947 url
= self
.url
+'/'+self
.tenant
+'/servers/'+vm_id
948 self
.logger
.info("Deleting VIM vm DELETE %s", url
)
949 vim_response
= requests
.delete(url
, headers
=self
.headers_req
)
950 self
._check
_http
_request
_response
(vim_response
)
951 #self.logger.debug(vim_response.text)
952 #print json.dumps(vim_response.json(), indent=4)
954 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
955 self
._format
_request
_exception
(e
)
957 def refresh_vms_status(self
, vm_list
):
958 '''Refreshes the status of the virtual machines'''
960 self
._get
_my
_tenant
()
961 except requests
.exceptions
.RequestException
as e
:
962 self
._format
_request
_exception
(e
)
964 for vm_id
in vm_list
:
966 #print "VIMConnector refresh_tenant_vms and nets: Getting tenant VM instance information from VIM"
968 url
= self
.url
+'/'+self
.tenant
+'/servers/'+ vm_id
969 self
.logger
.info("Getting vm GET %s", url
)
970 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
971 self
._check
_http
_request
_response
(vim_response
)
972 response
= vim_response
.json()
973 js_v(response
, new_vminstance_response_schema
)
974 if response
['server']['status'] in vmStatus2manoFormat
:
975 vm
['status'] = vmStatus2manoFormat
[ response
['server']['status'] ]
977 vm
['status'] = "OTHER"
978 vm
['error_msg'] = "VIM status reported " + response
['server']['status']
979 if response
['server'].get('last_error'):
980 vm
['error_msg'] = response
['server']['last_error']
981 vm
["vim_info"] = yaml
.safe_dump(response
['server'])
984 management_ip
= False
985 url2
= self
.url
+'/ports?device_id='+ vm_id
986 self
.logger
.info("Getting PORTS GET %s", url2
)
987 vim_response2
= requests
.get(url2
, headers
= self
.headers_req
)
988 self
._check
_http
_request
_response
(vim_response2
)
989 client_data
= vim_response2
.json()
990 if isinstance(client_data
.get("ports"), list):
992 for port
in client_data
.get("ports"):
994 interface
['vim_info'] = yaml
.safe_dump(port
)
995 interface
["mac_address"] = port
.get("mac_address")
996 interface
["vim_net_id"] = port
["network_id"]
997 interface
["vim_interface_id"] = port
["id"]
998 interface
["ip_address"] = port
.get("ip_address")
999 if interface
["ip_address"]:
1000 management_ip
= True
1001 if interface
["ip_address"] == "0.0.0.0":
1002 interface
["ip_address"] = None
1003 vm
["interfaces"].append(interface
)
1005 except Exception as e
:
1006 self
.logger
.error("refresh_vms_and_nets. Port get %s: %s", type(e
).__name
__, str(e
))
1008 if vm
['status'] == "ACTIVE" and not management_ip
:
1009 vm
['status'] = "ACTIVE:NoMgmtIP"
1011 except vimconn
.vimconnNotFoundException
as e
:
1012 self
.logger
.error("Exception getting vm status: %s", str(e
))
1013 vm
['status'] = "DELETED"
1014 vm
['error_msg'] = str(e
)
1015 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
, vimconn
.vimconnException
) as e
:
1016 self
.logger
.error("Exception getting vm status: %s", str(e
))
1017 vm
['status'] = "VIM_ERROR"
1018 vm
['error_msg'] = str(e
)
1022 def refresh_nets_status(self
, net_list
):
1023 '''Get the status of the networks
1024 Params: the list of network identifiers
1025 Returns a dictionary with:
1026 net_id: #VIM id of this network
1027 status: #Mandatory. Text with one of:
1028 # DELETED (not found at vim)
1029 # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
1030 # OTHER (Vim reported other status not understood)
1031 # ERROR (VIM indicates an ERROR status)
1032 # ACTIVE, INACTIVE, DOWN (admin down),
1033 # BUILD (on building process)
1035 error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
1036 vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
1040 self
._get
_my
_tenant
()
1041 except requests
.exceptions
.RequestException
as e
:
1042 self
._format
_request
_exception
(e
)
1045 for net_id
in net_list
:
1047 #print "VIMConnector refresh_tenant_vms_and_nets: Getting tenant network from VIM (tenant: " + str(self.tenant) + "): "
1049 net_vim
= self
.get_network(net_id
)
1050 if net_vim
['status'] in netStatus2manoFormat
:
1051 net
["status"] = netStatus2manoFormat
[ net_vim
['status'] ]
1053 net
["status"] = "OTHER"
1054 net
["error_msg"] = "VIM status reported " + net_vim
['status']
1056 if net
["status"] == "ACTIVE" and not net_vim
['admin_state_up']:
1057 net
["status"] = "DOWN"
1058 if net_vim
.get('last_error'):
1059 net
['error_msg'] = net_vim
['last_error']
1060 net
["vim_info"] = yaml
.safe_dump(net_vim
)
1061 except vimconn
.vimconnNotFoundException
as e
:
1062 self
.logger
.error("Exception getting net status: %s", str(e
))
1063 net
['status'] = "DELETED"
1064 net
['error_msg'] = str(e
)
1065 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
, vimconn
.vimconnException
) as e
:
1066 self
.logger
.error("Exception getting net status: %s", str(e
))
1067 net
['status'] = "VIM_ERROR"
1068 net
['error_msg'] = str(e
)
1069 net_dict
[net_id
] = net
1072 def action_vminstance(self
, vm_id
, action_dict
):
1073 '''Send and action over a VM instance from VIM'''
1074 '''Returns the status'''
1076 self
._get
_my
_tenant
()
1077 if "console" in action_dict
:
1078 raise vimconn
.vimconnException("getting console is not available at openvim", http_code
=vimconn
.HTTP_Service_Unavailable
)
1079 url
= self
.url
+'/'+self
.tenant
+'/servers/'+vm_id
+"/action"
1080 self
.logger
.info("Action over VM instance POST %s", url
)
1081 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=json
.dumps(action_dict
) )
1082 self
._check
_http
_request
_response
(vim_response
)
1084 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
1085 self
._format
_request
_exception
(e
)
1087 #NOT USED METHODS in current version
1089 def host_vim2gui(self
, host
, server_dict
):
1090 '''Transform host dictionary from VIM format to GUI format,
1091 and append to the server_dict
1093 if type(server_dict
) is not dict:
1094 print('vimconnector.host_vim2gui() ERROR, param server_dict must be a dictionary')
1098 for numa
in host
['host']['numas']:
1102 RAD_item
['memory']={'size': str(numa
['memory'])+'GB', 'eligible': str(numa
['hugepages'])+'GB'}
1103 occupation_item
['memory']= str(numa
['hugepages_consumed'])+'GB'
1106 RAD_item
['cpus']['cores'] = []
1107 RAD_item
['cpus']['eligible_cores'] = []
1108 occupation_item
['cores']=[]
1109 for _
in range(0, len(numa
['cores']) / 2):
1110 RAD_item
['cpus']['cores'].append( [] )
1111 for core
in numa
['cores']:
1112 RAD_item
['cpus']['cores'][core
['core_id']].append(core
['thread_id'])
1113 if not 'status' in core
: RAD_item
['cpus']['eligible_cores'].append(core
['thread_id'])
1114 if 'instance_id' in core
: occupation_item
['cores'].append(core
['thread_id'])
1116 RAD_item
['ports']={}
1117 occupation_item
['ports']={}
1118 for iface
in numa
['interfaces']:
1119 RAD_item
['ports'][ iface
['pci'] ] = 'speed:'+str(iface
['Mbps'])+'M'
1120 occupation_item
['ports'][ iface
['pci'] ] = { 'occupied': str(100*iface
['Mbps_consumed'] / iface
['Mbps']) + "%" }
1122 RAD
[ numa
['numa_socket'] ] = RAD_item
1123 occupation
[ numa
['numa_socket'] ] = occupation_item
1124 server_dict
[ host
['host']['name'] ] = {'RAD':RAD
, 'occupation':occupation
}
1126 def get_hosts_info(self
):
1127 '''Get the information of deployed hosts
1128 Returns the hosts content'''
1130 url
=self
.url
+'/hosts'
1132 vim_response
= requests
.get(url
)
1133 except requests
.exceptions
.RequestException
as e
:
1134 print("get_hosts_info Exception: {}", e
.args
)
1135 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1136 print("vim get {}, response:{} {}",url
, vim_response
.status_code
, vim_response
.json())
1137 #print vim_response.status_code
1138 #print json.dumps(vim_response.json(), indent=4)
1139 if vim_response
.status_code
!= 200:
1141 print('vimconnector.get_hosts_info error getting host list %d %s',vim_response
.status_code
, vim_response
.json())
1142 return -vim_response
.status_code
, "Error getting host list"
1144 res
,hosts
= self
._format
_in
(vim_response
, get_hosts_response_schema
)
1147 print("vimconnector.get_hosts_info error parsing GET HOSTS vim response", hosts
)
1148 return vimconn
.HTTP_Internal_Server_Error
, hosts
1149 #obtain hosts details
1151 for host
in hosts
['hosts']:
1152 url
=self
.url
+'/hosts/'+host
['id']
1154 vim_response
= requests
.get(url
)
1155 except requests
.exceptions
.RequestException
as e
:
1156 print("get_hosts_info Exception: ", e
.args
)
1157 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1158 print("vim get {} response{} {}", url
,vim_response
.status_code
, vim_response
.json())
1159 if vim_response
.status_code
!= 200:
1160 print('vimconnector.get_hosts_info error getting detailed host %d %s', vim_response
.status_code
, vim_response
.json())
1162 res
,host_detail
= self
._format
_in
(vim_response
, get_host_detail_response_schema
)
1164 print("vimconnector.get_hosts_info error parsing GET HOSTS/%s vim response", host
['id'], host_detail
)
1166 #print 'host id '+host['id'], json.dumps(host_detail, indent=4)
1167 self
.host_vim2gui(host_detail
, hosts_dict
)
1168 return 200, hosts_dict
1170 def get_hosts(self
, vim_tenant
):
1171 '''Get the hosts and deployed instances
1172 Returns the hosts content'''
1174 url
=self
.url
+'/hosts'
1176 vim_response
= requests
.get(url
)
1177 except requests
.exceptions
.RequestException
as e
:
1178 print("get_hosts Exception: ", e
.args
)
1179 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1180 print("vim get {} response:{} {}", url
, vim_response
.status_code
, vim_response
.json())
1181 #print vim_response.status_code
1182 #print json.dumps(vim_response.json(), indent=4)
1183 if vim_response
.status_code
!= 200:
1185 print('vimconnector.get_hosts error getting host list %d %s', vim_response
.status_code
, vim_response
.json())
1186 return -vim_response
.status_code
, "Error getting host list"
1188 res
,hosts
= self
._format
_in
(vim_response
, get_hosts_response_schema
)
1191 print("vimconnector.get_host error parsing GET HOSTS vim response {}", hosts
)
1192 return vimconn
.HTTP_Internal_Server_Error
, hosts
1193 #obtain instances from hosts
1194 for host
in hosts
['hosts']:
1195 url
=self
.url
+'/' + vim_tenant
+ '/servers?hostId='+host
['id']
1197 vim_response
= requests
.get(url
)
1198 except requests
.exceptions
.RequestException
as e
:
1199 print("get_hosts Exception:{}", e
.args
)
1200 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1201 print("vim get {} response: {} {}", url
, vim_response
.status_code
, vim_response
.json())
1202 if vim_response
.status_code
!= 200:
1203 print('vimconnector.get_hosts error getting instances at host %d %s',vim_response
.status_code
, vim_response
.json())
1205 res
,servers
= self
._format
_in
(vim_response
, get_server_response_schema
)
1207 print("vimconnector.get_host error parsing GET SERVERS/%s vim response",host
['id'], servers
)
1209 #print 'host id '+host['id'], json.dumps(host_detail, indent=4)
1210 host
['instances'] = servers
['servers']
1211 return 200, hosts
['hosts']
1213 def get_processor_rankings(self
):
1214 '''Get the processor rankings in the VIM database'''
1215 url
=self
.url
+'/processor_ranking'
1217 vim_response
= requests
.get(url
)
1218 except requests
.exceptions
.RequestException
as e
:
1219 print("get_processor_rankings Exception:{}", e
.args
)
1220 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1221 print("vim get {} response: {} {}", url
, vim_response
.status_code
, vim_response
.json())
1222 #print vim_response.status_code
1223 #print json.dumps(vim_response.json(), indent=4)
1224 if vim_response
.status_code
!= 200:
1226 print('vimconnector.get_processor_rankings error getting processor rankings %d %s',vim_response
.status_code
, vim_response
.json())
1227 return -vim_response
.status_code
, "Error getting processor rankings"
1229 res
,rankings
= self
._format
_in
(vim_response
, get_processor_rankings_response_schema
)
1230 return res
, rankings
['rankings']
1232 def new_host(self
, host_data
):
1233 '''Adds a new host to VIM'''
1234 '''Returns status code of the VIM response'''
1235 payload_req
= host_data
1237 url
= self
.url_admin
+'/hosts'
1238 self
.logger
.info("Adding a new host POST %s", url
)
1239 vim_response
= requests
.post(url
, headers
= self
.headers_req
, data
=payload_req
)
1240 self
._check
_http
_request
_response
(vim_response
)
1241 self
.logger
.debug(vim_response
.text
)
1242 #print json.dumps(vim_response.json(), indent=4)
1243 response
= vim_response
.json()
1244 js_v(response
, new_host_response_schema
)
1245 r
= self
._remove
_extra
_items
(response
, new_host_response_schema
)
1247 self
.logger
.warn("Warning: remove extra items %s", str(r
))
1248 host_id
= response
['host']['id']
1250 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
1251 self
._format
_request
_exception
(e
)
1253 def new_external_port(self
, port_data
):
1254 '''Adds a external port to VIM'''
1255 '''Returns the port identifier'''
1256 #TODO change to logging exception code policies
1257 print("VIMConnector: Adding a new external port")
1258 payload_req
= port_data
1260 vim_response
= requests
.post(self
.url_admin
+'/ports', headers
= self
.headers_req
, data
=payload_req
)
1261 except requests
.exceptions
.RequestException
as e
:
1262 self
.logger
.error("new_external_port Exception: ", str(e
))
1263 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1265 #print vim_response.status_code
1266 if vim_response
.status_code
== 200:
1267 #print vim_response.json()
1268 #print json.dumps(vim_response.json(), indent=4)
1269 res
, http_content
= self
._format
_in
(vim_response
, new_port_response_schema
)
1272 r
= self
._remove
_extra
_items
(http_content
, new_port_response_schema
)
1273 if r
is not None: print("Warning: remove extra items ", r
)
1275 port_id
= http_content
['port']['id']
1276 print("Port id: {}",port_id
)
1277 return vim_response
.status_code
,port_id
1278 else: return -vimconn
.HTTP_Bad_Request
,http_content
1280 #print vim_response.text
1281 jsonerror
= self
._format
_jsonerror
(vim_response
)
1282 text
= 'Error in VIM "%s": not possible to add new external port. HTTP Response: %d. Error: %s' % (self
.url_admin
, vim_response
.status_code
, jsonerror
)
1284 return -vim_response
.status_code
,text
1286 def new_external_network(self
,net_name
,net_type
):
1287 '''Adds a external network to VIM (shared)'''
1288 '''Returns the network identifier'''
1289 #TODO change to logging exception code policies
1290 print("VIMConnector: Adding external shared network to VIM (type {}:{})", net_type
.net_name
)
1292 payload_req
= '{"network":{"name": "' + net_name
+ '","shared":true,"type": "' + net_type
+ '"}}'
1294 vim_response
= requests
.post(self
.url
+'/networks', headers
= self
.headers_req
, data
=payload_req
)
1295 except requests
.exceptions
.RequestException
as e
:
1296 self
.logger
.error( "new_external_network Exception: ", e
.args
)
1297 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1299 #print vim_response.status_code
1300 if vim_response
.status_code
== 200:
1301 #print vim_response.json()
1302 #print json.dumps(vim_response.json(), indent=4)
1303 res
,http_content
= self
._format
_in
(vim_response
, new_network_response_schema
)
1306 r
= self
._remove
_extra
_items
(http_content
, new_network_response_schema
)
1307 if r
is not None: print("Warning: remove extra items ", r
)
1309 network_id
= http_content
['network']['id']
1310 print("Network id: ",network_id
)
1311 return vim_response
.status_code
,network_id
1312 else: return -vimconn
.HTTP_Bad_Request
,http_content
1314 #print vim_response.text
1315 jsonerror
= self
._format
_jsonerror
(vim_response
)
1316 text
= 'Error in VIM "%s": not possible to add new external network. HTTP Response: %d. Error: %s' % (self
.url
, vim_response
.status_code
, jsonerror
)
1318 return -vim_response
.status_code
,text
1320 def connect_port_network(self
, port_id
, network_id
, admin
=False):
1321 '''Connects a external port to a network'''
1322 '''Returns status code of the VIM response'''
1323 #TODO change to logging exception code policies
1324 print("VIMConnector: Connecting external port to network")
1326 payload_req
= '{"port":{"network_id":"' + network_id
+ '"}}'
1328 if self
.url_admin
==None:
1329 return -vimconn
.HTTP_Unauthorized
, "datacenter cannot contain admin URL"
1334 vim_response
= requests
.put(url
+'/ports/'+port_id
, headers
= self
.headers_req
, data
=payload_req
)
1335 except requests
.exceptions
.RequestException
as e
:
1336 print("connect_port_network Exception: {}", e
.args
)
1337 return -vimconn
.HTTP_Not_Found
, str(e
.args
[0])
1339 #print vim_response.status_code
1340 if vim_response
.status_code
== 200:
1341 #print vim_response.json()
1342 #print json.dumps(vim_response.json(), indent=4)
1343 res
,http_content
= self
._format
_in
(vim_response
, new_port_response_schema
)
1346 r
= self
._remove
_extra
_items
(http_content
, new_port_response_schema
)
1347 if r
is not None: print( "Warning: remove extra items ", r
)
1349 port_id
= http_content
['port']['id']
1350 print("Port id:{} ",port_id
)
1351 return vim_response
.status_code
,port_id
1352 else: return -vimconn
.HTTP_Bad_Request
,http_content
1354 print(vim_response
.text
)
1355 jsonerror
= self
._format
_jsonerror
(vim_response
)
1356 text
= 'Error in VIM "%s": not possible to connect external port to network. HTTP Response: %d. Error: %s' % (self
.url_admin
, vim_response
.status_code
, jsonerror
)
1358 return -vim_response
.status_code
,text
1360 def get_port(self
, port_id
):
1361 '''Obtain port details of port id'''
1363 url
= self
.url
+'/ports/'+port_id
1364 self
.logger
.info("Getting port GET %s", url
)
1365 vim_response
= requests
.get(url
, headers
= self
.headers_req
)
1366 self
._check
_http
_request
_response
(vim_response
)
1367 self
.logger
.debug(vim_response
.text
)
1368 #print json.dumps(vim_response.json(), indent=4)
1369 response
= vim_response
.json()
1370 return response
['port']
1371 except (requests
.exceptions
.RequestException
, js_e
.ValidationError
) as e
:
1372 self
._format
_request
_exception
(e
)