bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+@bottle.route(url_base + '/<tenant_id>/vim_accounts', method='GET')
+@bottle.route(url_base + '/<tenant_id>/vim_accounts/<vim_account_id>', method='GET')
+def http_get_vim_account(tenant_id, vim_account_id=None):
+ '''get vim_account list/details, '''
+ logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
+ try:
+ select_ = ('uuid', 'name', 'dt.datacenter_id as vim_id', 'vim_tenant_name', 'vim_tenant_id', 'user', 'config',
+ 'dt.created_at as created_at', 'passwd')
+ where_ = {'nfvo_tenant_id': tenant_id}
+ if vim_account_id:
+ where_['dt.uuid'] = vim_account_id
+ from_ = 'tenants_datacenters as td join datacenter_tenants as dt on dt.uuid=td.datacenter_tenant_id'
+ vim_accounts = mydb.get_rows(SELECT=select_, FROM=from_, WHERE=where_)
+
+ if len(vim_accounts) == 0 and vim_account_id:
+ bottle.abort(HTTP_Not_Found, "No vim_account found for tenant {} and id '{}'".format(tenant_id,
+ vim_account_id))
+ for vim_account in vim_accounts:
+ if vim_account["passwd"]:
+ vim_account["passwd"] = "******"
+ if vim_account['config'] != None:
+ try:
+ config_dict = yaml.load(vim_account['config'])
+ vim_account['config'] = config_dict
+ if vim_account['config'].get('admin_password'):
+ vim_account['config']['admin_password'] = "******"
+ if vim_account['config'].get('vcenter_password'):
+ vim_account['config']['vcenter_password'] = "******"
+ if vim_account['config'].get('nsx_password'):
+ vim_account['config']['nsx_password'] = "******"
+ except Exception as e:
+ logger.error("Exception '%s' while trying to load config information", str(e))
+ # change_keys_http2db(content, http2db_datacenter, reverse=True)
+ #convert_datetime2str(vim_account)
+ if vim_account_id:
+ return format_out({"datacenter": vim_accounts[0]})
+ else:
+ return format_out({"datacenters": vim_accounts})
+ except bottle.HTTPError:
+ raise
+ except (nfvo.NfvoException, db_base_Exception) as e:
+ logger.error("http_get_datacenter_id error {}: {}".format(e.http_code, str(e)))
+ bottle.abort(e.http_code, str(e))
+ except Exception as e:
+ logger.error("Unexpected exception: ", exc_info=True)
+ bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+
+
@bottle.route(url_base + '/<tenant_id>/datacenters/<datacenter_id>', method='GET')
def http_get_datacenter_id(tenant_id, datacenter_id):
'''get datacenter details, can use both uuid or name'''
@bottle.route(url_base + '/<tenant_id>/datacenters/<datacenter_id>', method='POST')
-def http_associate_datacenters(tenant_id, datacenter_id):
+@bottle.route(url_base + '/<tenant_id>/vim_accounts', method='POST')
+def http_associate_datacenters(tenant_id, datacenter_id=None):
'''associate an existing datacenter to a this tenant. '''
logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
#parse input data
if r:
logger.debug("Remove received extra items %s", str(r))
try:
- id_ = nfvo.associate_datacenter_to_tenant(mydb, tenant_id, datacenter_id,
- http_content['datacenter'].get('vim_tenant'),
- http_content['datacenter'].get('vim_tenant_name'),
- http_content['datacenter'].get('vim_username'),
- http_content['datacenter'].get('vim_password'),
- http_content['datacenter'].get('config')
- )
- return http_get_datacenter_id(tenant_id, id_)
+ vim_account_id = nfvo.create_vim_account(mydb, tenant_id, datacenter_id,
+ **http_content['datacenter'])
+ return http_get_vim_account(tenant_id, vim_account_id)
except bottle.HTTPError:
raise
except (nfvo.NfvoException, db_base_Exception) as e:
logger.error("Unexpected exception: ", exc_info=True)
bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+@bottle.route(url_base + '/<tenant_id>/vim_accounts/<vim_account_id>', method='PUT')
@bottle.route(url_base + '/<tenant_id>/datacenters/<datacenter_id>', method='PUT')
-def http_associate_datacenters_edit(tenant_id, datacenter_id):
+def http_vim_account_edit(tenant_id, vim_account_id=None, datacenter_id=None):
'''associate an existing datacenter to a this tenant. '''
logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
#parse input data
- http_content,_ = format_in( datacenter_associate_schema )
+ http_content,_ = format_in(datacenter_associate_schema)
r = utils.remove_extra_items(http_content, datacenter_associate_schema)
if r:
logger.debug("Remove received extra items %s", str(r))
try:
- id_ = nfvo.edit_datacenter_to_tenant(mydb, tenant_id, datacenter_id,
- http_content['datacenter'].get('vim_tenant'),
- http_content['datacenter'].get('vim_tenant_name'),
- http_content['datacenter'].get('vim_username'),
- http_content['datacenter'].get('vim_password'),
- http_content['datacenter'].get('config')
- )
- return http_get_datacenter_id(tenant_id, id_)
+ vim_account_id = nfvo.edit_vim_account(mydb, tenant_id, vim_account_id, datacenter_id=datacenter_id,
+ **http_content['datacenter'])
+ return http_get_vim_account(tenant_id, vim_account_id)
except bottle.HTTPError:
raise
except (nfvo.NfvoException, db_base_Exception) as e:
- logger.error("http_associate_datacenters_edit error {}: {}".format(e.http_code, str(e)))
+ logger.error("http_vim_account_edit error {}: {}".format(e.http_code, str(e)))
bottle.abort(e.http_code, str(e))
except Exception as e:
logger.error("Unexpected exception: ", exc_info=True)
bottle.abort(HTTP_Internal_Server_Error, type(e).__name__ + ": " + str(e))
+
@bottle.route(url_base + '/<tenant_id>/datacenters/<datacenter_id>', method='DELETE')
-def http_deassociate_datacenters(tenant_id, datacenter_id):
+@bottle.route(url_base + '/<tenant_id>/vim_accounts/<vim_account_id>', method='DELETE')
+def http_deassociate_datacenters(tenant_id, datacenter_id=None, vim_account_id=None):
'''deassociate an existing datacenter to a this tenant. '''
logger.debug('FROM %s %s %s', bottle.request.remote_addr, bottle.request.method, bottle.request.url)
try:
- data = nfvo.deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter_id)
+ data = nfvo.delete_vim_account(mydb, tenant_id, vim_account_id, datacenter_id)
return format_out({"result": data})
except bottle.HTTPError:
raise
HTTP_Internal_Server_Error)
thread_name = get_non_used_vim_name(vim['datacenter_name'], vim['vim_tenant_id'], vim['vim_tenant_name'],
vim['vim_tenant_id'])
- new_thread = vim_thread.vim_thread(myvim, task_lock, thread_name, vim['datacenter_name'],
+ new_thread = vim_thread.vim_thread(task_lock, thread_name, vim['datacenter_name'],
vim['datacenter_tenant_id'], db=db, db_lock=db_lock, ovim=ovim)
new_thread.start()
vim_threads["running"][thread_id] = new_thread
" dt on td.datacenter_tenant_id=dt.uuid"
else:
from_ = 'datacenters as d'
- vimaccounts = mydb.get_rows(FROM=from_, SELECT=("d.uuid as uuid",), WHERE=WHERE_dict )
+ vimaccounts = mydb.get_rows(FROM=from_, SELECT=("d.uuid as uuid, d.name as name",), WHERE=WHERE_dict )
if len(vimaccounts) == 0:
raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name)), HTTP_Not_Found)
elif len(vimaccounts)>1:
#print "nfvo.datacenter_action() error. Several datacenters found"
raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict)
- return vimaccounts[0]["uuid"]
+ return vimaccounts[0]["uuid"], vimaccounts[0]["name"]
def get_datacenter_by_name_uuid(mydb, tenant_id, datacenter_id_name=None, **extra_filter):
site_without_datacenter_field = False
for site in net_instance_desc["sites"]:
if site.get("datacenter"):
- site["datacenter"] = get_datacenter_uuid(mydb, tenant_id, site["datacenter"])
+ site["datacenter"], _ = get_datacenter_uuid(mydb, tenant_id, site["datacenter"])
if site["datacenter"] not in myvims:
# Add this datacenter to myvims
d, v = get_datacenter_by_name_uuid(mydb, tenant_id, site["datacenter"])
raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(vnf_name), HTTP_Bad_Request)
if "datacenter" in vnf_instance_desc:
# Add this datacenter to myvims
- vnf_instance_desc["datacenter"] = get_datacenter_uuid(mydb, tenant_id, vnf_instance_desc["datacenter"])
+ vnf_instance_desc["datacenter"], _ = get_datacenter_uuid(mydb, tenant_id, vnf_instance_desc["datacenter"])
if vnf_instance_desc["datacenter"] not in myvims:
d, v = get_datacenter_by_name_uuid(mydb, tenant_id, vnf_instance_desc["datacenter"])
myvims[d] = v
return datacenter_dict['uuid'] + " " + datacenter_dict['name']
-def associate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter, vim_tenant_id=None, vim_tenant_name=None, vim_username=None, vim_password=None, config=None):
+def create_vim_account(mydb, nfvo_tenant, datacenter_id, name=None, vim_id=None, vim_tenant=None, vim_tenant_name=None,
+ vim_username=None, vim_password=None, config=None):
# get datacenter info
try:
- datacenter_id = get_datacenter_uuid(mydb, None, datacenter)
+ if not datacenter_id:
+ if not vim_id:
+ raise NfvoException("You must provide 'vim_id", http_code=HTTP_Bad_Request)
+ datacenter_id = vim_id
+ datacenter_id, datacenter_name = get_datacenter_uuid(mydb, None, datacenter_id)
- create_vim_tenant = True if not vim_tenant_id and not vim_tenant_name else False
+ create_vim_tenant = True if not vim_tenant and not vim_tenant_name else False
# get nfvo_tenant info
tenant_dict = mydb.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant)
if vim_tenant_name==None:
vim_tenant_name=tenant_dict['name']
- #check that this association does not exist before
tenants_datacenter_dict={"nfvo_tenant_id":tenant_dict['uuid'], "datacenter_id":datacenter_id }
- tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
- if len(tenants_datacenters)>0:
- raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), HTTP_Conflict)
+ # #check that this association does not exist before
+ # tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
+ # if len(tenants_datacenters)>0:
+ # raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), HTTP_Conflict)
vim_tenant_id_exist_atdb=False
if not create_vim_tenant:
where_={"datacenter_id": datacenter_id}
- if vim_tenant_id!=None:
- where_["vim_tenant_id"] = vim_tenant_id
+ if vim_tenant!=None:
+ where_["vim_tenant_id"] = vim_tenant
if vim_tenant_name!=None:
where_["vim_tenant_name"] = vim_tenant_name
#check if vim_tenant_id is already at database
else: #result=0
datacenter_tenants_dict = {}
#insert at table datacenter_tenants
- else: #if vim_tenant_id==None:
+ else: #if vim_tenant==None:
#create tenant at VIM if not provided
try:
_, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter, vim_user=vim_username,
vim_passwd=vim_password)
datacenter_name = myvim["name"]
- vim_tenant_id = myvim.new_tenant(vim_tenant_name, "created by openmano for datacenter "+datacenter_name)
+ vim_tenant = myvim.new_tenant(vim_tenant_name, "created by openmano for datacenter "+datacenter_name)
except vimconn.vimconnException as e:
- raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id, str(e)), HTTP_Internal_Server_Error)
+ raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant, str(e)), HTTP_Internal_Server_Error)
datacenter_tenants_dict = {}
datacenter_tenants_dict["created"]="true"
#fill datacenter_tenants table
if not vim_tenant_id_exist_atdb:
- datacenter_tenants_dict["vim_tenant_id"] = vim_tenant_id
+ datacenter_tenants_dict["vim_tenant_id"] = vim_tenant
datacenter_tenants_dict["vim_tenant_name"] = vim_tenant_name
datacenter_tenants_dict["user"] = vim_username
datacenter_tenants_dict["passwd"] = vim_password
datacenter_tenants_dict["datacenter_id"] = datacenter_id
+ if name:
+ datacenter_tenants_dict["name"] = name
+ else:
+ datacenter_tenants_dict["name"] = datacenter_name
if config:
datacenter_tenants_dict["config"] = yaml.safe_dump(config, default_flow_style=True, width=256)
id_ = mydb.new_row('datacenter_tenants', datacenter_tenants_dict, add_uuid=True, confidential_data=True)
datacenter_tenant_id = datacenter_tenants_dict["uuid"]
tenants_datacenter_dict["datacenter_tenant_id"] = datacenter_tenant_id
mydb.new_row('tenants_datacenters', tenants_datacenter_dict)
+
# create thread
- datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_dict['uuid'], datacenter_id) # reload data
- datacenter_name = myvim["name"]
thread_name = get_non_used_vim_name(datacenter_name, datacenter_id, tenant_dict['name'], tenant_dict['uuid'])
- new_thread = vim_thread.vim_thread(myvim, task_lock, thread_name, datacenter_name, datacenter_tenant_id,
+ new_thread = vim_thread.vim_thread(task_lock, thread_name, datacenter_name, datacenter_tenant_id,
db=db, db_lock=db_lock, ovim=ovim)
new_thread.start()
thread_id = datacenter_tenants_dict["uuid"]
vim_threads["running"][thread_id] = new_thread
- return datacenter_id
+ return thread_id
except vimconn.vimconnException as e:
raise NfvoException(str(e), HTTP_Bad_Request)
-def edit_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=None, vim_tenant_name=None,
- vim_username=None, vim_password=None, config=None):
- #Obtain the data of this datacenter_tenant_id
- vim_data = mydb.get_rows(
- SELECT=("datacenter_tenants.vim_tenant_name", "datacenter_tenants.vim_tenant_id", "datacenter_tenants.user",
- "datacenter_tenants.passwd", "datacenter_tenants.config"),
- FROM="datacenter_tenants JOIN tenants_datacenters ON datacenter_tenants.uuid=tenants_datacenters.datacenter_tenant_id",
- WHERE={"tenants_datacenters.nfvo_tenant_id": nfvo_tenant,
- "tenants_datacenters.datacenter_id": datacenter_id})
-
- logger.debug(str(vim_data))
- if len(vim_data) < 1:
- raise NfvoException("Datacenter {} is not attached for tenant {}".format(datacenter_id, nfvo_tenant), HTTP_Conflict)
-
- v = vim_data[0]
- if v['config']:
- v['config'] = yaml.load(v['config'])
-
- if vim_tenant_id:
- v['vim_tenant_id'] = vim_tenant_id
+def edit_vim_account(mydb, nfvo_tenant, datacenter_tenant_id, datacenter_id=None, name=None, vim_tenant=None,
+ vim_tenant_name=None, vim_username=None, vim_password=None, config=None):
+
+ # get vim_account; check is valid for this tenant
+ from_ = "datacenter_tenants as dt JOIN tenants_datacenters as td ON dt.uuid=td.datacenter_tenant_id"
+ where_ = {"td.nfvo_tenant_id": nfvo_tenant}
+ if datacenter_tenant_id:
+ where_["dt.uuid"] = datacenter_tenant_id
+ if datacenter_id:
+ where_["dt.datacenter_id"] = datacenter_id
+ vim_accounts = mydb.get_rows(SELECT="dt.uuid as uuid, config", FROM=from_, WHERE=where_)
+ if not vim_accounts:
+ raise NfvoException("vim_account not found for this tenant", http_code=HTTP_Not_Found)
+ elif len(vim_accounts) > 1:
+ raise NfvoException("found more than one vim_account for this tenant", http_code=HTTP_Conflict)
+ datacenter_tenant_id = vim_accounts[0]["uuid"]
+ original_config = vim_accounts[0]["config"]
+
+ update_ = {}
+ if config:
+ original_config_dict = yaml.load(original_config)
+ original_config_dict.update(config)
+ update["config"] = yaml.safe_dump(original_config_dict, default_flow_style=True, width=256)
+ if name:
+ update_['name'] = name
+ if vim_tenant:
+ update_['vim_tenant_id'] = vim_tenant
if vim_tenant_name:
- v['vim_tenant_name'] = vim_tenant_name
+ update_['vim_tenant_name'] = vim_tenant_name
if vim_username:
- v['user'] = vim_username
+ update_['user'] = vim_username
if vim_password:
- v['passwd'] = vim_password
- if config:
- if not v['config']:
- v['config'] = {}
- v['config'].update(config)
+ update_['passwd'] = vim_password
+ if update_:
+ mydb.update_rows("datacenter_tenants", UPDATE=update_, WHERE={"uuid": datacenter_tenant_id})
- logger.debug(str(v))
- deassociate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=v['vim_tenant_id'])
- associate_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=v['vim_tenant_id'], vim_tenant_name=v['vim_tenant_name'],
- vim_username=v['user'], vim_password=v['passwd'], config=v['config'])
-
- return datacenter_id
+ vim_threads["running"][datacenter_tenant_id].insert_task("reload")
+ return datacenter_tenant_id
-def deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter, vim_tenant_id=None):
+def delete_vim_account(mydb, tenant_id, vim_account_id, datacenter=None):
#get nfvo_tenant info
if not tenant_id or tenant_id=="any":
tenant_uuid = None
tenant_dict = mydb.get_table_by_uuid_name('nfvo_tenants', tenant_id)
tenant_uuid = tenant_dict['uuid']
- datacenter_id = get_datacenter_uuid(mydb, tenant_uuid, datacenter)
#check that this association exist before
- tenants_datacenter_dict={"datacenter_id": datacenter_id }
+ tenants_datacenter_dict = {}
+ if datacenter:
+ datacenter_id, _ = get_datacenter_uuid(mydb, tenant_uuid, datacenter)
+ tenants_datacenter_dict["datacenter_id"] = datacenter_id
+ elif vim_account_id:
+ tenants_datacenter_dict["datacenter_tenant_id"] = vim_account_id
if tenant_uuid:
tenants_datacenter_dict["nfvo_tenant_id"] = tenant_uuid
tenant_datacenter_list = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
import Queue
import logging
import vimconn
+import vimconn_openvim
+import vimconn_aws
+import vimconn_opennebula
+import vimconn_openstack
+import vimconn_vmware
import yaml
from db_base import db_base_Exception
from lib_osm_openvim.ovim import ovimException
__author__ = "Alfonso Tierno, Pablo Montes"
__date__ = "$28-Sep-2017 12:07:15$"
+vim_module = {
+ "openvim": vimconn_openvim,
+ "aws": vimconn_aws,
+ "opennebula": vimconn_opennebula,
+ "openstack": vimconn_openstack,
+ "vmware": vimconn_vmware,
+}
def is_task_id(task_id):
return task_id.startswith("TASK-")
REFRESH_BUILD = 5 # 5 seconds
REFRESH_ACTIVE = 60 # 1 minute
- def __init__(self, myvimconn, task_lock, name=None, datacenter_name=None, datacenter_tenant_id=None,
+ def __init__(self, task_lock, name=None, datacenter_name=None, datacenter_tenant_id=None,
db=None, db_lock=None, ovim=None):
"""Init a thread.
Arguments:
'db', 'db_lock': database class and lock to use it in exclusion
"""
threading.Thread.__init__(self)
- if isinstance(myvimconn, vimconn.vimconnException):
- self.vim = None
- self.error_status = "Error accesing to VIM: {}".format(myvimconn)
- else:
- self.vim = myvimconn
- self.error_status = None
+ self.vim = None
+ self.error_status = None
self.datacenter_name = datacenter_name
self.datacenter_tenant_id = datacenter_tenant_id
self.ovim = ovim
self.name = vimconn["id"] + "." + vimconn["config"]["datacenter_tenant_id"]
else:
self.name = name
+ self.vim_persistent_info = {}
self.logger = logging.getLogger('openmano.vim.'+self.name)
self.db = db
<task2> # e.g. DELETE task
"""
+ def get_vimconnector(self):
+ try:
+ from_= "datacenter_tenants as dt join datacenters as d on dt.datacenter_id=d.uuid"
+ select_ = ('type', 'd.config as config', 'd.uuid as datacenter_id', 'vim_url', 'vim_url_admin',
+ 'd.name as datacenter_name', 'dt.uuid as datacenter_tenant_id',
+ 'dt.vim_tenant_name as vim_tenant_name', 'dt.vim_tenant_id as vim_tenant_id',
+ 'user', 'passwd', 'dt.config as dt_config')
+ where_ = {"dt.uuid": self.datacenter_tenant_id}
+ with self.db_lock:
+ vims = self.db.get_rows(FROM=from_, SELECT=select_, WHERE=where_)
+ vim = vims[0]
+ extra = {'datacenter_tenant_id': vim.get('datacenter_tenant_id'),
+ 'datacenter_id': vim.get('datacenter_id')}
+
+ self.vim = vim_module[vim["type"]].vimconnector(
+ uuid=vim['datacenter_id'], name=vim['datacenter_name'],
+ tenant_id=vim['vim_tenant_id'], tenant_name=vim['vim_tenant_name'],
+ url=vim['vim_url'], url_admin=vim['vim_url_admin'],
+ user=vim['user'], passwd=vim['passwd'],
+ config=extra, persistent_info=self.vim_persistent_info
+ )
+ self.error_status = None
+ except Exception as e:
+ self.logger.error("Cannot load vimconnector for vim_account {}: {}".format(self.datacenter_tenant_id, e))
+ self.vim = None
+ self.error_status = "Error loading vimconnector: {}".format(e)
+
def _reload_vim_actions(self):
"""
Read actions from database and reload them at memory. Fill self.refresh_list, pending_list, vim_actions
def run(self):
self.logger.debug("Starting")
while True:
+ self.get_vimconnector()
+ self.logger.debug("Vimconnector loaded")
self._reload_vim_actions()
reload_thread = False