From: jomacarpe Date: Tue, 27 Feb 2018 12:48:22 +0000 (+0100) Subject: OpenNebula VIM supported X-Git-Tag: v4.0.0~32 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=commitdiff_plain;h=ea2a73ee9c827a6a3559c715423cb1a63f9123d8 OpenNebula VIM supported Signed-off-by: jomacarpe OpenNebula VIM supported Signed-off-by: albertoflorez --- diff --git a/Dockerfile b/Dockerfile index e2b9c553..01dc9ea2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,5 +13,7 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get -y install python-novaclient python-keystoneclient python-glanceclient python-cinderclient python-neutronclient && \ DEBIAN_FRONTEND=noninteractive pip install -U progressbar pyvmomi pyvcloud==19.1.1 && \ DEBIAN_FRONTEND=noninteractive apt-get -y install python-argcomplete python-bottle python-cffi python-packaging python-paramiko python-pkgconfig libmysqlclient-dev libssl-dev libffi-dev python-mysqldb && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-logutils python-openstackclient python-openstacksdk + DEBIAN_FRONTEND=noninteractive apt-get -y install python-logutils python-openstackclient python-openstacksdk && \ + DEBIAN_FRONTEND=noninteractive pip install untangle && \ + DEBIAN_FRONTEND=noninteractive pip install -e git+https://github.com/python-oca/python-oca#egg=oca diff --git a/osm_ro/vimconn_opennebula.py b/osm_ro/vimconn_opennebula.py new file mode 100644 index 00000000..eaf3021a --- /dev/null +++ b/osm_ro/vimconn_opennebula.py @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- + +## +# Copyright 2017 Telefónica Digital España S.L.U. +# This file is part of ETSI OSM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + +# License for the specific language governing permissions and limitations +# under the License. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: patent-office@telefonica.com +## + +""" +vimconnector implements all the methods to interact with OpenNebula using the XML-RPC API. +""" +__author__ = "Jose Maria Carmona Perez,Juan Antonio Hernando Labajo, Emilio Abraham Garrido Garcia,Alberto Florez " \ + "Pages, Andres Pozo Muñoz, Santiago Perez Marin, Onlife Networks Telefonica I+D Product Innovation " +__date__ = "$13-dec-2017 11:09:29$" +import vimconn +import requests +import logging +import oca +import untangle +import math +import random + + +class vimconnector(vimconn.vimconnector): + def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, + log_level="DEBUG", config={}, persistent_info={}): + vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level, + config) + self.tenant = None + self.headers_req = {'content-type': 'application/json'} + self.logger = logging.getLogger('openmano.vim.opennebula') + self.persistent_info = persistent_info + if tenant_id: + self.tenant = tenant_id + + def __setitem__(self, index, value): + """Set individuals parameters + Throw TypeError, KeyError + """ + if index == 'tenant_id': + self.tenant = value + elif index == 'tenant_name': + self.tenant = None + vimconn.vimconnector.__setitem__(self, index, value) + + def new_tenant(self, tenant_name, tenant_description): + # '''Adds a new tenant to VIM with this name and description, returns the tenant identifier''' + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + group_list = oca.GroupPool(client) + user_list = oca.UserPool(client) + group_list.info() + user_list.info() + create_primarygroup = 1 + # create group-tenant + for group in group_list: + if str(group.name) == str(tenant_name): + create_primarygroup = 0 + break + if create_primarygroup == 1: + oca.Group.allocate(client, tenant_name) + group_list.info() + # set to primary_group the tenant_group and oneadmin to secondary_group + for group in group_list: + if str(group.name) == str(tenant_name): + for user in user_list: + if str(user.name) == str(self.user): + if user.name == "oneadmin": + return str(0) + else: + self._add_secondarygroup(user.id, group.id) + user.chgrp(group.id) + return str(group.id) + except Exception as e: + self.logger.error("Create new tenant error: " + str(e)) + raise vimconn.vimconnException(e) + + def _add_secondarygroup(self, id_user, id_group): + # change secondary_group to primary_group + params = ' \ + \ + one.user.addgroup\ + \ + \ + {}:{}\ + \ + \ + {}\ + \ + \ + {}\ + \ + \ + '.format(self.user, self.passwd, (str(id_user)), (str(id_group))) + requests.post(self.url, params) + + def delete_tenant(self, tenant_id): + """Delete a tenant from VIM. Returns the old tenant identifier""" + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + group_list = oca.GroupPool(client) + user_list = oca.UserPool(client) + group_list.info() + user_list.info() + for group in group_list: + if str(group.id) == str(tenant_id): + for user in user_list: + if str(user.name) == str(self.user): + self._delete_secondarygroup(user.id, group.id) + group.delete(client) + return None + raise vimconn.vimconnNotFoundException("Group {} not found".format(tenant_id)) + except Exception as e: + self.logger.error("Delete tenant " + str(tenant_id) + " error: " + str(e)) + raise vimconn.vimconnException(e) + + # to be used in future commits + def _delete_secondarygroup(self, id_user, id_group): + params = ' \ + \ + one.user.delgroup\ + \ + \ + {}:{}\ + \ + \ + {}\ + \ + \ + {}\ + \ + \ + '.format(self.user, self.passwd, (str(id_user)), (str(id_group))) + requests.post(self.url, params) + + # to be used in future commits + # def get_tenant_list(self, filter_dict={}): + # return ["tenant"] + + # to be used in future commits + # def _check_tenant(self): + # try: + # client = oca.Client(self.user + ':' + self.passwd, self.url) + # group_list = oca.GroupPool(client) + # user_list = oca.UserPool(client) + # group_list.info() + # user_list.info() + # for group in group_list: + # if str(group.name) == str(self.tenant_name): + # for user in user_list: + # if str(user.name) == str(self.user): + # self._add_secondarygroup(user.id, group.id) + # user.chgrp(group.id) + # except vimconn.vimconnException as e: + # self.logger.error(e) + + # to be used in future commits, needs refactor to manage networks + # def _create_bridge_host(self, vlan): + # file = open('manage_bridge_OSM', 'w') + # # password_path = self.config["password"]["path"] + # a = "#! /bin/bash\nsudo brctl addbr br_osm_{vlanused}\n" \ + # "sudo ip link add link veth1 name veth1.{vlanused} type vlan id {vlanused}\n" \ + # "sudo brctl addif br_osm_{vlanused} veth1.{vlanused}\n" \ + # "sudo ip link set dev br_osm_{vlanused} up\n" \ + # "sudo ip link set dev veth1.{vlanused} up\n".format(vlanused=vlan) + # # a = "#! /bin/bash\nsudo brctl addbr br_osm\nsudo ip link set dev br_osm up\n" + # file.write(a) + # file.close() + # for host in self.config["cluster"]["ip"]: + # file_scp = "/usr/bin/scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {} manage_bridge_OSM {}@{}:/home/{}".format( + # self.config["cluster"]["password_path"][host], self.config["cluster"]["login"][host], + # self.config["cluster"]["ip"][host], self.config["cluster"]["login"][host]) + # os.system(file_scp) + # file_permissions = "/usr/bin/ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {} {}@{} sudo chmod 700 manage_bridge_OSM".format( + # self.config["cluster"]["password_path"][host], self.config["cluster"]["login"][host], + # self.config["cluster"]["ip"][host]) + # os.system(file_permissions) + # exec_script = "/usr/bin/ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {} {}@{} sudo ./manage_bridge_OSM".format( + # self.config["cluster"]["password_path"][host], self.config["cluster"]["login"][host], + # self.config["cluster"]["ip"][host]) + # os.system(exec_script) + # os.remove("manage_bridge_OSM") + + # to be used to manage networks with vlan + # def delete_bridge_host(self, vlan): + # file = open('manage_bridge_OSM', 'w') + # a = "#! /bin/bash\nsudo ip link set dev veth1.3142 down\nsudo ip link set dev br_3142 down\nsudo brctl delbr br_3142\n" + # file.write(a) + # file.close() + # os.system("/usr/bin/scp -i onlife manage_bridge_OSM sysadmin@10.95.84.12:/home/sysadmin") + # os.system("/usr/bin/ssh -i onlife sysadmin@10.95.84.12 sudo chmod 700 manage_bridge_OSM") + # os.system("/usr/bin/ssh -i onlife sysadmin@10.95.84.12 sudo ./manage_bridge_OSM") + # os.remove("manage_bridge_OSM") + + def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None): # , **vim_specific): + """Returns the network identifier""" + # oca library method cannot be used in this case (problem with cluster parameters) + try: + # vlan = str(random.randint(self.config["vlan"]["start-range"], self.config["vlan"]["finish-range"])) + # self.create_bridge_host(vlan) + bridge_config = self.config["bridge_service"] + ip_version = "IP4" + size = "256" + if ip_profile is None: + random_number_ipv4 = random.randint(1, 255) + ip_start = "192.168." + str(random_number_ipv4) + ".1" # random value + else: + index = ip_profile["subnet_address"].find("/") + ip_start = ip_profile["subnet_address"][:index] + if "dhcp_count" in ip_profile.keys() and ip_profile["dhcp_count"] is not None: + size = str(ip_profile["dhcp_count"]) + elif not ("dhcp_count" in ip_profile.keys()) and ip_profile["ip_version"] == "IPv4": + prefix = ip_profile["subnet_address"][index + 1:] + size = int(math.pow(2, 32 - prefix)) + if "dhcp_start_address" in ip_profile.keys() and ip_profile["dhcp_start_address"] is not None: + ip_start = str(ip_profile["dhcp_start_address"]) + if ip_profile["ip_version"] == "IPv6": + ip_version = "IP6" + if ip_version == "IP6": + config = "NAME = {}\ + BRIDGE = {}\ + VN_MAD = dummy\ + AR = [TYPE = {}, GLOBAL_PREFIX = {}, SIZE = {}]".format(net_name, bridge_config, ip_version, + ip_start, size) + else: + config = 'NAME = "{}"\ + BRIDGE = {}\ + VN_MAD = dummy\ + AR = [TYPE = {}, IP = {}, SIZE = {}]'.format(net_name, bridge_config, ip_version, ip_start, + size) + + params = ' \ + \ + one.vn.allocate\ + \ + \ + {}:{}\ + \ + \ + {}\ + \ + \ + {}\ + \ + \ + '.format(self.user, self.passwd, config, self.config["cluster"]["id"]) + r = requests.post(self.url, params) + obj = untangle.parse(str(r.content)) + return obj.methodResponse.params.param.value.array.data.value[1].i4.cdata.encode('utf-8') + except Exception as e: + self.logger.error("Create new network error: " + str(e)) + raise vimconn.vimconnException(e) + + def get_network_list(self, filter_dict={}): + """Obtain tenant networks of VIM + Filter_dict can be: + name: network name + id: network uuid + public: boolean + tenant_id: tenant + admin_state_up: boolean + status: 'ACTIVE' + Returns the network list of dictionaries + """ + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + networkList = oca.VirtualNetworkPool(client) + networkList.info() + response = [] + if "name" in filter_dict.keys(): + network_name_filter = filter_dict["name"] + else: + network_name_filter = None + if "id" in filter_dict.keys(): + network_id_filter = filter_dict["id"] + else: + network_id_filter = None + for network in networkList: + match = False + if network.name == network_name_filter and network.id == network_id_filter: + match = True + if network_name_filter is None and network.id == network_id_filter: + match = True + if network_id_filter is None and network.name == network_name_filter: + match = True + if match: + net_dict = {"name": network.name, "id": str(network.id)} + response.append(net_dict) + return response + except Exception as e: + self.logger.error("Get network list error: " + str(e)) + raise vimconn.vimconnException(e) + + def get_network(self, net_id): + """Obtain network details of network id""" + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + networkList = oca.VirtualNetworkPool(client) + networkList.info() + net = {} + for network in networkList: + if str(network.id) == str(net_id): + net['id'] = net_id + net['name'] = network.name + net['status'] = "ACTIVE" + break + if net: + return net + else: + raise vimconn.vimconnNotFoundException("Network {} not found".format(net_id)) + except Exception as e: + self.logger.error("Get network " + str(net_id) + " error): " + str(e)) + raise vimconn.vimconnException(e) + + def delete_network(self, net_id): + """Deletes a tenant network from VIM + Returns the network identifier + """ + try: + # self.delete_bridge_host() + client = oca.Client(self.user + ':' + self.passwd, self.url) + networkList = oca.VirtualNetworkPool(client) + networkList.info() + network_deleted = False + for network in networkList: + if str(network.id) == str(net_id): + oca.VirtualNetwork.delete(network) + network_deleted = True + if network_deleted: + return net_id + else: + raise vimconn.vimconnNotFoundException("Network {} not found".format(net_id)) + except Exception as e: + self.logger.error("Delete network " + str(net_id) + "error: " + str(e)) + raise vimconn.vimconnException(e) + + def get_flavor(self, flavor_id): # Esta correcto + """Obtain flavor details from the VIM""" + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + listaTemplate = oca.VmTemplatePool(client) + listaTemplate.info() + for template in listaTemplate: + if str(template.id) == str(flavor_id): + return {'id': template.id, 'name': template.name} + raise vimconn.vimconnNotFoundException("Flavor {} not found".format(flavor_id)) + except Exception as e: + self.logger.error("get flavor " + str(flavor_id) + " error: " + str(e)) + raise vimconn.vimconnException(e) + + def new_flavor(self, flavor_data): + """Adds a tenant flavor to VIM + Returns the flavor identifier""" + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + template_name = flavor_data["name"][:-4] + name = 'NAME = "{}" '.format(template_name) + cpu = 'CPU = "{}" '.format(flavor_data["vcpus"]) + memory = 'MEMORY = "{}" '.format(flavor_data["ram"]) + context = 'CONTEXT = [NETWORK = "YES",SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]" ] ' + graphics = 'GRAPHICS = [ LISTEN = "0.0.0.0", TYPE = "VNC" ] ' + sched_requeriments = 'CLUSTER_ID={}'.format(self.config["cluster"]["id"]) + template = name + cpu + memory + context + graphics + sched_requeriments + template_id = oca.VmTemplate.allocate(client, template) + return template_id + except Exception as e: + self.logger.error("Create new flavor error: " + str(e)) + raise vimconn.vimconnException(e) + + def delete_flavor(self, flavor_id): + """ Deletes a tenant flavor from VIM + Returns the old flavor_id + """ + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + listaTemplate = oca.VmTemplatePool(client) + listaTemplate.info() + self.logger.info("Deleting VIM flavor DELETE {}".format(self.url)) + for template in listaTemplate: + if str(template.id) == str(flavor_id): + template.delete() + return template.id + raise vimconn.vimconnNotFoundException("Flavor {} not found".format(flavor_id)) + except Exception as e: + self.logger.error("Delete flavor " + str(flavor_id) + " error: " + str(e)) + raise vimconn.vimconnException(e) + + def get_image_list(self, filter_dict={}): + """Obtain tenant images from VIM + Filter_dict can be: + name: image name + id: image uuid + checksum: image checksum + location: image path + Returns the image list of dictionaries: + [{}, ...] + List can be empty + """ + # IMPORTANT!!!!! Modify python oca library path pool.py line 102 + + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + image_pool = oca.ImagePool(client) + image_pool.info() + images = [] + if "name" in filter_dict.keys(): + image_name_filter = filter_dict["name"] + else: + image_name_filter = None + if "id" in filter_dict.keys(): + image_id_filter = filter_dict["id"] + else: + image_id_filter = None + for image in image_pool: + match = False + if str(image_name_filter) == str(image.name) and image.id == image_id_filter: + match = True + if image_name_filter is None and image.id == image_id_filter: + match = True + if image_id_filter is None and str(image_name_filter) == str(image.name): + match = True + if match: + images_dict = {"name": image.name, "id": str(image.id)} + images.append(images_dict) + return images + except Exception as e: + self.logger.error("Get image list error: " + str(e)) + raise vimconn.vimconnException(e) + + def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None, + availability_zone_index=None, availability_zone_list=None): + """Adds a VM instance to VIM + Params: + start: indicates if VM must start or boot in pause mode. Ignored + image_id,flavor_id: image and flavor uuid + net_list: list of interfaces, each one is a dictionary with: + name: + net_id: network uuid to connect + vpci: virtual vcpi to assign + model: interface model, virtio, e2000, ... + mac_address: + use: 'data', 'bridge', 'mgmt' + type: 'virtual', 'PF', 'VF', 'VFnotShared' + vim_id: filled/added by this function + #TODO ip, security groups + Returns the instance identifier + """ + self.logger.debug( + "new_vminstance input: image='{}' flavor='{}' nics='{}'".format(image_id, flavor_id, str(net_list))) + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + listaTemplate = oca.VmTemplatePool(client) + listaTemplate.info() + for template in listaTemplate: + if str(template.id) == str(flavor_id): + cpu = ' CPU = "{}"'.format(template.template.cpu) + memory = ' MEMORY = "{}"'.format(template.template.memory) + context = ' CONTEXT = [NETWORK = "YES",SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]" ]' + graphics = ' GRAPHICS = [ LISTEN = "0.0.0.0", TYPE = "VNC" ]' + disk = ' DISK = [ IMAGE_ID = {}]'.format(image_id) + sched_requeriments = ' SCHED_REQUIREMENTS = "CLUSTER_ID={}"'.format(self.config["cluster"]["id"]) + template_updated = cpu + memory + context + graphics + disk + sched_requeriments + networkListVim = oca.VirtualNetworkPool(client) + networkListVim.info() + network = "" + for net in net_list: + network_found = False + for network_existingInVim in networkListVim: + if str(net["net_id"]) == str(network_existingInVim.id): + net["vim_id"] = network_existingInVim["id"] + network = 'NIC = [NETWORK = "{}",NETWORK_UNAME = "{}" ]'.format( + network_existingInVim.name, network_existingInVim.uname) + network_found = True + break + if not network_found: + raise vimconn.vimconnNotFoundException("Network {} not found".format(net["net_id"])) + template_updated += network + oca.VmTemplate.update(template, template_updated) + self.logger.info( + "Instanciating in OpenNebula a new VM name:{} id:{}".format(template.name, template.id)) + vminstance_id = template.instantiate(name=name) + return str(vminstance_id), None + raise vimconn.vimconnNotFoundException("Flavor {} not found".format(flavor_id)) + except Exception as e: + self.logger.error("Create new vm instance error: " + str(e)) + raise vimconn.vimconnException(e) + + def delete_vminstance(self, vm_id, created_items=None): + """Removes a VM instance from VIM, returns the deleted vm_id""" + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + vm_pool = oca.VirtualMachinePool(client) + vm_exist = False + for i in vm_pool: + if i.id == vm_id: + vm_exist = True + break + if not vm_exist: + self.logger.info("The vm " + str(vm_id) + " does not exist or is already deleted") + raise vimconn.vimconnNotFoundException("The vm {} does not exist or is already deleted".format(vm_id)) + params = ' \ + \ + one.vm.recover\ + \ + \ + {}:{}\ + \ + \ + {}\ + \ + \ + {}\ + \ + \ + '.format(self.user, self.passwd, str(vm_id), str(3)) + r = requests.post(self.url, params) + obj = untangle.parse(str(r.content)) + response_success = obj.methodResponse.params.param.value.array.data.value[0].boolean.cdata.encode('utf-8') + response = obj.methodResponse.params.param.value.array.data.value[1].i4.cdata.encode('utf-8') + # response can be the resource ID on success or the error string on failure. + response_error_code = obj.methodResponse.params.param.value.array.data.value[2].i4.cdata.encode('utf-8') + if response_success.lower() == "true": + return response + else: + raise vimconn.vimconnException("vm {} cannot be deleted with error_code {}: {}".format(vm_id, response_error_code, response)) + except Exception as e: + self.logger.error("Delete vm instance " + str(vm_id) + " error: " + str(e)) + raise vimconn.vimconnException(e) + + def refresh_vms_status(self, vm_list): + """Refreshes the status of the virtual machines""" + vm_dict = {} + try: + client = oca.Client(self.user + ':' + self.passwd, self.url) + vm_pool = oca.VirtualMachinePool(client) + vm_pool.info() + for vm_id in vm_list: + vm = {"interfaces": []} + vm_exist = False + vm_element = None + for i in vm_pool: + if i.id == vm_id: + vm_exist = True + vm_element = i + break + if not vm_exist: + self.logger.info("The vm " + str(vm_id) + " does not exist.") + vm['status'] = "DELETED" + vm['error_msg'] = ("The vm " + str(vm_id) + " does not exist.") + continue + vm_element.info() + vm["vim_info"] = None + VMstatus = vm_element.str_lcm_state + if VMstatus == "RUNNING": + vm['status'] = "ACTIVE" + elif "FAILURE" in VMstatus: + vm['status'] = "ERROR" + vm['error_msg'] = "VM failure" + else: + vm['status'] = "BUILD" + try: + for red in vm_element.template.nics: + interface = {'vim_info': None, "mac_address": str(red.mac), "vim_net_id": str(red.network_id), + "vim_interface_id": str(red.network_id)} + # maybe it should be 2 different keys for ip_address if an interface has ipv4 and ipv6 + if hasattr(red, 'ip'): + interface["ip_address"] = str(red.ip) + if hasattr(red, 'ip6_global'): + interface["ip_address"] = str(red.ip6_global) + vm["interfaces"].append(interface) + except Exception as e: + self.logger.error("Error getting vm interface_information " + type(e).__name__ + ":" + str(e)) + vm["status"] = "VIM_ERROR" + vm["error_msg"] = "Error getting vm interface_information " + type(e).__name__ + ":" + str(e) + vm_dict[vm_id] = vm + return vm_dict + except Exception as e: + self.logger.error(e) + for k in vm_dict: + vm_dict[k]["status"] = "VIM_ERROR" + vm_dict[k]["error_msg"] = str(e) + return vm_dict + + def refresh_nets_status(self, net_list): + """Get the status of the networks + Params: the list of network identifiers + Returns a dictionary with: + net_id: #VIM id of this network + status: #Mandatory. Text with one of: + # DELETED (not found at vim) + # VIM_ERROR (Cannot connect to VIM, VIM response error, ...) + # OTHER (Vim reported other status not understood) + # ERROR (VIM indicates an ERROR status) + # ACTIVE, INACTIVE, DOWN (admin down), + # BUILD (on building process) + # + error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR + vim_info: #Text with plain information obtained from vim (yaml.safe_dump) + """ + net_dict = {} + try: + for net_id in net_list: + net = {} + try: + net_vim = self.get_network(net_id) + net["status"] = net_vim["status"] + net["vim_info"] = None + except vimconn.vimconnNotFoundException as e: + self.logger.error("Exception getting net status: {}".format(str(e))) + net['status'] = "DELETED" + net['error_msg'] = str(e) + except vimconn.vimconnException as e: + self.logger.error(e) + net["status"] = "VIM_ERROR" + net["error_msg"] = str(e) + net_dict[net_id] = net + return net_dict + except vimconn.vimconnException as e: + self.logger.error(e) + for k in net_dict: + net_dict[k]["status"] = "VIM_ERROR" + net_dict[k]["error_msg"] = str(e) + return net_dict + + # to be used and fixed in future commits... not working properly + # def action_vminstance(self, vm_id, action_dict): + # """Send and action over a VM instance from VIM + # Returns the status""" + # try: + # if "console" in action_dict: + # console_dict = {"protocol": "http", + # "server": "10.95.84.42", + # "port": "29876", + # "suffix": "?token=4hsb9cu9utruakon4p3z" + # } + # return console_dict + # except vimconn.vimconnException as e: + # self.logger.error(e) diff --git a/requirements.txt b/requirements.txt index 374cb188..6e1068af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,4 +17,5 @@ pyvmomi progressbar prettytable boto - +untangle +oca diff --git a/scripts/install-openmano.sh b/scripts/install-openmano.sh index 5dd66c09..084ae0a7 100755 --- a/scripts/install-openmano.sh +++ b/scripts/install-openmano.sh @@ -259,6 +259,10 @@ then pip install prettytable || exit 1 pip install pyvmomi || exit 1 + # required for OpenNebula connector + pip install untangle || exit 1 + pip install -e git+https://github.com/python-oca/python-oca#egg=oca || exit 1 + # required for AWS connector [ "$_DISTRO" == "Ubuntu" ] && install_packages "python-boto" [ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ] && install_packages "python-boto" #TODO check if at Centos it exists with this name, or PIP should be used diff --git a/scripts/python-osm-ro.postinst b/scripts/python-osm-ro.postinst index f8670d3e..615cbc4a 100755 --- a/scripts/python-osm-ro.postinst +++ b/scripts/python-osm-ro.postinst @@ -28,6 +28,8 @@ pip install --upgrade progressbar pip install --upgrade prettytable pip install --upgrade pyvmomi pip install --upgrade pyang pyangbind +pip install untangle +pip install -e git+https://github.com/python-oca/python-oca#egg=oca systemctl enable osm-ro.service