same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright {yyyy} {name of copyright owner}
+ Copyright Copyright 2019 ETSI
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
return map(str, subnets)
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'start-address': ip_schema, first IP to grant
'count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
requests
netaddr
boto
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
# -*- coding: utf-8 -*-
+##
+# 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.
+##
-__author__='Sergio Gonzalez'
-__date__ ='$18-apr-2019 23:59:59$'
-
-from osm_ro import vimconn
+import base64
+import vimconn
import logging
+import netaddr
+import re
from os import getenv
-from uuid import uuid4
-
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.compute import ComputeManagementClient
+from azure.mgmt.compute.models import DiskCreateOption
+from msrestazure.azure_exceptions import CloudError
+from msrest.exceptions import AuthenticationError
+from requests.exceptions import ConnectionError
+
+__author__ = 'Isabel Lloret, Sergio Gonzalez, Alfonso Tierno'
+__date__ = '$18-apr-2019 23:59:59$'
+
+
+if getenv('OSMRO_PDB_DEBUG'):
+ import sys
+ print(sys.path)
+ import pdb
+ pdb.set_trace()
class vimconnector(vimconn.vimconnector):
+ # Translate azure provisioning state to OSM provision state
+ # The first three ones are the transitional status once a user initiated action has been requested
+ # Once the operation is complete, it will transition into the states Succeeded or Failed
+ # https://docs.microsoft.com/en-us/azure/virtual-machines/windows/states-lifecycle
+ provision_state2osm = {
+ "Creating": "BUILD",
+ "Updating": "BUILD",
+ "Deleting": "INACTIVE",
+ "Succeeded": "ACTIVE",
+ "Failed": "ERROR"
+ }
+
+ # Translate azure power state to OSM provision state
+ power_state2osm = {
+ "starting": "INACTIVE",
+ "running": "ACTIVE",
+ "stopping": "INACTIVE",
+ "stopped": "INACTIVE",
+ "unknown": "OTHER",
+ "deallocated": "BUILD",
+ "deallocating": "BUILD"
+ }
+
def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level=None,
config={}, persistent_info={}):
+ """
+ Constructor of VIM. Raise an exception is some needed parameter is missing, but it must not do any connectivity
+ checking against the VIM
+ Using common constructor parameters.
+ In this case: config must include the following parameters:
+ subscription_id: assigned azure subscription identifier
+ region_name: current region for azure network
+ resource_group: used for all azure created resources
+ vnet_name: base vnet for azure, created networks will be subnets from this base network
+ config may also include the following parameter:
+ flavors_pattern: pattern that will be used to select a range of vm sizes, for example
+ "^((?!Standard_B).)*$" will filter out Standard_B range that is cheap but is very overused
+ "^Standard_B" will select a serie B maybe for test environment
+ """
vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level,
config, persistent_info)
+ # Variable that indicates if client must be reloaded or initialized
+ self.reload_client = True
+
+ self.vnet_address_space = None
# LOGGER
self.logger = logging.getLogger('openmano.vim.azure')
if log_level:
logging.basicConfig()
self.logger.setLevel(getattr(logging, log_level))
- # CREDENTIALS
- self.credentials = ServicePrincipalCredentials(
- client_id=user,
- secret=passwd,
- tenant=(tenant_id or tenant_name)
- )
+ self.tenant = (tenant_id or tenant_name)
+
+ # Store config to create azure subscription later
+ self._config = {
+ "user": user,
+ "passwd": passwd,
+ "tenant": tenant_id or tenant_name
+ }
# SUBSCRIPTION
if 'subscription_id' in config:
- self.subscription_id = config.get('subscription_id')
- self.logger.debug('Setting subscription '+str(self.subscription_id))
+ self._config["subscription_id"] = config.get('subscription_id')
+ # self.logger.debug('Setting subscription to: %s', self.config["subscription_id"])
else:
raise vimconn.vimconnException('Subscription not specified')
+
# REGION
if 'region_name' in config:
self.region = config.get('region_name')
else:
raise vimconn.vimconnException('Azure region_name is not specified at config')
+
# RESOURCE_GROUP
if 'resource_group' in config:
self.resource_group = config.get('resource_group')
else:
raise vimconn.vimconnException('Azure resource_group is not specified at config')
+
# VNET_NAME
if 'vnet_name' in config:
self.vnet_name = config["vnet_name"]
# public ssh key
self.pub_key = config.get('pub_key')
+
+ # flavor pattern regex
+ if 'flavors_pattern' in config:
+ self._config['flavors_pattern'] = config['flavors_pattern']
def _reload_connection(self):
"""
- Sets connections to work with Azure service APIs
- :return:
+ Called before any operation, checks python azure clients
"""
- self.logger.debug('Reloading API Connection')
- try:
- self.conn = ResourceManagementClient(self.credentials, self.subscription_id)
- self.conn_compute = ComputeManagementClient(self.credentials, self.subscription_id)
- self.conn_vnet = NetworkManagementClient(self.credentials, self.subscription_id)
- self._check_or_create_resource_group()
- self._check_or_create_vnet()
- except Exception as e:
- self.format_vimconn_exception(e)
+ if self.reload_client:
+ self.logger.debug('reloading azure client')
+ try:
+ self.credentials = ServicePrincipalCredentials(
+ client_id=self._config["user"],
+ secret=self._config["passwd"],
+ tenant=self._config["tenant"]
+ )
+ self.conn = ResourceManagementClient(self.credentials, self._config["subscription_id"])
+ self.conn_compute = ComputeManagementClient(self.credentials, self._config["subscription_id"])
+ self.conn_vnet = NetworkManagementClient(self.credentials, self._config["subscription_id"])
+ self._check_or_create_resource_group()
+ self._check_or_create_vnet()
+
+ # Set to client created
+ self.reload_client = False
+ except Exception as e:
+ self._format_vimconn_exception(e)
def _get_resource_name_from_resource_id(self, resource_id):
- return str(resource_id.split('/')[-1])
+ """
+ Obtains resource_name from the azure complete identifier: resource_name will always be last item
+ """
+ try:
+ resource = str(resource_id.split('/')[-1])
+ return resource
+ except Exception as e:
+ raise vimconn.vimconnException("Unable to get resource name from resource_id '{}' Error: '{}'".
+ format(resource_id, e))
def _get_location_from_resource_group(self, resource_group_name):
- return self.conn.resource_groups.get(resource_group_name).location
-
+ try:
+ location = self.conn.resource_groups.get(resource_group_name).location
+ return location
+ except Exception as e:
+ raise vimconn.vimconnNotFoundException("Location '{}' not found".format(resource_group_name))
+
def _get_resource_group_name_from_resource_id(self, resource_id):
- return str(resource_id.split('/')[4])
+
+ try:
+ rg = str(resource_id.split('/')[4])
+ return rg
+ except Exception as e:
+ raise vimconn.vimconnException("Unable to get resource group from invalid resource_id format '{}'".
+ format(resource_id))
+
+ def _get_net_name_from_resource_id(self, resource_id):
+
+ try:
+ net_name = str(resource_id.split('/')[8])
+ return net_name
+ except Exception as e:
+ raise vimconn.vimconnException("Unable to get azure net_name from invalid resource_id format '{}'".
+ format(resource_id))
def _check_subnets_for_vm(self, net_list):
# All subnets must belong to the same resource group and vnet
- if len(set(self._get_resource_group_name_from_resource_id(net['id']) +
- self._get_resource_name_from_resource_id(net['id']) for net in net_list)) != 1:
- raise self.format_vimconn_exception('Azure VMs can only attach to subnets in same VNET')
+ rg_vnet = set(self._get_resource_group_name_from_resource_id(net['net_id']) +
+ self._get_net_name_from_resource_id(net['net_id']) for net in net_list)
+
+ if len(rg_vnet) != 1:
+ raise self._format_vimconn_exception('Azure VMs can only attach to subnets in same VNET')
- def format_vimconn_exception(self, e):
+ def _format_vimconn_exception(self, e):
"""
- Params: an Exception object
- :param e:
- :return: Raises the proper vimconnException
+ Transforms a generic or azure exception to a vimcommException
"""
- self.conn = None
- self.conn_vnet = None
- raise vimconn.vimconnConnectionException(type(e).__name__ + ': ' + str(e))
+ if isinstance(e, vimconn.vimconnException):
+ raise
+ elif isinstance(e, AuthenticationError):
+ raise vimconn.vimconnAuthException(type(e).__name__ + ': ' + str(e))
+ elif isinstance(e, ConnectionError):
+ raise vimconn.vimconnConnectionException(type(e).__name__ + ': ' + str(e))
+ else:
+ # In case of generic error recreate client
+ self.reload_client = True
+ raise vimconn.vimconnException(type(e).__name__ + ': ' + str(e))
def _check_or_create_resource_group(self):
"""
- Creates a resource group in indicated region
- :return: None
+ Creates the base resource group if it does not exist
"""
- self.logger.debug('Creating RG {} in location {}'.format(self.resource_group, self.region))
- self.conn.resource_groups.create_or_update(self.resource_group, {'location': self.region})
+ try:
+ rg_exists = self.conn.resource_groups.check_existence(self.resource_group)
+ if not rg_exists:
+ self.logger.debug("create base rgroup: %s", self.resource_group)
+ self.conn.resource_groups.create_or_update(self.resource_group, {'location': self.region})
+ except Exception as e:
+ self._format_vimconn_exception(e)
def _check_or_create_vnet(self):
+ """
+ Try to get existent base vnet, in case it does not exist it creates it
+ """
+ try:
+ vnet = self.conn_vnet.virtual_networks.get(self.resource_group, self.vnet_name)
+ self.vnet_address_space = vnet.address_space.address_prefixes[0]
+ self.vnet_id = vnet.id
+ return
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ pass
+ # continue and create it
+ else:
+ self._format_vimconn_exception(e)
+
+ # if it does not exist, create it
try:
vnet_params = {
'location': self.region,
'address_space': {
- 'address_prefixes': "10.0.0.0/8"
+ 'address_prefixes': ["10.0.0.0/8"]
},
}
+ self.vnet_address_space = "10.0.0.0/8"
+
+ self.logger.debug("create base vnet: %s", self.vnet_name)
self.conn_vnet.virtual_networks.create_or_update(self.resource_group, self.vnet_name, vnet_params)
+ vnet = self.conn_vnet.virtual_networks.get(self.resource_group, self.vnet_name)
+ self.vnet_id = vnet.id
except Exception as e:
- self.format_vimconn_exception(e)
+ self._format_vimconn_exception(e)
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""
Adds a tenant network to VIM
:param net_name: name of the network
- :param net_type:
+ :param net_type: not used for azure networks
:param ip_profile: is a dict containing the IP parameters of the network (Currently only IPv4 is implemented)
'ip-version': can be one of ['IPv4','IPv6']
'subnet-address': ip_prefix_schema, that is X.X.X.X/Y
- 'gateway-address': (Optional) ip_schema, that is X.X.X.X
- 'dns-address': (Optional) ip_schema,
- 'dhcp': (Optional) dict containing
+ 'gateway-address': (Optional) ip_schema, that is X.X.X.X, not implemented for azure connector
+ 'dns-address': (Optional) ip_schema, not implemented for azure connector
+ 'dhcp': (Optional) dict containing, not implemented for azure connector
'enabled': {'type': 'boolean'},
'start-address': ip_schema, first IP to grant
'count': number of IPs to grant.
- :param shared:
- :param vlan:
+ :param shared: Not allowed for Azure Connector
+ :param provider_network_profile: (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
:return: a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
as not present.
"""
-
return self._new_subnet(net_name, ip_profile)
def _new_subnet(self, net_name, ip_profile):
"""
- Adds a tenant network to VIM. It creates a new VNET with a single subnet
- :param net_name:
+ Adds a tenant network to VIM. It creates a new subnet at existing base vnet
+ :param net_name: subnet name
:param ip_profile:
- :return:
+ subnet-address: if it is not provided a subnet/24 in the default vnet is created,
+ otherwise it creates a subnet in the indicated address
+ :return: a tuple with the network identifier and created_items, or raises an exception on error
"""
- self.logger.debug('Adding a subnet to VNET '+self.vnet_name)
+ self.logger.debug('create subnet name %s, ip_profile %s', net_name, ip_profile)
self._reload_connection()
if ip_profile is None:
- # TODO get a non used vnet ip range /24 and allocate automatically
- raise vimconn.vimconnException('Azure cannot create VNET with no CIDR')
+ # get a non used vnet ip range /24 and allocate automatically inside the range self.vnet_address_space
+ used_subnets = self.get_network_list()
+ for ip_range in netaddr.IPNetwork(self.vnet_address_space).subnet(24):
+ for used_subnet in used_subnets:
+ subnet_range = netaddr.IPNetwork(used_subnet["cidr_block"])
+ if subnet_range in ip_range or ip_range in subnet_range:
+ # this range overlaps with an existing subnet ip range. Breaks and look for another
+ break
+ else:
+ ip_profile = {"subnet_address": str(ip_range)}
+ self.logger.debug('dinamically obtained ip_profile: %s', ip_range)
+ break
+ else:
+ raise vimconn.vimconnException("Cannot find a non-used subnet range in {}".
+ format(self.vnet_address_space))
+ else:
+ ip_profile = {"subnet_address": ip_profile['subnet_address']}
try:
- vnet_params= {
- 'location': self.region,
- 'address_space': {
- 'address_prefixes': [ip_profile['subnet_address']]
- },
- 'subnets': [
- {
- 'name': "{}-{}".format(net_name[:24], uuid4()),
- 'address_prefix': ip_profile['subnet_address']
- }
- ]
+ # subnet_name = "{}-{}".format(net_name[:24], uuid4())
+ subnet_params = {
+ 'address_prefix': ip_profile['subnet_address']
}
- self.conn_vnet.virtual_networks.create_or_update(self.resource_group, self.vnet_name, vnet_params)
- # TODO return a tuple (subnet-ID, None)
+ # Assign a not duplicated net name
+ subnet_name = self._get_unused_subnet_name(net_name)
+
+ self.logger.debug('creating subnet_name: {}'.format(subnet_name))
+ async_creation = self.conn_vnet.subnets.create_or_update(self.resource_group, self.vnet_name,
+ subnet_name, subnet_params)
+ async_creation.wait()
+ self.logger.debug('created subnet_name: {}'.format(subnet_name))
+
+ return "{}/subnets/{}".format(self.vnet_id, subnet_name), None
except Exception as e:
- self.format_vimconn_exception(e)
+ self._format_vimconn_exception(e)
+
+ def _get_unused_subnet_name(self, subnet_name):
+ """
+ Adds a prefix to the subnet_name with a number in case the indicated name is repeated
+ Checks subnets with the indicated name (without suffix) and adds a suffix with a number
+ """
+ all_subnets = self.conn_vnet.subnets.list(self.resource_group, self.vnet_name)
+ # Filter to subnets starting with the indicated name
+ subnets = list(filter(lambda subnet: (subnet.name.startswith(subnet_name)), all_subnets))
+ net_names = [str(subnet.name) for subnet in subnets]
- def _create_nic(self, subnet_id, nic_name, static_ip=None):
+ # get the name with the first not used suffix
+ name_suffix = 0
+ # name = subnet_name + "-" + str(name_suffix)
+ name = subnet_name # first subnet created will have no prefix
+ while name in net_names:
+ name_suffix += 1
+ name = subnet_name + "-" + str(name_suffix)
+ return name
+
+ def _create_nic(self, net, nic_name, static_ip=None):
+
+ self.logger.debug('create nic name %s, net_name %s', nic_name, net)
self._reload_connection()
-
- resource_group_name=self._get_resource_group_name_from_resource_id(subnet_id)
- location = self._get_location_from_resource_group(resource_group_name)
-
- if static_ip:
- async_nic_creation = self.conn_vnet.network_interfaces.create_or_update(
- resource_group_name,
- nic_name,
- {
- 'location': location,
- 'ip_configurations': [{
- 'name': nic_name + 'ipconfiguration',
- 'privateIPAddress': static_ip,
- 'privateIPAllocationMethod': 'Static',
- 'subnet': {
- 'id': subnet_id
- }
- }]
- }
- )
- else:
- async_nic_creation = self.conn_vnet.network_interfaces.create_or_update(
- resource_group_name,
- nic_name,
- {
+
+ subnet_id = net['net_id']
+ location = self._get_location_from_resource_group(self.resource_group)
+ try:
+ net_ifz = {'location': location}
+ net_ip_config = {'name': nic_name + '-ipconfiguration', 'subnet': {'id': subnet_id}}
+ if static_ip:
+ net_ip_config['privateIPAddress'] = static_ip
+ net_ip_config['privateIPAllocationMethod'] = 'Static'
+ net_ifz['ip_configurations'] = [net_ip_config]
+ mac_address = net.get('mac_address')
+ if mac_address:
+ net_ifz['mac_address'] = mac_address
+
+ async_nic_creation = self.conn_vnet.network_interfaces.create_or_update(self.resource_group, nic_name,
+ net_ifz)
+ async_nic_creation.wait()
+ self.logger.debug('created nic name %s', nic_name)
+
+ public_ip = net.get('floating_ip')
+ if public_ip:
+ public_ip_address_params = {
'location': location,
- 'ip_configurations': [{
- 'name': nic_name + 'ipconfiguration',
- 'subnet': {
- 'id': subnet_id
- }
- }]
+ 'public_ip_allocation_method': 'Dynamic'
}
- )
+ public_ip_name = nic_name + '-public-ip'
+ public_ip = self.conn_vnet.public_ip_addresses.create_or_update(
+ self.resource_group,
+ public_ip_name,
+ public_ip_address_params
+ )
+ self.logger.debug('created public IP: {}'.format(public_ip.result()))
+
+ # Associate NIC to Public IP
+ nic_data = self.conn_vnet.network_interfaces.get(
+ self.resource_group,
+ nic_name)
+
+ nic_data.ip_configurations[0].public_ip_address = public_ip.result()
+
+ self.conn_vnet.network_interfaces.create_or_update(
+ self.resource_group,
+ nic_name,
+ nic_data)
+
+ except Exception as e:
+ self._format_vimconn_exception(e)
return async_nic_creation.result()
- def get_image_list(self, filter_dict={}):
+ def new_flavor(self, flavor_data):
"""
- The urn contains for marketplace 'publisher:offer:sku:version'
+ It is not allowed to create new flavors in Azure, must always use an existing one
+ """
+ raise vimconn.vimconnAuthException("It is not possible to create new flavors in AZURE")
- :param filter_dict:
- :return:
+ def new_tenant(self, tenant_name, tenant_description):
"""
- image_list = []
+ It is not allowed to create new tenants in azure
+ """
+ raise vimconn.vimconnAuthException("It is not possible to create a TENANT in AZURE")
+
+ def new_image(self, image_dict):
+ """
+ It is not allowed to create new images in Azure, must always use an existing one
+ """
+ raise vimconn.vimconnAuthException("It is not possible to create new images in AZURE")
+
+ def get_image_id_from_path(self, path):
+ """Get the image id from image path in the VIM database.
+ Returns the image_id or raises a vimconnNotFoundException
+ """
+ raise vimconn.vimconnAuthException("It is not possible to obtain image from path in AZURE")
+
+ def get_image_list(self, filter_dict={}):
+ """Obtain tenant images from VIM
+ Filter_dict can be:
+ name: image name with the format: publisher:offer:sku:version
+ If some part of the name is provide ex: publisher:offer it will search all availables skus and version
+ for the provided publisher and offer
+ id: image uuid, currently not supported for azure
+ Returns the image list of dictionaries:
+ [{<the fields at Filter_dict plus some VIM specific>}, ...]
+ List can be empty
+ """
+
+ self.logger.debug("get_image_list filter {}".format(filter_dict))
self._reload_connection()
- if filter_dict.get("name"):
- params = filter_dict["name"].split(":")
- if len(params) >= 3:
+ try:
+ image_list = []
+ if filter_dict.get("name"):
+ # name will have the format 'publisher:offer:sku:version'
+ # publisher is required, offer sku and version will be searched if not provided
+ params = filter_dict["name"].split(":")
publisher = params[0]
- offer = params[1]
- sku = params[2]
- version = None
- if len(params) == 4:
- version = params[3]
- images = self.conn_compute.virtual_machine_images.list(self.region, publisher, offer, sku)
- for image in images:
- if version:
- image_version = str(image.id).split("/")[-1]
- if image_version != version:
- continue
- image_list.append({
- 'id': str(image.id),
- 'name': self._get_resource_name_from_resource_id(image.id)
- })
- return image_list
-
- images = self.conn_compute.virtual_machine_images.list()
-
- for image in images:
- # TODO implement filter_dict
- if filter_dict:
- if filter_dict.get("id") and str(image.id) != filter_dict["id"]:
- continue
- if filter_dict.get("name") and \
- self._get_resource_name_from_resource_id(image.id) != filter_dict["name"]:
- continue
- # TODO add checksum
- image_list.append({
- 'id': str(image.id),
- 'name': self._get_resource_name_from_resource_id(image.id),
- })
+ if publisher:
+ # obtain offer list
+ offer_list = self._get_offer_list(params, publisher)
+ for offer in offer_list:
+ # obtain skus
+ sku_list = self._get_sku_list(params, publisher, offer)
+ for sku in sku_list:
+ # if version is defined get directly version, else list images
+ if len(params) == 4 and params[3]:
+ version = params[3]
+ image_list = self._get_version_image_list(publisher, offer, sku, version)
+ else:
+ image_list = self._get_sku_image_list(publisher, offer, sku)
+ else:
+ raise vimconn.vimconnAuthException(
+ "List images in Azure must include name param with at least publisher")
+ else:
+ raise vimconn.vimconnAuthException("List images in Azure must include name param with at"
+ " least publisher")
+
+ return image_list
+ except Exception as e:
+ self._format_vimconn_exception(e)
+
+ def _get_offer_list(self, params, publisher):
+ """
+ Helper method to obtain offer list for defined publisher
+ """
+ if len(params) >= 2 and params[1]:
+ return [params[1]]
+ else:
+ try:
+ # get list of offers from azure
+ result_offers = self.conn_compute.virtual_machine_images.list_offers(self.region, publisher)
+ return [offer.name for offer in result_offers]
+ except CloudError as e:
+ # azure raises CloudError when not found
+ self.logger.info("error listing offers for publisher {}, Error: {}".format(publisher, e))
+ return []
+
+ def _get_sku_list(self, params, publisher, offer):
+ """
+ Helper method to obtain sku list for defined publisher and offer
+ """
+ if len(params) >= 3 and params[2]:
+ return [params[2]]
+ else:
+ try:
+ # get list of skus from azure
+ result_skus = self.conn_compute.virtual_machine_images.list_skus(self.region, publisher, offer)
+ return [sku.name for sku in result_skus]
+ except CloudError as e:
+ # azure raises CloudError when not found
+ self.logger.info("error listing skus for publisher {}, offer {}, Error: {}".format(publisher, offer, e))
+ return []
+
+ def _get_sku_image_list(self, publisher, offer, sku):
+ """
+ Helper method to obtain image list for publisher, offer and sku
+ """
+ image_list = []
+ try:
+ result_images = self.conn_compute.virtual_machine_images.list(self.region, publisher, offer, sku)
+ for result_image in result_images:
+ image_list.append({
+ 'id': str(result_image.id),
+ 'name': ":".join([publisher, offer, sku, result_image.name])
+ })
+ except CloudError as e:
+ self.logger.info(
+ "error listing skus for publisher {}, offer {}, Error: {}".format(publisher, offer, e))
+ image_list = []
+ return image_list
+
+ def _get_version_image_list(self, publisher, offer, sku, version):
+ image_list = []
+ try:
+ result_image = self.conn_compute.virtual_machine_images.get(self.region, publisher, offer, sku, version)
+ if result_image:
+ image_list.append({
+ 'id': str(result_image.id),
+ 'name': ":".join([publisher, offer, sku, version])
+ })
+ except CloudError as e:
+ # azure gives CloudError when not found
+ self.logger.info("error listing images for publisher {}, offer {}, sku {}, version {} Error: {}".
+ format(publisher, offer, sku, version, e))
+ image_list = []
return image_list
def get_network_list(self, filter_dict={}):
"""Obtain tenant networks of VIM
Filter_dict can be:
name: network name
- id: network uuid
- shared: boolean
- tenant_id: tenant
- admin_state_up: boolean
- status: 'ACTIVE'
+ id: network id
+ shared: boolean, not implemented in Azure
+ tenant_id: tenant, not used in Azure, all networks same tenants
+ admin_state_up: boolean, not implemented in Azure
+ status: 'ACTIVE', not implemented in Azure #
Returns the network list of dictionaries
"""
- self.logger.debug('Getting all subnets from VIM')
+ # self.logger.debug('getting network list for vim, filter %s', filter_dict)
try:
self._reload_connection()
- vnet = self.conn_vnet.virtual_networks.get(self.config["resource_group"], self.vnet_name)
+
+ vnet = self.conn_vnet.virtual_networks.get(self.resource_group, self.vnet_name)
subnet_list = []
-
+
for subnet in vnet.subnets:
- # TODO implement filter_dict
if filter_dict:
if filter_dict.get("id") and str(subnet.id) != filter_dict["id"]:
continue
if filter_dict.get("name") and \
- self._get_resource_name_from_resource_id(subnet.id) != filter_dict["name"]:
+ str(subnet.name) != filter_dict["name"]:
continue
+ name = self._get_resource_name_from_resource_id(subnet.id)
+
subnet_list.append({
'id': str(subnet.id),
- 'name': self._get_resource_name_from_resource_id(subnet.id),
- 'status': str(vnet.provisioning_state), # TODO Does subnet contains status???
- 'cidr_block': str(subnet.address_prefix)
- }
- )
+ 'name': name,
+ 'status': self.provision_state2osm[subnet.provisioning_state],
+ 'cidr_block': str(subnet.address_prefix),
+ 'type': 'bridge',
+ 'shared': False
+ })
+
return subnet_list
except Exception as e:
- self.format_vimconn_exception(e)
+ self._format_vimconn_exception(e)
- def new_vminstance(self, vm_name, description, start, image_id, flavor_id, net_list, cloud_config=None,
+ 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):
- return self._new_vminstance(vm_name, image_id, flavor_id, net_list)
-
- def _new_vminstance(self, vm_name, image_id, flavor_id, net_list, cloud_config=None, disk_list=None,
- availability_zone_index=None, availability_zone_list=None):
- #Create NICs
+ self.logger.debug("new vm instance name: %s, image_id: %s, flavor_id: %s, net_list: %s, cloud_config: %s, "
+ "disk_list: %s, availability_zone_index: %s, availability_zone_list: %s",
+ name, image_id, flavor_id, net_list, cloud_config, disk_list,
+ availability_zone_index, availability_zone_list)
+
+ self._reload_connection()
+
+ # Validate input data is valid
+ # The virtual machine name must have less or 64 characters and it can not have the following
+ # characters: (~ ! @ # $ % ^ & * ( ) = + _ [ ] { } \ | ; : ' " , < > / ?.)
+ vm_name = self._check_vm_name(name)
+ # Obtain vm unused name
+ vm_name = self._get_unused_vm_name(vm_name)
+
+ # At least one network must be provided
+ if not net_list:
+ raise vimconn.vimconnException("At least one net must be provided to create a new VM")
+
+ # image_id are several fields of the image_id
+ image_reference = self._get_image_reference(image_id)
+
self._check_subnets_for_vm(net_list)
vm_nics = []
for idx, net in enumerate(net_list):
- subnet_id=net['subnet_id']
+ # Fault with subnet_id
+ # subnet_id=net['subnet_id']
+ # subnet_id=net['net_id']
nic_name = vm_name + '-nic-'+str(idx)
- vm_nic = self._create_nic(subnet_id, nic_name)
- vm_nics.append({ 'id': str(vm_nic.id)})
+ vm_nic = self._create_nic(net, nic_name, net.get('ip_address'))
+ vm_nics.append({'id': str(vm_nic.id)})
+ net['vim_id'] = vm_nic.id
try:
+
+ # cloud-init configuration
+ # cloud config
+ if cloud_config:
+ config_drive, userdata = self._create_user_data(cloud_config)
+ custom_data = base64.b64encode(userdata.encode('utf-8')).decode('latin-1')
+ key_data = None
+ key_pairs = cloud_config.get("key-pairs")
+ if key_pairs:
+ key_data = key_pairs[0]
+
+ if cloud_config.get("users"):
+ user_name = cloud_config.get("users")[0].get("name", "osm")
+ else:
+ user_name = "osm" # DEFAULT USER IS OSM
+
+ os_profile = {
+ 'computer_name': vm_name,
+ 'admin_username': user_name,
+ 'linux_configuration': {
+ "disable_password_authentication": True,
+ "ssh": {
+ "public_keys": [{
+ "path": "/home/{}/.ssh/authorized_keys".format(user_name),
+ "key_data": key_data
+ }]
+ }
+ },
+ 'custom_data': custom_data
+ }
+ else:
+ os_profile = {
+ 'computer_name': vm_name,
+ 'admin_username': 'osm',
+ 'admin_password': 'Osm4u!',
+ }
+
vm_parameters = {
'location': self.region,
- 'os_profile': {
- 'computer_name': vm_name, # TODO if vm_name cannot be repeated add uuid4() suffix
- 'admin_username': 'sergio', # TODO is it mandatory???
- 'linuxConfiguration': {
- 'disablePasswordAuthentication': 'true',
- 'ssh': {
- 'publicKeys': [
- {
- 'path': '/home/sergio/.ssh/authorized_keys',
- 'keyData': self.pub_key
- }
- ]
- }
- }
-
- },
+ 'os_profile': os_profile,
'hardware_profile': {
- 'vm_size':flavor_id
+ 'vm_size': flavor_id
},
'storage_profile': {
- 'image_reference': image_id
- },
- 'network_profile': {
- 'network_interfaces': [
- vm_nics[0]
- ]
+ 'image_reference': image_reference
}
}
+
+ # Add data disks if they are provided
+ if disk_list:
+ data_disks = []
+ for lun_name, disk in enumerate(disk_list):
+ self.logger.debug("add disk size: %s, image: %s", disk.get("size"), disk.get("image_id"))
+ if not disk.get("image_id"):
+ data_disks.append({
+ 'lun': lun_name, # You choose the value, depending of what is available for you
+ 'name': vm_name + "_data_disk-" + str(lun_name),
+ 'create_option': DiskCreateOption.empty,
+ 'disk_size_gb': disk.get("size")
+ })
+ else:
+ # self.logger.debug("currently not able to create data disks from image for azure, ignoring")
+ data_disks.append({
+ 'lun': lun_name, # You choose the value, depending of what is available for you
+ 'name': vm_name + "_data_disk-" + str(lun_name),
+ 'create_option': 'Attach',
+ 'disk_size_gb': disk.get("size"),
+ 'managed_disk': {
+ 'id': disk.get("image_id")
+ }
+ })
+
+ if data_disks:
+ vm_parameters["storage_profile"]["data_disks"] = data_disks
+
+ # If the machine has several networks one must be marked as primary
+ # As it is not indicated in the interface the first interface will be marked as primary
+ if len(vm_nics) > 1:
+ for idx, vm_nic in enumerate(vm_nics):
+ if idx == 0:
+ vm_nics[0]['Primary'] = True
+ else:
+ vm_nics[idx]['Primary'] = False
+
+ vm_parameters['network_profile'] = {'network_interfaces': vm_nics}
+
+ self.logger.debug("create vm name: %s", vm_name)
creation_result = self.conn_compute.virtual_machines.create_or_update(
self.resource_group,
- vm_name,
+ vm_name,
vm_parameters
)
+ # creation_result.wait()
+ result = creation_result.result()
+ self.logger.debug("created vm name: %s", vm_name)
+
+ if start:
+ self.conn_compute.virtual_machines.start(
+ self.resource_group,
+ vm_name)
+ # start_result.wait()
+
+ return result.id, None
- run_command_parameters = {
- 'command_id': 'RunShellScript', # For linux, don't change it
- 'script': [
- 'date > /home/sergio/test.txt'
- ]
+ # run_command_parameters = {
+ # 'command_id': 'RunShellScript', # For linux, don't change it
+ # 'script': [
+ # 'date > /tmp/test.txt'
+ # ]
+ # }
+ except Exception as e:
+ self.logger.debug('Exception creating new vminstance: %s', e, exc_info=True)
+ self._format_vimconn_exception(e)
+
+ def _get_unused_vm_name(self, vm_name):
+ """
+ Checks the vm name and in case it is used adds a suffix to the name to allow creation
+ :return:
+ """
+ all_vms = self.conn_compute.virtual_machines.list(self.resource_group)
+ # Filter to vms starting with the indicated name
+ vms = list(filter(lambda vm: (vm.name.startswith(vm_name)), all_vms))
+ vm_names = [str(vm.name) for vm in vms]
+
+ # get the name with the first not used suffix
+ name_suffix = 0
+ # name = subnet_name + "-" + str(name_suffix)
+ name = vm_name # first subnet created will have no prefix
+ while name in vm_names:
+ name_suffix += 1
+ name = vm_name + "-" + str(name_suffix)
+ return name
+
+ # It is necesary extract from image_id data to create the VM with this format
+ # 'image_reference': {
+ # 'publisher': vm_reference['publisher'],
+ # 'offer': vm_reference['offer'],
+ # 'sku': vm_reference['sku'],
+ # 'version': vm_reference['version']
+ # },
+ def _get_image_reference(self, image_id):
+
+ try:
+ # The data input format example:
+ # /Subscriptions/ca3d18ab-d373-4afb-a5d6-7c44f098d16a/Providers/Microsoft.Compute/Locations/westeurope/
+ # Publishers/Canonical/ArtifactTypes/VMImage/
+ # Offers/UbuntuServer/
+ # Skus/18.04-LTS/
+ # Versions/18.04.201809110
+ publisher = str(image_id.split('/')[8])
+ offer = str(image_id.split('/')[12])
+ sku = str(image_id.split('/')[14])
+ version = str(image_id.split('/')[16])
+
+ return {
+ 'publisher': publisher,
+ 'offer': offer,
+ 'sku': sku,
+ 'version': version
}
- poller = self.conn_compute.virtual_machines.run_command(
- self.resource_group,
- vm_name,
- run_command_parameters
- )
- # TODO return a tuple (vm-ID, None)
except Exception as e:
- self.format_vimconn_exception(e)
+ raise vimconn.vimconnException(
+ "Unable to get image_reference from invalid image_id format: '{}'".format(image_id))
+
+ # Azure VM names can not have some special characters
+ def _check_vm_name(self, vm_name):
+ """
+ Checks vm name, in case the vm has not allowed characters they are removed, not error raised
+ """
+
+ chars_not_allowed_list = "~!@#$%^&*()=+_[]{}|;:<>/?."
+
+ # First: the VM name max length is 64 characters
+ vm_name_aux = vm_name[:64]
+
+ # Second: replace not allowed characters
+ for elem in chars_not_allowed_list:
+ # Check if string is in the main string
+ if elem in vm_name_aux:
+ # self.logger.debug('Dentro del IF')
+ # Replace the string
+ vm_name_aux = vm_name_aux.replace(elem, '-')
+
+ return vm_name_aux
def get_flavor_id_from_data(self, flavor_dict):
- self.logger.debug("Getting flavor id from data")
- self._reload_connection()
- vm_sizes_list = [vm_size.serialize() for vm_size in self.conn_compute.virtual_machine_sizes.list(self.region)]
- cpus = flavor_dict['vcpus']
- memMB = flavor_dict['ram']
+ self.logger.debug("getting flavor id from data, flavor_dict: %s", flavor_dict)
+ filter_dict = flavor_dict or {}
+ try:
+ self._reload_connection()
+ vm_sizes_list = [vm_size.serialize() for vm_size in
+ self.conn_compute.virtual_machine_sizes.list(self.region)]
+
+ cpus = filter_dict.get('vcpus') or 0
+ memMB = filter_dict.get('ram') or 0
+
+ # Filter
+ if self._config.get("flavors_pattern"):
+ filtered_sizes = [size for size in vm_sizes_list if size['numberOfCores'] >= cpus and
+ size['memoryInMB'] >= memMB and
+ re.search(self._config.get("flavors_pattern"), size["name"])]
+ else:
+ filtered_sizes = [size for size in vm_sizes_list if size['numberOfCores'] >= cpus and
+ size['memoryInMB'] >= memMB]
- filteredSizes = [size for size in vm_sizes_list if size['numberOfCores'] > cpus and size['memoryInMB'] > memMB]
- listedFilteredSizes = sorted(filteredSizes, key=lambda k: k['numberOfCores'])
+ # Sort
+ listedFilteredSizes = sorted(filtered_sizes, key=lambda k: (k['numberOfCores'], k['memoryInMB'],
+ k['resourceDiskSizeInMB']))
- return listedFilteredSizes[0]['name']
+ if listedFilteredSizes:
+ return listedFilteredSizes[0]['name']
+ raise vimconn.vimconnNotFoundException("Cannot find any flavor matching '{}'".format(str(flavor_dict)))
+
+ except Exception as e:
+ self._format_vimconn_exception(e)
+
+ def _get_flavor_id_from_flavor_name(self, flavor_name):
+
+ # self.logger.debug("getting flavor id from flavor name {}".format(flavor_name))
+ try:
+ self._reload_connection()
+ vm_sizes_list = [vm_size.serialize() for vm_size in
+ self.conn_compute.virtual_machine_sizes.list(self.region)]
+
+ output_flavor = None
+ for size in vm_sizes_list:
+ if size['name'] == flavor_name:
+ output_flavor = size
+
+ # None is returned if not found anything
+ return output_flavor
+
+ except Exception as e:
+ self._format_vimconn_exception(e)
def check_vim_connectivity(self):
try:
raise vimconn.vimconnException("Connectivity issue with Azure API: {}".format(e))
def get_network(self, net_id):
- resGroup = self._get_resource_group_name_from_resource_id(net_id)
- resName = self._get_resource_name_from_resource_id(net_id)
-
+
+ # self.logger.debug('get network id: {}'.format(net_id))
+ # res_name = self._get_resource_name_from_resource_id(net_id)
self._reload_connection()
- vnet = self.conn_vnet.virtual_networks.get(resGroup, resName)
- return vnet
+ filter_dict = {'name': net_id}
+ network_list = self.get_network_list(filter_dict)
+
+ if not network_list:
+ raise vimconn.vimconnNotFoundException("network '{}' not found".format(net_id))
+ else:
+ return network_list[0]
+
+ def delete_network(self, net_id, created_items=None):
+
+ self.logger.debug('deleting network {} - {}'.format(self.resource_group, net_id))
- def delete_network(self, net_id):
- resGroup = self._get_resource_group_name_from_resource_id(net_id)
- resName = self._get_resource_name_from_resource_id(net_id)
-
self._reload_connection()
- self.conn_vnet.virtual_networks.delete(resGroup, resName)
+ res_name = self._get_resource_name_from_resource_id(net_id)
+ filter_dict = {'name': res_name}
+ network_list = self.get_network_list(filter_dict)
+ if not network_list:
+ raise vimconn.vimconnNotFoundException("network '{}' not found".format(net_id))
+
+ try:
+ # Subnet API fails (CloudError: Azure Error: ResourceNotFound)
+ # Put the initial virtual_network API
+ async_delete = self.conn_vnet.subnets.delete(self.resource_group, self.vnet_name, res_name)
+ async_delete.wait()
+ return net_id
+
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ raise vimconn.vimconnNotFoundException("network '{}' not found".format(net_id))
+ else:
+ self._format_vimconn_exception(e)
+ except Exception as e:
+ self._format_vimconn_exception(e)
- def delete_vminstance(self, vm_id):
- resGroup = self._get_resource_group_name_from_resource_id(net_id)
- resName = self._get_resource_name_from_resource_id(net_id)
-
+ def delete_vminstance(self, vm_id, created_items=None):
+ """ Deletes a vm instance from the vim.
+ """
+ self.logger.debug('deleting VM instance {} - {}'.format(self.resource_group, vm_id))
self._reload_connection()
- self.conn_compute.virtual_machines.delete(resGroup, resName)
+
+ try:
+
+ res_name = self._get_resource_name_from_resource_id(vm_id)
+ vm = self.conn_compute.virtual_machines.get(self.resource_group, res_name)
+
+ # Shuts down the virtual machine and releases the compute resources
+ # vm_stop = self.conn_compute.virtual_machines.power_off(self.resource_group, resName)
+ # vm_stop.wait()
+
+ vm_delete = self.conn_compute.virtual_machines.delete(self.resource_group, res_name)
+ vm_delete.wait()
+ self.logger.debug('deleted VM name: %s', res_name)
+
+ # Delete OS Disk
+ os_disk_name = vm.storage_profile.os_disk.name
+ self.logger.debug('delete OS DISK: %s', os_disk_name)
+ self.conn_compute.disks.delete(self.resource_group, os_disk_name)
+ self.logger.debug('deleted OS DISK name: %s', os_disk_name)
+
+ for data_disk in vm.storage_profile.data_disks:
+ self.logger.debug('delete data_disk: %s', data_disk.name)
+ self.conn_compute.disks.delete(self.resource_group, data_disk.name)
+ self.logger.debug('deleted OS DISK name: %s', data_disk.name)
+
+ # After deleting VM, it is necessary to delete NIC, because if is not deleted delete_network
+ # does not work because Azure says that is in use the subnet
+ network_interfaces = vm.network_profile.network_interfaces
+
+ for network_interface in network_interfaces:
+
+ nic_name = self._get_resource_name_from_resource_id(network_interface.id)
+ nic_data = self.conn_vnet.network_interfaces.get(
+ self.resource_group,
+ nic_name)
+
+ public_ip_name = None
+ exist_public_ip = nic_data.ip_configurations[0].public_ip_address
+ if exist_public_ip:
+ public_ip_id = nic_data.ip_configurations[0].public_ip_address.id
+
+ # Delete public_ip
+ public_ip_name = self._get_resource_name_from_resource_id(public_ip_id)
+
+ # Public ip must be deleted afterwards of nic that is attached
+
+ self.logger.debug('delete NIC name: %s', nic_name)
+ nic_delete = self.conn_vnet.network_interfaces.delete(self.resource_group, nic_name)
+ nic_delete.wait()
+ self.logger.debug('deleted NIC name: %s', nic_name)
+
+ # Delete list of public ips
+ if public_ip_name:
+ self.logger.debug('delete PUBLIC IP - ' + public_ip_name)
+ self.conn_vnet.public_ip_addresses.delete(self.resource_group, public_ip_name)
+
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ raise vimconn.vimconnNotFoundException("No vm instance found '{}'".format(vm_id))
+ else:
+ self._format_vimconn_exception(e)
+ except Exception as e:
+ self._format_vimconn_exception(e)
+
+ def action_vminstance(self, vm_id, action_dict, created_items={}):
+ """Send and action over a VM instance from VIM
+ Returns the vm_id if the action was successfully sent to the VIM
+ """
+
+ self.logger.debug("Action over VM '%s': %s", vm_id, str(action_dict))
+ try:
+ self._reload_connection()
+ resName = self._get_resource_name_from_resource_id(vm_id)
+ if "start" in action_dict:
+ self.conn_compute.virtual_machines.start(self.resource_group, resName)
+ elif "stop" in action_dict or "shutdown" in action_dict or "shutoff" in action_dict:
+ self.conn_compute.virtual_machines.power_off(self.resource_group, resName)
+ elif "terminate" in action_dict:
+ self.conn_compute.virtual_machines.delete(self.resource_group, resName)
+ elif "reboot" in action_dict:
+ self.conn_compute.virtual_machines.restart(self.resource_group, resName)
+ return None
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ raise vimconn.vimconnNotFoundException("No vm found '{}'".format(vm_id))
+ else:
+ self._format_vimconn_exception(e)
+ except Exception as e:
+ self._format_vimconn_exception(e)
+
+ def delete_flavor(self, flavor_id):
+ raise vimconn.vimconnAuthException("It is not possible to delete a FLAVOR in AZURE")
+
+ def delete_tenant(self, tenant_id,):
+ raise vimconn.vimconnAuthException("It is not possible to delete a TENANT in AZURE")
+
+ def delete_image(self, image_id):
+ raise vimconn.vimconnAuthException("It is not possible to delete a IMAGE in AZURE")
def get_vminstance(self, vm_id):
- resGroup = self._get_resource_group_name_from_resource_id(net_id)
- resName = self._get_resource_name_from_resource_id(net_id)
-
+ """
+ Obtaing the vm instance data from v_id
+ """
+ self.logger.debug("get vm instance: %s", vm_id)
self._reload_connection()
- vm=self.conn_compute.virtual_machines.get(resGroup, resName)
+ try:
+ resName = self._get_resource_name_from_resource_id(vm_id)
+ vm = self.conn_compute.virtual_machines.get(self.resource_group, resName)
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ raise vimconn.vimconnNotFoundException("No vminstance found '{}'".format(vm_id))
+ else:
+ self._format_vimconn_exception(e)
+ except Exception as e:
+ self._format_vimconn_exception(e)
return vm
def get_flavor(self, flavor_id):
+ """
+ Obtains the flavor_data from the flavor_id
+ """
self._reload_connection()
- for vm_size in self.conn_compute.virtual_machine_sizes.list(self.region):
- if vm_size.name == flavor_id :
- return vm_size
+ self.logger.debug("get flavor from id: %s", flavor_id)
+ flavor_data = self._get_flavor_id_from_flavor_name(flavor_id)
+ if flavor_data:
+ flavor = {
+ 'id': flavor_id,
+ 'name': flavor_id,
+ 'ram': flavor_data['memoryInMB'],
+ 'vcpus': flavor_data['numberOfCores'],
+ 'disk': flavor_data['resourceDiskSizeInMB']/1024
+ }
+ return flavor
+ else:
+ raise vimconn.vimconnNotFoundException("flavor '{}' not found".format(flavor_id))
+
+ def get_tenant_list(self, filter_dict={}):
+ """ Obtains the list of tenants
+ For the azure connector only the azure tenant will be returned if it is compatible
+ with filter_dict
+ """
+ tenants_azure = [{'name': self.tenant, 'id': self.tenant}]
+ tenant_list = []
+
+ self.logger.debug("get tenant list: %s", filter_dict)
+ for tenant_azure in tenants_azure:
+ if filter_dict:
+ if filter_dict.get("id") and str(tenant_azure.get("id")) != filter_dict["id"]:
+ continue
+ if filter_dict.get("name") and str(tenant_azure.get("name")) != filter_dict["name"]:
+ continue
+
+ tenant_list.append(tenant_azure)
+
+ return tenant_list
+ 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)
+
+ """
+
+ out_nets = {}
+ self._reload_connection()
+
+ self.logger.debug("reload nets status net_list: %s", net_list)
+ for net_id in net_list:
+ try:
+ netName = self._get_net_name_from_resource_id(net_id)
+ resName = self._get_resource_name_from_resource_id(net_id)
+
+ net = self.conn_vnet.subnets.get(self.resource_group, netName, resName)
+
+ out_nets[net_id] = {
+ "status": self.provision_state2osm[net.provisioning_state],
+ "vim_info": str(net)
+ }
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ self.logger.info("Not found subnet net_name: %s, subnet_name: %s", netName, resName)
+ out_nets[net_id] = {
+ "status": "DELETED",
+ "error_msg": str(e)
+ }
+ else:
+ self.logger.error("CloudError Exception %s when searching subnet", e)
+ out_nets[net_id] = {
+ "status": "VIM_ERROR",
+ "error_msg": str(e)
+ }
+ except vimconn.vimconnNotFoundException as e:
+ self.logger.error("VimConnNotFoundException %s when searching subnet", e)
+ out_nets[net_id] = {
+ "status": "DELETED",
+ "error_msg": str(e)
+ }
+ except Exception as e:
+ self.logger.error("Exception %s when searching subnet", e, exc_info=True)
+ out_nets[net_id] = {
+ "status": "VIM_ERROR",
+ "error_msg": str(e)
+ }
+ return out_nets
+
+ def refresh_vms_status(self, vm_list):
+ """ Get the status of the virtual machines and their interfaces/ports
+ Params: the list of VM identifiers
+ Returns a dictionary with:
+ vm_id: # VIM id of this Virtual Machine
+ 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, PAUSED, SUSPENDED, INACTIVE (not running),
+ # BUILD (on building process), ERROR
+ # ACTIVE:NoMgmtIP (Active but none of its interfaces has an IP address
+ # (ACTIVE:NoMgmtIP is not returned for Azure)
+ #
+ 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)
+ interfaces: list with interface info. Each item a dictionary with:
+ vim_interface_id - The ID of the interface
+ mac_address - The MAC address of the interface.
+ ip_address - The IP address of the interface within the subnet.
+ """
+
+ out_vms = {}
+ self._reload_connection()
+
+ self.logger.debug("refresh vm status vm_list: %s", vm_list)
+ search_vm_list = vm_list or {}
+
+ for vm_id in search_vm_list:
+ out_vm = {}
+ try:
+ res_name = self._get_resource_name_from_resource_id(vm_id)
+
+ vm = self.conn_compute.virtual_machines.get(self.resource_group, res_name)
+ out_vm['vim_info'] = str(vm)
+ out_vm['status'] = self.provision_state2osm.get(vm.provisioning_state, 'OTHER')
+ if vm.provisioning_state == 'Succeeded':
+ # check if machine is running or stopped
+ instance_view = self.conn_compute.virtual_machines.instance_view(self.resource_group,
+ res_name)
+ for status in instance_view.statuses:
+ splitted_status = status.code.split("/")
+ if len(splitted_status) == 2 and splitted_status[0] == 'PowerState':
+ out_vm['status'] = self.power_state2osm.get(splitted_status[1], 'OTHER')
+
+ network_interfaces = vm.network_profile.network_interfaces
+ out_vm['interfaces'] = self._get_vm_interfaces_status(vm_id, network_interfaces)
+
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ self.logger.debug("Not found vm id: %s", vm_id)
+ out_vm['status'] = "DELETED"
+ out_vm['error_msg'] = str(e)
+ out_vm['vim_info'] = None
+ else:
+ # maybe connection error or another type of error, return vim error
+ self.logger.error("Exception %s refreshing vm_status", e)
+ out_vm['status'] = "VIM_ERROR"
+ out_vm['error_msg'] = str(e)
+ out_vm['vim_info'] = None
+ except Exception as e:
+ self.logger.error("Exception %s refreshing vm_status", e, exc_info=True)
+ out_vm['status'] = "VIM_ERROR"
+ out_vm['error_msg'] = str(e)
+ out_vm['vim_info'] = None
+
+ out_vms[vm_id] = out_vm
+
+ return out_vms
+
+ def _get_vm_interfaces_status(self, vm_id, interfaces):
+ """
+ Gets the interfaces detail for a vm
+ :param interfaces: List of interfaces.
+ :return: Dictionary with list of interfaces including, vim_interface_id, mac_address and ip_address
+ """
+ try:
+ interface_list = []
+ for network_interface in interfaces:
+ interface_dict = {}
+ nic_name = self._get_resource_name_from_resource_id(network_interface.id)
+ interface_dict['vim_interface_id'] = network_interface.id
+
+ nic_data = self.conn_vnet.network_interfaces.get(
+ self.resource_group,
+ nic_name)
+
+ ips = []
+ if nic_data.ip_configurations[0].public_ip_address:
+ self.logger.debug("Obtain public ip address")
+ public_ip_name = self._get_resource_name_from_resource_id(
+ nic_data.ip_configurations[0].public_ip_address.id)
+ public_ip = self.conn_vnet.public_ip_addresses.get(self.resource_group, public_ip_name)
+ self.logger.debug("Public ip address is: %s", public_ip.ip_address)
+ ips.append(public_ip.ip_address)
+
+ private_ip = nic_data.ip_configurations[0].private_ip_address
+ ips.append(private_ip)
+
+ interface_dict['mac_address'] = nic_data.mac_address
+ interface_dict['ip_address'] = ";".join(ips)
+ interface_list.append(interface_dict)
+
+ return interface_list
+ except Exception as e:
+ self.logger.error("Exception %s obtaining interface data for vm: %s, error: %s", vm_id, e, exc_info=True)
+ self._format_vimconn_exception(e)
-# TODO refresh_nets_status ver estado activo
-# TODO refresh_vms_status ver estado activo
-# TODO get_vminstance_console for getting console
if __name__ == "__main__":
# Making some basic test
- vim_id='azure'
- vim_name='azure'
+ vim_id = 'azure'
+ vim_name = 'azure'
needed_test_params = {
"client_id": "AZURE_CLIENT_ID",
"secret": "AZURE_SECRET",
test_params[param] = value
config = {
- 'region_name': getenv("AZURE_REGION_NAME", 'westeurope'),
- 'resource_group': getenv("AZURE_RESOURCE_GROUP"),
- 'subscription_id': getenv("AZURE_SUBSCRIPTION_ID"),
- 'pub_key': getenv("AZURE_PUB_KEY", None),
- 'vnet_name': getenv("AZURE_VNET_NAME", 'myNetwork'),
+ 'region_name': getenv("AZURE_REGION_NAME", 'westeurope'),
+ 'resource_group': getenv("AZURE_RESOURCE_GROUP"),
+ 'subscription_id': getenv("AZURE_SUBSCRIPTION_ID"),
+ 'pub_key': getenv("AZURE_PUB_KEY", None),
+ 'vnet_name': getenv("AZURE_VNET_NAME", 'myNetwork'),
}
virtualMachine = {
vnet_config = {
'subnet_address': '10.1.2.0/24',
- #'subnet_name': 'subnet-oam'
+ # 'subnet_name': 'subnet-oam'
}
###########################
# azure.new_vminstance(virtualMachine['name'], virtualMachine['description'], virtualMachine['status'],
# virtualMachine['image'], virtualMachine['hardware_profile']['vm_size'], subnets)
- azure.get_flavor("Standard_A11")
+ azure.new_network("mynet", None)
+ net_id = "/subscriptions/82f80cc1-876b-4591-9911-1fb5788384fd/resourceGroups/osmRG/providers/Microsoft."\
+ "Network/virtualNetworks/test"
+ net_id_not_found = "/subscriptions/82f80cc1-876b-4591-9911-1fb5788384fd/resourceGroups/osmRG/providers/"\
+ "Microsoft.Network/virtualNetworks/testALF"
+ azure.refresh_nets_status([net_id, net_id_not_found])
requests
netaddr
azure
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
except Exception as e:
raise vimconn.vimconnConnectionException("VIM not reachable. Error {}".format(e))
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
Returns the network identifier on success or raises and exception on failure
"""
self.logger.debug('new_network: {}'.format(locals()))
except Exception as e:
raise vimconn.vimconnException("Unable to create network {}. Error {}".format(net_name, e))
# No way from the current rest service to get the actual error, most likely it will be an already existing error
- return net_uuid
+ return net_uuid,{}
def get_network_list(self, filter_dict={}):
"""Obtain tenant networks of VIM
raise vimconn.vimconnNotFoundException("Network {} not found at VIM".format(net_id))
return res[0]
- def delete_network(self, net_id):
+ def delete_network(self, net_id, created_items=None):
"""Deletes a tenant network from VIM
Returns the network identifier or raises an exception upon error or when network is not found
"""
requests
netaddr
fog05rest>=0.0.4
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
</methodCall>'.format(self.user, self.passwd, (str(id_user)), (str(id_group)))
requests.post(self.url, params)
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None): # , **vim_specific):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None): # , **vim_specific):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
+ 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
# oca library method cannot be used in this case (problem with cluster parameters)
try:
+ vlan = None
+ if provider_network_profile:
+ vlan = provider_network_profile.get("segmentation-id")
created_items = {}
one = self._new_one_connection()
size = "254"
untangle
pyone
git+https://github.com/python-oca/python-oca#egg=oca
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
except (ksExceptions.ConnectionError, ksExceptions.ClientException, ksExceptions.NotFound, ConnectionError) as e:
self._format_exception(e)
- def new_network(self,net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self,net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
+ 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
"""
self.logger.debug("Adding a new network to VIM name '%s', type '%s'", net_name, net_type)
# self.logger.debug(">>>>>>>>>>>>>>>>>> IP profile %s", str(ip_profile))
+
try:
+ vlan = None
+ if provider_network_profile:
+ vlan = provider_network_profile.get("segmentation-id")
new_net = None
created_items = {}
self._reload_connection()
#TODO py3 python-keystoneclient
#TODO py3 python-glanceclient
#TODO py3 python-cinderclient
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
except requests.exceptions.RequestException as e:
self._format_request_exception(e)
- def new_network(self,net_name, net_type, ip_profile=None, shared=False, vlan=None): #, **vim_specific):
+ def new_network(self,net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None): #, **vim_specific):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
+ 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
as not present.
"""
try:
+ vlan = None
+ if provider_network_profile:
+ vlan = provider_network_profile.get("segmentation-id")
created_items = {}
self._get_my_tenant()
if net_type=="bridge":
PyYAML
requests
netaddr
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
# -*- coding: utf-8 -*-
##
-# Copyright 2016-2017 VMware Inc.
+# Copyright 2016-2019 VMware Inc.
# This file is part of ETSI OSM
# All Rights Reserved.
#
return vdclist
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
+ 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
as not present.
"""
- self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {}"
- .format(net_name, net_type, ip_profile, shared))
+ self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {} provider_network_profile {}"
+ .format(net_name, net_type, ip_profile, shared, provider_network_profile))
+ vlan = None
+ if provider_network_profile:
+ vlan = provider_network_profile.get("segmentation-id")
created_items = {}
isshared = 'false'
# if self.config.get('dv_switch_name') == None:
# raise vimconn.vimconnConflictException("You must provide 'dv_switch_name' at config value")
# network_uuid = self.create_dvPort_group(net_name)
+ parent_network_uuid = None
+
+ import traceback
+ traceback.print_stack()
+
+ if provider_network_profile is not None:
+ for k, v in provider_network_profile.items():
+ if k == 'physical_network':
+ parent_network_uuid = self.get_physical_network_by_name(v)
network_uuid = self.create_network(network_name=net_name, net_type=net_type,
- ip_profile=ip_profile, isshared=isshared)
+ ip_profile=ip_profile, isshared=isshared,
+ parent_network_uuid=parent_network_uuid)
if network_uuid is not None:
return network_uuid, created_items
else:
The return network uuid.
network_uuid: network_id
"""
-
if not network_name:
self.logger.debug("get_network_id_by_name() : Network name is empty")
return None
return None
+ def get_physical_network_by_name(self, physical_network_name):
+ '''
+ Methos returns uuid of physical network which passed
+ Args:
+ physical_network_name: physical network name
+ Returns:
+ UUID of physical_network_name
+ '''
+ try:
+ client_as_admin = self.connect_as_admin()
+ if not client_as_admin:
+ raise vimconn.vimconnConnectionException("Failed to connect vCD.")
+ url_list = [self.url, '/api/admin/vdc/', self.tenant_id]
+ vm_list_rest_call = ''.join(url_list)
+
+ if client_as_admin._session:
+ headers = {'Accept':'application/*+xml;version=' + API_VERSION,
+ 'x-vcloud-authorization': client_as_admin._session.headers['x-vcloud-authorization']}
+
+ response = self.perform_request(req_type='GET',
+ url=vm_list_rest_call,
+ headers=headers)
+
+ provider_network = None
+ available_network = None
+ add_vdc_rest_url = None
+
+ if response.status_code != requests.codes.ok:
+ self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
+ response.status_code))
+ return None
+ else:
+ try:
+ vm_list_xmlroot = XmlElementTree.fromstring(response.content)
+ for child in vm_list_xmlroot:
+
+ if child.tag.split("}")[1] == 'ProviderVdcReference':
+ provider_network = child.attrib.get('href')
+ # application/vnd.vmware.admin.providervdc+xml
+ if child.tag.split("}")[1] == 'Link':
+ if child.attrib.get('type') == 'application/vnd.vmware.vcloud.orgVdcNetwork+xml' \
+ and child.attrib.get('rel') == 'add':
+ add_vdc_rest_url = child.attrib.get('href')
+ except:
+ self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
+ self.logger.debug("Respond body {}".format(response.content))
+ return None
+
+ # find pvdc provided available network
+ response = self.perform_request(req_type='GET',
+ url=provider_network,
+ headers=headers)
+
+ if response.status_code != requests.codes.ok:
+ self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
+ response.status_code))
+ return None
+
+ try:
+ vm_list_xmlroot = XmlElementTree.fromstring(response.content)
+ for child in vm_list_xmlroot.iter():
+ if child.tag.split("}")[1] == 'AvailableNetworks':
+ for networks in child.iter():
+ if networks.attrib.get('href') is not None and networks.attrib.get('name') is not None:
+ if networks.attrib.get('name') == physical_network_name:
+ network_url = networks.attrib.get('href')
+ available_network = network_url[network_url.rindex('/')+1:]
+ break
+ except Exception as e:
+ return None
+
+ return available_network
+ except Exception as e:
+ self.logger.error("Error while getting physical network: {}".format(e))
+
def list_org_action(self):
"""
Method leverages vCloud director and query for available organization for particular user
try:
vm_list_xmlroot = XmlElementTree.fromstring(response.content)
for child in vm_list_xmlroot:
+
if child.tag.split("}")[1] == 'ProviderVdcReference':
provider_network = child.attrib.get('href')
# application/vnd.vmware.admin.providervdc+xml
response = self.perform_request(req_type='GET',
url=provider_network,
headers=headers)
+
if response.status_code != requests.codes.ok:
self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
response.status_code))
dns2_text = ""
if len(dns_list) >= 2:
dns2_text = "\n <Dns2>{}</Dns2>\n".format(dns_list[1])
- data = """ <OrgVdcNetwork name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5">
- <Description>Openmano created</Description>
- <Configuration>
- <IpScopes>
- <IpScope>
- <IsInherited>{1:s}</IsInherited>
- <Gateway>{2:s}</Gateway>
- <Netmask>{3:s}</Netmask>
- <Dns1>{4:s}</Dns1>{5:s}
- <IsEnabled>{6:s}</IsEnabled>
- <IpRanges>
- <IpRange>
- <StartAddress>{7:s}</StartAddress>
- <EndAddress>{8:s}</EndAddress>
- </IpRange>
- </IpRanges>
- </IpScope>
- </IpScopes>
- <FenceMode>{9:s}</FenceMode>
- </Configuration>
- <IsShared>{10:s}</IsShared>
- </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
- subnet_address, dns1, dns2_text, dhcp_enabled,
- dhcp_start_address, dhcp_end_address,
- fence_mode, isshared)
+ if net_type == "isolated":
+ fence_mode="isolated"
+ data = """ <OrgVdcNetwork name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5">
+ <Description>Openmano created</Description>
+ <Configuration>
+ <IpScopes>
+ <IpScope>
+ <IsInherited>{1:s}</IsInherited>
+ <Gateway>{2:s}</Gateway>
+ <Netmask>{3:s}</Netmask>
+ <Dns1>{4:s}</Dns1>{5:s}
+ <IsEnabled>{6:s}</IsEnabled>
+ <IpRanges>
+ <IpRange>
+ <StartAddress>{7:s}</StartAddress>
+ <EndAddress>{8:s}</EndAddress>
+ </IpRange>
+ </IpRanges>
+ </IpScope>
+ </IpScopes>
+ <FenceMode>{9:s}</FenceMode>
+ </Configuration>
+ <IsShared>{10:s}</IsShared>
+ </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
+ subnet_address, dns1, dns2_text, dhcp_enabled,
+ dhcp_start_address, dhcp_end_address,
+ fence_mode, isshared)
+ else:
+ fence_mode = "bridged"
+ data = """ <OrgVdcNetwork name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5">
+ <Description>Openmano created</Description>
+ <Configuration>
+ <IpScopes>
+ <IpScope>
+ <IsInherited>{1:s}</IsInherited>
+ <Gateway>{2:s}</Gateway>
+ <Netmask>{3:s}</Netmask>
+ <Dns1>{4:s}</Dns1>{5:s}
+ <IsEnabled>{6:s}</IsEnabled>
+ <IpRanges>
+ <IpRange>
+ <StartAddress>{7:s}</StartAddress>
+ <EndAddress>{8:s}</EndAddress>
+ </IpRange>
+ </IpRanges>
+ </IpScope>
+ </IpScopes>
+ <ParentNetwork href="{9:s}"/>
+ <FenceMode>{10:s}</FenceMode>
+ </Configuration>
+ <IsShared>{11:s}</IsShared>
+ </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
+ subnet_address, dns1, dns2_text, dhcp_enabled,
+ dhcp_start_address, dhcp_end_address, available_networks,
+ fence_mode, isshared)
headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml'
try:
progressbar
prettytable
# TODO py3 genisoimage
-git+https://osm.etsi.org/gerrit/osm/RO.git@py3#egg=osm-ro&subdirectory=RO
+git+https://osm.etsi.org/gerrit/osm/RO.git#egg=osm-ro&subdirectory=RO
}
function upgrade_to_40(){
echo " Adding instance_wim_net_id, created_at, modified_at at 'instance_interfaces'"
- sql "ALTER TABLE instance_interfaces ADD COLUMN instance_wim_net_id VARCHAR(36) NULL AFTER instance_net_id, "\
- "ADD COLUMN model VARCHAR(12) NULL DEFAULT NULL AFTER type, "\"
+ sql "ALTER TABLE instance_interfaces ADD COLUMN instance_wim_net_id VARCHAR(36) NULL AFTER instance_net_id, " \
+ "ADD COLUMN model VARCHAR(12) NULL DEFAULT NULL AFTER type, " \
"ADD COLUMN created_at DOUBLE NULL DEFAULT NULL AFTER vlan, " \
"ADD COLUMN modified_at DOUBLE NULL DEFAULT NULL AFTER created_at;"
echo " Adding sdn to 'instance_wim_nets'"
" CHANGE COLUMN pop_switch_port device_interface_id VARCHAR(64) NULL AFTER device_id, " \
" CHANGE COLUMN wan_service_endpoint_id service_endpoint_id VARCHAR(256) NOT NULL AFTER device_interface_id, " \
" CHANGE COLUMN wan_service_mapping_info service_mapping_info TEXT NULL AFTER service_endpoint_id, " \
- " ADD COLUMN switch_dpid VARCHAR(64) NULL AFTER wan_service_endpoint_id," \
+ " ADD COLUMN switch_dpid VARCHAR(64) NULL AFTER service_endpoint_id," \
" ADD COLUMN switch_port VARCHAR(64) NULL AFTER switch_dpid;"
echo " remove unique name to 'datacenters'"
sql "ALTER TABLE datacenters DROP INDEX name;"
" CHANGE COLUMN service_endpoint_id wan_service_endpoint_id VARCHAR(256) NOT NULL AFTER pop_switch_port, " \
" CHANGE COLUMN service_mapping_info wan_service_mapping_info TEXT NULL AFTER wan_service_endpoint_id, " \
" DROP COLUMN switch_dpid, DROP COLUMN switch_port;"
- sql "ALTER TABLE wim_port_mappings ADD UNIQUE INDEX unique_datacenter_port_mapping(datacenter_id, pop_switch_dpid,
- pop_switch_port);"
+ sql "ALTER TABLE wim_port_mappings ADD UNIQUE INDEX unique_datacenter_port_mapping(datacenter_id, " \
+ "pop_switch_dpid, pop_switch_port);"
echo " add unique name to 'datacenters'"
sql "ALTER TABLE datacenters ADD UNIQUE INDEX name (name);"
sql "DELETE FROM schema_version WHERE version_int='40';"
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##
-
+
'''
NFVO engine, implementing all the methods for the creation, deletion and management of vnfs, scenarios and instances
'''
if vnfd["mgmt-interface"].get("ip-address"):
mgmt_access["ip-address"] = str(vnfd["mgmt-interface"].get("ip-address"))
- if vnfd["mgmt-interface"].get("cp"):
+ if vnfd["mgmt-interface"].get("cp") and vnfd.get("vdu"):
if vnfd["mgmt-interface"]["cp"] not in cp_name2iface_uuid:
raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. "
"Reference to a non-existing connection-point".format(
elif vld.get("vim-network-name"):
db_sce_net["vim_network_name"] = get_str(vld, "vim-network-name", 255)
+
# table sce_interfaces (vld:vnfd-connection-point-ref)
for iface in vld.get("vnfd-connection-point-ref").values():
+ # Check if there are VDUs in the descriptor
vnf_index = str(iface['member-vnf-index-ref'])
- # check correct parameters
- if vnf_index not in vnf_index2vnf_uuid:
- raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
- "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
- "'nsd':'constituent-vnfd'".format(
- str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"])),
- httperrors.Bad_Request)
-
- existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid', 'i.type as iface_type'),
- FROM="interfaces as i join vms on i.vm_id=vms.uuid",
- WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index],
- 'external_name': get_str(iface, "vnfd-connection-point-ref",
- 255)})
- if not existing_ifaces:
- raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
- "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
- "connection-point name at VNFD '{}'".format(
- str(nsd["id"]), str(vld["id"]), str(iface["vnfd-connection-point-ref"]),
- str(iface.get("vnfd-id-ref"))[:255]),
- httperrors.Bad_Request)
- interface_uuid = existing_ifaces[0]["uuid"]
- if existing_ifaces[0]["iface_type"] == "data":
- db_sce_net["type"] = "data"
- sce_interface_uuid = str(uuid4())
- uuid_list.append(sce_net_uuid)
- iface_ip_address = None
- if iface.get("ip-address"):
- iface_ip_address = str(iface.get("ip-address"))
- db_sce_interface = {
- "uuid": sce_interface_uuid,
- "sce_vnf_id": vnf_index2scevnf_uuid[vnf_index],
- "sce_net_id": sce_net_uuid,
- "interface_id": interface_uuid,
- "ip_address": iface_ip_address,
- }
- db_sce_interfaces.append(db_sce_interface)
- if not db_sce_net["type"]:
- db_sce_net["type"] = "bridge"
+ existing_vdus = mydb.get_rows(SELECT=('vms.uuid'), FROM="vms", WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index]})
+ if existing_vdus:
+ # check correct parameters
+ if vnf_index not in vnf_index2vnf_uuid:
+ raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
+ "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
+ "'nsd':'constituent-vnfd'".format(
+ str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"])),
+ httperrors.Bad_Request)
+
+ existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid', 'i.type as iface_type'),
+ FROM="interfaces as i join vms on i.vm_id=vms.uuid",
+ WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index],
+ 'external_name': get_str(iface, "vnfd-connection-point-ref",
+ 255)})
+ if not existing_ifaces:
+ raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
+ "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
+ "connection-point name at VNFD '{}'".format(
+ str(nsd["id"]), str(vld["id"]), str(iface["vnfd-connection-point-ref"]),
+ str(iface.get("vnfd-id-ref"))[:255]),
+ httperrors.Bad_Request)
+ interface_uuid = existing_ifaces[0]["uuid"]
+ if existing_ifaces[0]["iface_type"] == "data":
+ db_sce_net["type"] = "data"
+ sce_interface_uuid = str(uuid4())
+ uuid_list.append(sce_net_uuid)
+ iface_ip_address = None
+ if iface.get("ip-address"):
+ iface_ip_address = str(iface.get("ip-address"))
+ db_sce_interface = {
+ "uuid": sce_interface_uuid,
+ "sce_vnf_id": vnf_index2scevnf_uuid[vnf_index],
+ "sce_net_id": sce_net_uuid,
+ "interface_id": interface_uuid,
+ "ip_address": iface_ip_address,
+ }
+ db_sce_interfaces.append(db_sce_interface)
+ if not db_sce_net["type"]:
+ db_sce_net["type"] = "bridge"
# table sce_vnffgs (vnffgd)
for vnffg in nsd.get("vnffgd").values():
myNetDict["type"] = myNetType
myNetDict["tenant_id"] = myvim_tenant
myNetIPProfile = sce_net.get('ip_profile', None)
+ myProviderNetwork = sce_net.get('provider_network', None)
#TODO:
#We should use the dictionary as input parameter for new_network
#print myNetDict
if not sce_net["external"]:
- network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile)
+ network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile, provider_network_profile=myProviderNetwork)
#print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id)
sce_net['vim_id'] = network_id
auxNetDict['scenario'][sce_net['uuid']] = network_id
myNetDict["type"] = myNetType
myNetDict["tenant_id"] = myvim_tenant
myNetIPProfile = net.get('ip_profile', None)
+ myProviderNetwork = sce_net.get('provider_network', None)
#print myNetDict
#TODO:
#We should use the dictionary as input parameter for new_network
- network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile)
+ network_id, _ = myvim.new_network(myNetName, myNetType, myNetIPProfile, provider_network_profile=myProviderNetwork)
#print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id)
net['vim_id'] = network_id
if sce_vnf['uuid'] not in auxNetDict:
def create_instance(mydb, tenant_id, instance_dict):
# print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
# logger.debug("Creating instance...")
+
scenario = instance_dict["scenario"]
# find main datacenter
else:
update(scenario_net['ip_profile'], ipprofile_db)
+ if 'provider-network' in net_instance_desc:
+ provider_network_db = net_instance_desc['provider-network']
+ if 'provider-network' not in scenario_net:
+ scenario_net['provider-network'] = provider_network_db
+ else:
+ update(scenario_net['provider-network'], provider_network_db)
+
for vdu_id, vdu_instance_desc in vnf_instance_desc.get("vdus", {}).items():
for scenario_vm in scenario_vnf['vms']:
if vdu_id == scenario_vm['osm_id'] or vdu_id == scenario_vm["name"]:
scenario_net['ip_profile'] = ipprofile_db
else:
update(scenario_net['ip_profile'], ipprofile_db)
+ if 'provider-network' in net_instance_desc:
+ provider_network_db = net_instance_desc['provider-network']
+
+ if 'provider-network' not in scenario_net:
+ scenario_net['provider_network'] = provider_network_db
+ else:
+ update(scenario_net['provider-network'], provider_network_db)
+
for interface in net_instance_desc.get('interfaces', ()):
if 'ip_address' in interface:
for vnf in scenarioDict['vnfs']:
# logger.debug("Creating instance scenario-dict MERGED:\n%s",
# yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
+
# 1. Creating new nets (sce_nets) in the VIM"
number_mgmt_networks = 0
db_instance_nets = []
db_instance_wim_nets = []
for sce_net in scenarioDict['nets']:
+
sce_net_uuid = sce_net.get('uuid', sce_net["name"])
# get involved datacenters where this network need to be created
involved_datacenters = []
task_extra = {}
if create_network:
task_action = "CREATE"
- task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None), wim_account_name)
+ task_extra["params"] = (net_vim_name, net_type, sce_net.get('ip_profile', None), None, sce_net.get('provider_network', None), wim_account_name)
+
if lookfor_network:
task_extra["find"] = (lookfor_filter,)
elif lookfor_network:
action_dict['add_public_key'],
password=password, ro_key=priv_RO_key)
vm_result[ vm['uuid'] ] = {"vim_result": 200,
- "description": "Public key injected",
- "name":vm['name']
+ "description": "Public key injected",
+ "name":vm['name']
}
-
except KeyError:
raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm['uuid']),
httperrors.Internal_Server_Error)
net_public = net.pop("shared", False)
net_ipprofile = net.pop("ip_profile", None)
net_vlan = net.pop("vlan", None)
- content, _ = myvim.new_network(net_name, net_type, net_ipprofile, shared=net_public, vlan=net_vlan) #, **net)
+ net_provider_network_profile = None
+ if net_vlan:
+ net_provider_network_profile = {"segmentation-id": net_vlan}
+ content, _ = myvim.new_network(net_name, net_type, net_ipprofile, shared=net_public, provider_network_profile=net_provider_network_profile) #, **net)
#If the datacenter has a SDN controller defined and the network is of dataplane type, then create the sdn network
if get_sdn_controller_id(mydb, datacenter) != None and (net_type == 'data' or net_type == 'ptp'):
# CREATE
params = task["params"]
action_text = "creating VIM"
- vim_net_id, created_items = self.vim.new_network(*params[0:3])
+
+ vim_net_id, created_items = self.vim.new_network(*params[0:5])
# net_name = params[0]
# net_type = params[1]
# wim_account_name = None
- # if len(params) >= 4:
- # wim_account_name = params[3]
+ # if len(params) >= 6:
+ # wim_account_name = params[5]
# TODO fix at nfvo adding external port
# if wim_account_name and self.vim.config["wim_external_ports"]:
"""
raise vimconnNotImplemented("Should have implemented this")
- def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
+ def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None):
"""Adds a tenant network to VIM
Params:
'net_name': name of the network
'dhcp_start_address': ip_schema, first IP to grant
'dhcp_count': number of IPs to grant.
'shared': if this network can be seen/use by other tenants/organization
- 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
+ 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk}
Returns a tuple with the network identifier and created_items, or raises an exception on error
created_items can be None or a dictionary where this method can include key-values that will be passed to
the method delete_network. Can be used to store created segments, created l2gw connections, etc.
#
##
+# DEBUG WITH PDB
+from os import getenv
+if getenv('OSMRO_PDB_DEBUG'):
+ import sys
+ print(sys.path)
+ import pdb
+ pdb.set_trace()
+
+
"""
Module for testing openmano functionality. It uses openmanoclient.py for invoking openmano
"""
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], self.__class__.test_index,
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
+ logger.debug("Test create tenant")
tenant = test_config["client"].create_tenant(name=self.__class__.tenant_name,
description=self.__class__.tenant_name)
logger.debug("{}".format(tenant))
vca_object = test_config["vim_conn"].connect()
logger.debug("{}".format(vca_object))
self.assertIsNotNone(vca_object)
- elif test_config['vimtype'] == 'openstack':
+ elif test_config['vimtype'] in ('openstack', 'azure'):
test_config["vim_conn"]._reload_connection()
network_list = test_config["vim_conn"].get_network_list()
logger.debug("{}".format(network_list))
self.assertIsNotNone(network_list)
+
class test_vimconn_new_network(test_base):
network_name = None
network, _ = test_config["vim_conn"].new_network(net_name=self.__class__.network_name,
net_type=network_type)
self.__class__.network_id = network
- logger.debug("{}".format(network))
+ logger.debug("Created network {}".format(network))
network_list = test_config["vim_conn"].get_network_list()
+ logger.debug("Network list {}".format(network_list))
for net in network_list:
if self.__class__.network_name in net.get('name'):
self.assertIn(self.__class__.network_name, net.get('name'))
else:
logger.info("Failed to delete network id {}".format(self.__class__.network_id))
+ network_list = test_config["vim_conn"].get_network_list()
+ logger.debug("Network list after deletion {}".format(network_list))
+
def test_010_new_network_by_types(self):
delete_net_ids = []
network_types = ['data','bridge','mgmt']
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
self.__class__.test_index,
inspect.currentframe().f_code.co_name)
+ network_list = test_config["vim_conn"].get_network_list()
+ logger.debug("Network list at start {}".format(network_list))
self.__class__.test_index += 1
for net_type in network_types:
self.__class__.network_name = _get_random_string(20)
logger.info("Network id {} sucessfully deleted".format(net_id))
else:
logger.info("Failed to delete network id {}".format(net_id))
+ network_list = test_config["vim_conn"].get_network_list()
+ logger.debug("Network list after test {}".format(network_list))
def test_020_new_network_by_ipprofile(self):
test_directory_content = os.listdir(test_config["test_directory"])
with open(vnfd, 'r') as stream:
vnf_descriptor = yaml.load(stream, Loader=yaml.Loader)
- internal_connections_list = vnf_descriptor['vnf']['internal-connections']
+ #internal_connections_list = vnf_descriptor['vnf']['internal-connections']
+ internal_connections_list = vnf_descriptor['vnfd-catalog']['vnfd'][0]['ip-profiles']
for item in internal_connections_list:
- if 'ip-profile' in item:
- version = item['ip-profile']['ip-version']
- dhcp_count = item['ip-profile']['dhcp']['count']
- dhcp_enabled = item['ip-profile']['dhcp']['enabled']
- dhcp_start_address = item['ip-profile']['dhcp']['start-address']
- subnet_address = item['ip-profile']['subnet-address']
-
+ version = item['ip-version']
+ dhcp_count = item['dhcp-params']['count']
+ dhcp_enabled = item['dhcp-params']['enabled']
+ dhcp_start_address = item['dhcp-params']['start-address']
+ subnet_address = item['subnet-address']
self.__class__.network_name = _get_random_string(20)
ip_profile = {'dhcp_count': dhcp_count,
logger.debug("{}".format(network))
network_list = test_config["vim_conn"].get_network_list()
+ logger.debug("Created network by ip_profile {}".format(network_list))
for net in network_list:
if self.__class__.network_name in net.get('name'):
self.assertIn(self.__class__.network_name, net.get('name'))
self.__class__.test_index += 1
# refresh net status
+ # if azure network name must have the following format
+ if test_config['vimtype'] == 'azure':
+ unknown_net_id = "/" + "/".join(["subscriptions", test_config["vim_conn"].subscription_id,
+ "resourceGroups", test_config["vim_conn"].resource_group,
+ "providers", "Microsoft.Network",
+ "virtualNetworks", test_config["vim_conn"].vnet_name,
+ "subnets", unknown_net_id])
+ #unknown_net_id = "/subscriptions/ca3d18ab-d373-4afb-a5d6-7c44f098d16a/resourceGroups/osmRG/providers/Microsoft.Network/virtualNetworks/osm_vnet/subnets/unnkown_net"
+
net_dict = test_config["vim_conn"].refresh_nets_status([unknown_net_id])
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
self.assertEqual(net_dict[unknown_net_id]['status'], 'DELETED')
else:
# TODO : Fix vmware connector to return status DELETED as per vimconn.py
self.assertIn(self.__class__.network_name, net.get('name'))
self.assertEqual(net.get('type'), self.__class__.net_type)
self.assertEqual(net.get('status'), 'ACTIVE')
- self.assertEqual(net.get('shared'), False)
+ if test_config['vimtype'] != 'azure':
+ self.assertEqual(net.get('shared'), False)
def test_010_get_network_list_by_name(self):
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
network_name = test_config['vim_conn'].get_network(self.__class__.network_id)['name']
else:
network_name = test_config['vim_conn'].get_network_name_by_id(self.__class__.network_id)
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
network_name = test_config['vim_conn'].get_network(self.__class__.network_id)['name']
else:
network_name = test_config['vim_conn'].get_network_name_by_id(self.__class__.network_id)
self.__class__.test_index += 1
tenant_list = test_config["vim_conn"].get_tenant_list()
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
network_name = test_config['vim_conn'].get_network(self.__class__.network_id)['name']
else:
network_name = test_config['vim_conn'].get_network_name_by_id(self.__class__.network_id)
self.__class__.test_index += 1
status = 'ACTIVE'
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
network_name = test_config['vim_conn'].get_network(self.__class__.network_id)['name']
else:
network_name = test_config['vim_conn'].get_network_name_by_id(self.__class__.network_id)
flavor_id = None
def test_000_new_flavor(self):
- flavor_data = {'name': _get_random_string(20), 'ram': 1024, 'vpcus': 1, 'disk': 10}
+ flavor_data = {'name': _get_random_string(20), 'ram': 1024, 'vcpus': 1, 'disk': 10}
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
self.__class__.test_index,
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- # create new flavor
- self.__class__.flavor_id = test_config["vim_conn"].new_flavor(flavor_data)
- self.assertIsInstance(self.__class__.flavor_id, (str, unicode))
- self.assertIsInstance(uuid.UUID(self.__class__.flavor_id), uuid.UUID)
+ if test_config['vimtype'] == 'azure':
+ with self.assertRaises(Exception) as context:
+ test_config["vim_conn"].new_flavor(flavor_data)
+
+ self.assertEqual((context.exception).http_code, 401)
+ else:
+ # create new flavor
+ self.__class__.flavor_id = test_config["vim_conn"].new_flavor(flavor_data)
+ self.assertIsInstance(self.__class__.flavor_id, (str, unicode))
+ self.assertIsInstance(uuid.UUID(self.__class__.flavor_id), uuid.UUID)
def test_010_delete_flavor(self):
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
self.__class__.test_index += 1
# delete flavor
- result = test_config["vim_conn"].delete_flavor(self.__class__.flavor_id)
- if result:
- logger.info("Flavor id {} sucessfully deleted".format(result))
+ if test_config['vimtype'] == 'azure':
+ with self.assertRaises(Exception) as context:
+ test_config["vim_conn"].delete_flavor(self.__class__.flavor_id)
+
+ self.assertEqual((context.exception).http_code, 401)
else:
- logger.error("Failed to delete flavor id {}".format(result))
- raise Exception ("Failed to delete created flavor")
+ result = test_config["vim_conn"].delete_flavor(self.__class__.flavor_id)
+ if result:
+ logger.info("Flavor id {} sucessfully deleted".format(result))
+ else:
+ logger.error("Failed to delete flavor id {}".format(result))
+ raise Exception ("Failed to delete created flavor")
def test_020_new_flavor_negative(self):
Invalid_flavor_data = {'ram': '1024', 'vcpus': 2.0, 'disk': 2.0}
with self.assertRaises(Exception) as context:
test_config["vim_conn"].new_flavor(Invalid_flavor_data)
-
- self.assertEqual((context.exception).http_code, 400)
+ if test_config['vimtype'] != 'azure':
+ self.assertEqual((context.exception).http_code, 400)
+ else:
+ self.assertEqual((context.exception).http_code, 401)
def test_030_delete_flavor_negative(self):
Non_exist_flavor_id = str(uuid.uuid4())
with self.assertRaises(Exception) as context:
test_config["vim_conn"].delete_flavor(Non_exist_flavor_id)
- self.assertEqual((context.exception).http_code, 404)
+ if test_config['vimtype'] != 'azure':
+ self.assertEqual((context.exception).http_code, 404)
+ else:
+ self.assertEqual((context.exception).http_code, 401)
# class test_vimconn_new_image(test_base):
#
self.__class__.test_index,
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- image_list = test_config["vim_conn"].get_image_list()
- for item in image_list:
- if 'name' in item:
- self.__class__.image_name = item['name']
- self.__class__.image_id = item['id']
- self.assertIsInstance(self.__class__.image_name, (str, unicode))
- self.assertIsInstance(self.__class__.image_id, (str, unicode))
+ if test_config['vimtype'] != 'azure':
+ image_list = test_config["vim_conn"].get_image_list()
+ logger.debug("{}: Result image list: {}".format(self.__class__.test_text, image_list))
+
+ for item in image_list:
+ if 'name' in item:
+ self.__class__.image_name = item['name']
+ self.__class__.image_id = item['id']
+ self.assertIsInstance(self.__class__.image_name, (str, unicode))
+ self.assertIsInstance(self.__class__.image_id, (str, unicode))
+ else:
+ with self.assertRaises(Exception) as context:
+ image_list = test_config["vim_conn"].get_image_list()
+ self.assertEqual((context.exception).http_code, 401)
+ logger.debug(self.__class__.test_text + "Exception unauthorized: " + str(context.exception))
def test_010_get_image_list_by_name(self):
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
self.__class__.test_index,
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
+ self.__class__.image_name = test_config['image_name']
+ logger.debug("{}: Image name: {}".format(self.__class__.test_text, self.__class__.image_name))
image_list = test_config["vim_conn"].get_image_list({'name': self.__class__.image_name})
+ logger.debug("{}: Result image list: {}".format(self.__class__.test_text, image_list))
for item in image_list:
self.assertIsInstance(item['id'], (str, unicode))
self.assertIsInstance(item['name'], (str, unicode))
- self.assertEqual(item['id'], self.__class__.image_id)
+ #self.assertEqual(item['id'], self.__class__.image_id)
self.assertEqual(item['name'], self.__class__.image_name)
def test_020_get_image_list_by_id(self):
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci,
+ 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
- self.__class__.instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=self.__class__.image_id, flavor_id=flavor_id, net_list=net_list)
+ self.__class__.instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='',
+ start=False,
+ image_id=self.__class__.image_id,
+ flavor_id=flavor_id, net_list=net_list)
self.assertIsInstance(self.__class__.instance_id, (str, unicode))
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True, 'model': model_name, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True,
+ 'model': model_name, 'type': 'virtual', 'net_id': self.__class__.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=self.__class__.image_id,flavor_id=flavor_id,net_list=net_list)
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=self.__class__.image_id,
+ flavor_id=flavor_id,net_list=net_list)
self.assertIsInstance(instance_id, (str, unicode))
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': net_use, 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': net_use, 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'virtual',
+ 'net_id': self.__class__.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=self.__class__.image_id,disk_list=None,
- flavor_id=flavor_id,
- net_list=net_list)
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=self.__class__.image_id,disk_list=None,
+ flavor_id=flavor_id, net_list=net_list)
self.assertIsInstance(instance_id, (str, unicode))
# Deleting created vm instance
net_list=net_list)
self.assertEqual(type(instance_id),str)
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
# create network of type data
network_name = _get_random_string(20)
net_type = 'data'
'type': _type, 'net_id': network_id}]
instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
- image_id=self.__class__.image_id, disk_list=None,
- flavor_id=flavor_id,
- net_list=net_list)
+ image_id=self.__class__.image_id, disk_list=None,
+ flavor_id=flavor_id,
+ net_list=net_list)
self.assertEqual(type(instance_id), unicode)
name = 'eth0'
user_name = 'test_user'
- key_pairs = ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy2w9GHMKKNkpCmrDK2ovc3XBYDETuLWwaW24S+feHhLBQiZlzh3gSQoINlA+2ycM9zYbxl4BGzEzpTVyCQFZv5PidG4m6ox7LR+KYkDcITMyjsVuQJKDvt6oZvRt6KbChcCi0n2JJD/oUiJbBFagDBlRslbaFI2mmqmhLlJ5TLDtmYxzBLpjuX4m4tv+pdmQVfg7DYHsoy0hllhjtcDlt1nn05WgWYRTu7mfQTWfVTavu+OjIX3e0WN6NW7yIBWZcE/Q9lC0II3W7PZDE3QaT55se4SPIO2JTdqsx6XGbekdG1n6adlduOI27sOU5m4doiyJ8554yVbuDB/z5lRBD alfonso.tiernosepulveda@telefonica.com']
+ key_pairs = ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtAjl5R+GSKP3gFrdFxgizKEUzhXKQbyjaxJH9thsK 0/fDiYlaNEjvijgPgiVZkfwvqgWeLprPcpzL2j4jvmmSJ3+7C8ihCwObWP0VUiuewmbIINBPAR0RqusjMRyPsa+q0asFBPOoZLx3Cv3vzmC1AA3mKuCNeT EuA0rlWhDIOVwMcU5sP1grnmuexQB8HcR7BdKcA9y08pTwnCQR8vmtW77SRkaxEGXm4Gnw5qw8Z27mHdk2wWS2SnbVH7aFwWvDXc6jjf5TpEWypdr/EAPC +eJipeS2Oa4FsntEqAu3Fz6gp/9ub8uNqgCgHfMzs6FhYpZpipwS0hXYyF6eVsSx osm@osm']
- users_data = [{'key-pairs': ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy2w9GHMKKNkpCmrDK2ovc3XBYDETuLWwaW24S+feHhLBQiZlzh3gSQoINlA+2ycM9zYbxl4BGzEzpTVyCQFZv5PidG4m6ox7LR+KYkDcITMyjsVuQJKDvt6oZvRt6KbChcCi0n2JJD/oUiJbBFagDBlRslbaFI2mmqmhLlJ5TLDtmYxzBLpjuX4m4tv+pdmQVfg7DYHsoy0hllhjtcDlt1nn05WgWYRTu7mfQTWfVTavu+OjIX3e0WN6NW7yIBWZcE/Q9lC0II3W7PZDE3QaT55se4SPIO2JTdqsx6XGbekdG1n6adlduOI27sOU5m4doiyJ8554yVbuDB/z5lRBD alfonso.tiernosepulveda@telefonica.com'], 'name': user_name}]
+ users_data = [{'key-pairs': ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtAjl5R+GSKP3gFrdFxgizKEUzhXKQbyjaxJH9thsK0/fDiYlaNEjvijgPgiVZkfwvqgWeLprPcpzL2j4jvmmSJ3+7C8ihCwObWP0VUiuewmbIINBPAR0RqusjMRyPsa+q0asFBPOoZLx3Cv3vzmC1AA3mKuCNeTEuA0rlWhDIOVwMcU5sP1grnmuexQB8HcR7BdKcA9y08pTwnCQR8vmtW77SRkaxEGXm4Gnw5qw8Z27mHdk2wWS2SnbVH7aFwWvDXc6jjf5TpEWypdr/EAPC+eJipeS2Oa4FsntEqAu3Fz6gp/9ub8uNqgCgHfMzs6FhYpZpipwS0hXYyF6eVsSx osm@osm'], 'name': 'cloudinit'}]
cloud_data = {'config-files': [{'content': 'auto enp0s3\niface enp0s3 inet dhcp\n', 'dest': '/etc/network/interfaces.d/enp0s3.cfg', 'owner': 'root:root', 'permissions': '0644'}, {'content': '#! /bin/bash\nls -al >> /var/log/osm.log\n', 'dest': '/etc/rc.local', 'permissions': '0755'}, {'content': 'file content', 'dest': '/etc/test_delete'}], 'boot-data-drive': True, 'key-pairs': key_pairs, 'users': users_data }
+ #cloud_data = {'users': users_data }
# create new flavor
flavor_id = test_config["vim_conn"].new_flavor(flavor_data)
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True,
+ 'type': 'virtual', 'net_id': self.__class__.network_id}]
instance_id, _ = test_config["vim_conn"].new_vminstance(name='Cloud_vm', description='', start=False,
- image_id=self.__class__.image_id, flavor_id=flavor_id,net_list=net_list,cloud_config=cloud_data)
+ image_id=self.__class__.image_id,
+ flavor_id=flavor_id,net_list=net_list,
+ cloud_config=cloud_data)
self.assertIsInstance(instance_id, (str, unicode))
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True,
+ 'type': 'virtual', 'net_id': self.__class__.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='VM_test1', description='', start=False, image_id=self.__class__.image_id,
- flavor_id=flavor_id,
- net_list=net_list,
- disk_list=device_data)
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='VM_test1', description='', start=False,
+ image_id=self.__class__.image_id,
+ flavor_id=flavor_id, net_list=net_list,
+ disk_list=device_data)
self.assertIsInstance(instance_id, (str, unicode))
# Deleting created vm instance
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'port_security': True,
+ 'type': 'virtual', 'net_id': self.__class__.network_id}]
with self.assertRaises(Exception) as context:
- test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=unknown_image_id,
- flavor_id=unknown_flavor_id,
- net_list=net_list)
+ test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=unknown_image_id,
+ flavor_id=unknown_flavor_id,
+ net_list=net_list)
self.assertIn((context.exception).http_code, (400, 404))
if attr == 'interfaces':
self.assertEqual(type(vm_info[self.__class__.instance_id][attr]), list)
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
vpci = "0000:00:11.0"
name = "eth0"
# create new flavor
flavor_id = test_config["vim_conn"].new_flavor(flavor_data)
# create new vm instance
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci,
+ 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=self.__class__.image_id, flavor_id=flavor_id, net_list=net_list)
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=self.__class__.image_id,
+ flavor_id=flavor_id, net_list=net_list)
time.sleep(30)
vm_list = []
if test_config['vimtype'] == 'vmware':
self.assertEqual(vm_dict,{})
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
self.assertEqual(vm_dict[unknown_id]['status'], 'DELETED')
def test_110_action_vminstance(self):
{action: None})
self.assertEqual(instance_id, self.__class__.instance_id)
- if test_config['vimtype'] == 'openstack':
+ if test_config['vimtype'] in ('openstack', 'azure'):
# create new vm instance
vpci = "0000:00:11.0"
name = "eth0"
# create new flavor
flavor_id = test_config["vim_conn"].new_flavor(flavor_data)
- net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci, 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
+ net_list = [{'use': self.__class__.net_type, 'name': name, 'floating_ip': False, 'vpci': vpci,
+ 'port_security': True, 'type': 'virtual', 'net_id': self.__class__.network_id}]
- new_instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False, image_id=self.__class__.image_id, flavor_id=flavor_id, net_list=net_list)
+ new_instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='',
+ start=False, image_id=self.__class__.image_id,
+ flavor_id=flavor_id, net_list=net_list)
- action_list = ['shutdown','start','shutoff','rebuild','start','pause','start']
+ if test_config['vimtype'] == 'openstack':
+ action_list = ['shutdown','start','shutoff','rebuild','start','pause','start']
+ else:
+ action_list = ['shutdown','start','stop','start','shutoff','start','reboot']
# various action on vminstace
for action in action_list:
self.assertEqual(sriov_net_name, list_item.get('name'))
self.__class__.sriov_network_id = list_item.get('id')
- net_list = [{'use': 'data', 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'VF', 'net_id': self.__class__.sriov_network_id}]
+ net_list = [{'use': 'data', 'name': name, 'floating_ip': False, 'port_security': True, 'type': 'VF',
+ 'net_id': self.__class__.sriov_network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_sriov_vm', description='', start=False, image_id=self.__class__.image_id, flavor_id=flavor_id, net_list=net_list)
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_sriov_vm', description='', start=False,
+ image_id=self.__class__.image_id, flavor_id=flavor_id,
+ net_list=net_list)
self.assertIsInstance(instance_id, (str, unicode))
# Getting tenant list
tenant_list = test_config["vim_conn"].get_tenant_list()
+ logger.debug(self.__class__.test_text + "Tenant list: " + str(tenant_list))
for item in tenant_list:
if test_config['tenant'] == item['name']:
# Getting filter tenant list by its id
filter_tenant_list = test_config["vim_conn"].get_tenant_list({'id': self.__class__.tenant_id})
+ logger.debug(self.__class__.test_text + "Tenant list: " + str(filter_tenant_list))
for item in filter_tenant_list:
self.assertIsInstance(item['id'], (str, unicode))
# Getting filter tenant list by its name
filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': test_config['tenant']})
+ logger.debug(self.__class__.test_text + "Tenant list: " + str(filter_tenant_list))
for item in filter_tenant_list:
self.assertIsInstance(item['name'], (str, unicode))
# Getting filter tenant list by its name and id
filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': test_config['tenant'],
'id': self.__class__.tenant_id})
+ logger.debug(self.__class__.test_text + "Tenant list: " + str(filter_tenant_list))
for item in filter_tenant_list:
self.assertIsInstance(item['name'], (str, unicode))
filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': non_exist_tenant_name,
'id': non_exist_tenant_id})
+ logger.debug(self.__class__.test_text + "Tenant list: " + str(filter_tenant_list))
self.assertEqual(filter_tenant_list, [])
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- self.__class__.tenant_id = test_config["vim_conn"].new_tenant(tenant_name, "")
- time.sleep(15)
+ if test_config['vimtype'] != 'azure':
+ self.__class__.tenant_id = test_config["vim_conn"].new_tenant(tenant_name, "")
+ time.sleep(15)
- self.assertIsInstance(self.__class__.tenant_id, (str, unicode))
+ self.assertIsInstance(self.__class__.tenant_id, (str, unicode))
+ else:
+ with self.assertRaises(Exception) as context:
+ test_config["vim_conn"].new_tenant(self.__class__.tenant_id, "")
+ self.assertEqual((context.exception).http_code, 401)
+ logger.debug(self.__class__.test_text + "Exception unauthorized: " + str(context.exception))
def test_010_new_tenant_negative(self):
with self.assertRaises(Exception) as context:
test_config["vim_conn"].new_tenant(Invalid_tenant_name, "")
- self.assertEqual((context.exception).http_code, 400)
+ if test_config['vimtype'] != 'azure':
+ self.assertEqual((context.exception).http_code, 400)
+ else:
+ self.assertEqual((context.exception).http_code, 401)
+ logger.debug(self.__class__.test_text + "Exception unauthorized: " + str(context.exception))
def test_020_delete_tenant(self):
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
- tenant_id = test_config["vim_conn"].delete_tenant(self.__class__.tenant_id)
-
- self.assertIsInstance(tenant_id, (str, unicode))
+ if test_config['vimtype'] != 'azure':
+ tenant_id = test_config["vim_conn"].delete_tenant(self.__class__.tenant_id)
+ self.assertIsInstance(tenant_id, (str, unicode))
+ else:
+ with self.assertRaises(Exception) as context:
+ test_config["vim_conn"].delete_tenant(self.__class__.tenant_id)
+ self.assertEqual((context.exception).http_code, 401)
+ logger.debug(self.__class__.test_text + "Exception unauthorized: " + str(context.exception))
def test_030_delete_tenant_negative(self):
- Non_exist_tenant_name = 'Test_30_tenant'
+ non_exist_tenant_name = 'Test_30_tenant'
self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"],
self.__class__.test_index,
inspect.currentframe().f_code.co_name)
self.__class__.test_index += 1
with self.assertRaises(Exception) as context:
- test_config["vim_conn"].delete_tenant(Non_exist_tenant_name)
+ test_config["vim_conn"].delete_tenant(non_exist_tenant_name)
- self.assertEqual((context.exception).http_code, 404)
+ if test_config['vimtype'] != 'azure':
+ self.assertEqual((context.exception).http_code, 404)
+ else:
+ self.assertEqual((context.exception).http_code, 401)
+ logger.debug(self.__class__.test_text + "Exception unauthorized: " + str(context.exception))
def get_image_id():
net_list = [{'use': 'bridge', 'name': name, 'floating_ip': False, 'port_security': True,
'type': 'virtual', 'net_id': self.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', image_id=image_id,
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=image_id,
flavor_id=flavor_id, net_list=net_list,disk_list=disk_list)
self.assertEqual(type(instance_id),str)
net_list = [{'use': 'bridge', 'name': name, 'floating_ip': False, 'port_security': True,
'type': 'virtual', 'net_id': self.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', image_id=image_id,
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=image_id,
flavor_id=flavor_id, net_list=net_list,disk_list=disk_list)
self.assertEqual(type(instance_id),str)
net_list = [{'use': 'bridge', 'name': name, 'floating_ip': False, 'port_security': True,
'type': 'virtual', 'net_id': self.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', image_id=image_id,
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=image_id,
flavor_id=flavor_id, net_list=net_list,disk_list=disk_list )
self.assertEqual(type(instance_id),str)
net_list = [{'use': 'bridge', 'name': name, 'floating_ip': False, 'port_security': True,
'type': 'virtual', 'net_id': self.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', image_id=image_id,
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=image_id,
flavor_id=flavor_id, net_list=net_list,availability_zone_index=1,
availability_zone_list=['HG_174','HG_175'])
def test_000_vminstance_by_numa_affinity(self):
flavor_data = {'extended': {'numas': [{'paired-threads-id': [['1', '3'], ['2', '4']],
- ' paired-threads': 2, 'memory': 1}]},
- 'ram': 1024, 'vcpus': 1, 'disk': 10}
+ ' paired-threads': 2, 'memory': 1}]},
+ 'ram': 1024, 'vcpus': 1, 'disk': 10}
name = "eth10"
# create new flavor
net_list = [{'use': 'bridge', 'name': name, 'floating_ip': False, 'port_security': True,
'type': 'virtual', 'net_id': self.network_id}]
- instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', image_id=image_id,
+ instance_id, _ = test_config["vim_conn"].new_vminstance(name='Test1_vm', description='', start=False,
+ image_id=image_id,
flavor_id=flavor_id, net_list=net_list)
self.assertEqual(type(instance_id),str)
test_config['sriov_net_name'] = args.sriov_net_name
# vmware connector obj
- test_config['vim_conn'] = vim.vimconnector(name=org_name, tenant_name=tenant_name, user=org_user,passwd=org_passwd, url=vim_url, config=config_params)
+ test_config['vim_conn'] = vim.vimconnector(name=org_name, tenant_name=tenant_name, user=org_user,
+ passwd=org_passwd, url=vim_url, config=config_params)
elif args.vimtype == "aws":
import vimconn_aws as vim
elif args.vimtype == "openvim":
import vimconn_openvim as vim
+ elif args.vimtype == "azure":
+ import vimconn_azure as vim
+
+ test_config["test_directory"] = os.path.dirname(__file__) + "/RO_tests"
+
+ tenant_name = args.tenant_name
+ test_config['tenant'] = tenant_name
+ config_params = yaml.load(args.config_param)
+ os_user = config_params.get('user')
+ os_passwd = config_params.get('passwd')
+ vim_url = args.endpoint_url
+ test_config['image_path'] = args.image_path
+ test_config['image_name'] = args.image_name
+ #test_config['sriov_net_name'] = args.sriov_net_name
+ args_log_level = "DEBUG" if args.debug else "INFO"
+
+ # azure connector obj
+ vim_persistent_info = {}
+ test_config['vim_conn'] = vim.vimconnector(
+ uuid="test-uuid-1", name="VIO-azure",
+ tenant_id=None, tenant_name=tenant_name,
+ url=vim_url, url_admin=None,
+ user=os_user, passwd=os_passwd, log_level= args_log_level,
+ config=config_params, persistent_info=vim_persistent_info
+ )
+ test_config['vim_conn'].debug = "true"
+
else:
logger.critical("vimtype '{}' not supported".format(args.vimtype))
sys.exit(1)
vimconn_parser.set_defaults(func=test_vimconnector)
# Mandatory arguments
mandatory_arguments = vimconn_parser.add_argument_group('mandatory arguments')
- mandatory_arguments.add_argument('--vimtype', choices=['vmware', 'aws', 'openstack', 'openvim'], required=True,
+ mandatory_arguments.add_argument('--vimtype', choices=['vmware', 'aws', 'openstack', 'openvim','azure'], required=True,
help='Set the vimconnector type to test')
mandatory_arguments.add_argument('-c', '--config', dest='config_param', required=True,
help='Set the vimconnector specific config parameters in dictionary format')
# clean
docker rm -f ro_pkg 2>/dev/null && echo docker ro_pkg removed
rm -rf $HERE/temp/*
+find $RO_BASE -name "*.pyc" -exec rm {} ";"
mkdir -p $HERE/temp
echo -e "\n\n[STAGE 1] Builind dockerfile userd for the package generation"