summaryrefslogtreecommitdiffstats
path: root/sdnvpn/lib
diff options
context:
space:
mode:
Diffstat (limited to 'sdnvpn/lib')
-rw-r--r--sdnvpn/lib/openstack_utils.py82
-rw-r--r--sdnvpn/lib/utils.py117
2 files changed, 163 insertions, 36 deletions
diff --git a/sdnvpn/lib/openstack_utils.py b/sdnvpn/lib/openstack_utils.py
index f0b9ba7..d377c33 100644
--- a/sdnvpn/lib/openstack_utils.py
+++ b/sdnvpn/lib/openstack_utils.py
@@ -18,19 +18,17 @@ import urllib
from keystoneauth1 import loading
from keystoneauth1 import session
-from cinderclient import client as cinderclient
-from heatclient import client as heatclient
from keystoneclient import client as keystoneclient
from neutronclient.neutron import client as neutronclient
from openstack import connection
from openstack import cloud as os_cloud
+from openstack.exceptions import ResourceNotFound
from functest.utils import env
logger = logging.getLogger(__name__)
DEFAULT_API_VERSION = '2'
-DEFAULT_HEAT_API_VERSION = '1'
# *********************************************
@@ -165,20 +163,6 @@ def get_keystone_client(other_creds={}):
interface=os.getenv('OS_INTERFACE', 'admin'))
-def get_cinder_client_version():
- api_version = os.getenv('OS_VOLUME_API_VERSION')
- if api_version is not None:
- logger.info("OS_VOLUME_API_VERSION is set in env as '%s'",
- api_version)
- return api_version
- return DEFAULT_API_VERSION
-
-
-def get_cinder_client(other_creds={}):
- sess = get_session(other_creds)
- return cinderclient.Client(get_cinder_client_version(), session=sess)
-
-
def get_neutron_client_version():
api_version = os.getenv('OS_NETWORK_API_VERSION')
if api_version is not None:
@@ -193,20 +177,6 @@ def get_neutron_client(other_creds={}):
return neutronclient.Client(get_neutron_client_version(), session=sess)
-def get_heat_client_version():
- api_version = os.getenv('OS_ORCHESTRATION_API_VERSION')
- if api_version is not None:
- logger.info("OS_ORCHESTRATION_API_VERSION is set in env as '%s'",
- api_version)
- return api_version
- return DEFAULT_HEAT_API_VERSION
-
-
-def get_heat_client(other_creds={}):
- sess = get_session(other_creds)
- return heatclient.Client(get_heat_client_version(), session=sess)
-
-
def download_url(url, dest_path):
"""
Download a file to a destination path given a URL
@@ -1434,10 +1404,52 @@ def delete_user(keystone_client, user_id):
# *********************************************
# HEAT
# *********************************************
-def get_resource(heat_client, stack_id, resource):
+def get_resource(conn, stack_id, resource):
try:
- resources = heat_client.resources.get(stack_id, resource)
- return resources
+ resource = conn.orchestration.resources(stack_id, id=resource).next()
+ return resource
except Exception as e:
- logger.error("Error [get_resource]: %s" % e)
+ logger.error("Error [get_resource(orchestration)]: %s" % e)
return None
+
+
+def create_stack(conn, **kwargs):
+ try:
+ stack = conn.orchestration.create_stack(**kwargs)
+ stack_id = stack.id
+ if stack_id is None:
+ logger.error("Stack create start failed")
+ raise SystemError("Stack create start failed")
+ return stack_id
+ except Exception as e:
+ logger.error("Error [create_stack(orchestration)]: %s" % e)
+ return None
+
+
+def delete_stack(conn, stack_id):
+ try:
+ conn.orchestration.delete_stack(stack_id)
+ return True
+ except Exception as e:
+ logger.error("Error [delete_stack(orchestration)]: %s" % e)
+ return False
+
+
+def list_stacks(conn, **kwargs):
+ try:
+ result = conn.orchestration.stacks(**kwargs)
+ return result
+ except Exception as e:
+ logger.error("Error [list_stack(orchestration)]: %s" % e)
+ return None
+
+
+def get_output(conn, stack_id, output_key):
+ try:
+ stack = conn.orchestration.get_stack(stack_id)
+ for output in stack.outputs:
+ if output['output_key'] == output_key:
+ return output
+ except ResourceNotFound as e:
+ logger.error("Error [get_output(orchestration)]: %s" % e)
+ return None
diff --git a/sdnvpn/lib/utils.py b/sdnvpn/lib/utils.py
index 9a5e181..a4bb959 100644
--- a/sdnvpn/lib/utils.py
+++ b/sdnvpn/lib/utils.py
@@ -15,7 +15,7 @@ import requests
import re
import subprocess
from concurrent.futures import ThreadPoolExecutor
-from openstack.exceptions import ResourceNotFound
+from openstack.exceptions import ResourceNotFound, NotFoundException
from requests.auth import HTTPBasicAuth
from opnfv.deployment.factory import Factory as DeploymentFactory
@@ -987,3 +987,118 @@ def is_fib_entry_present_on_odl(controllers, ip_prefix, vrf_id):
logger.error('Failed to find ip prefix %s with error %s'
% (ip_prefix, e))
return False
+
+
+def wait_stack_for_status(conn, stack_id, stack_status, limit=12):
+ """ Waits to reach specified stack status. To be used with
+ CREATE_COMPLETE and UPDATE_COMPLETE.
+ Will try a specific number of attempts at 10sec intervals
+ (default 2min)
+
+ :param stack_id: the stack id returned by create_stack api call
+ :param stack_status: the stack status waiting for
+ :param limit: the maximum number of attempts
+ """
+ logger.debug("Stack '%s' create started" % stack_id)
+
+ stack_create_complete = False
+ attempts = 0
+ while attempts < limit:
+ try:
+ stack_st = conn.orchestration.get_stack(stack_id).status
+ except NotFoundException:
+ logger.error("Stack create failed")
+ raise SystemError("Stack create failed")
+ return False
+ if stack_st == stack_status:
+ stack_create_complete = True
+ break
+ attempts += 1
+ time.sleep(10)
+
+ logger.debug("Stack status check: %s times" % attempts)
+ if stack_create_complete is False:
+ logger.error("Stack create failed")
+ raise SystemError("Stack create failed")
+ return False
+
+ return True
+
+
+def delete_stack_and_wait(conn, stack_id, limit=12):
+ """ Starts and waits for completion of delete stack
+
+ Will try a specific number of attempts at 10sec intervals
+ (default 2min)
+
+ :param stack_id: the id of the stack to be deleted
+ :param limit: the maximum number of attempts
+ """
+ delete_started = False
+ if stack_id is not None:
+ delete_started = os_utils.delete_stack(conn, stack_id)
+
+ if delete_started is True:
+ logger.debug("Stack delete succesfully started")
+ else:
+ logger.error("Stack delete start failed")
+
+ stack_delete_complete = False
+ attempts = 0
+ while attempts < limit:
+ try:
+ stack_st = conn.orchestration.get_stack(stack_id).status
+ if stack_st == 'DELETE_COMPLETE':
+ stack_delete_complete = True
+ break
+ attempts += 1
+ time.sleep(10)
+ except NotFoundException:
+ stack_delete_complete = True
+ break
+
+ logger.debug("Stack status check: %s times" % attempts)
+ if not stack_delete_complete:
+ logger.error("Stack delete failed")
+ raise SystemError("Stack delete failed")
+ return False
+
+ return True
+
+
+def get_heat_environment(testcase, common_config):
+ """ Reads the heat parameters of a testcase into a yaml object
+
+ Each testcase where Heat Orchestratoin Template (HOT) is introduced
+ has an associated parameters section.
+ Reads testcase.heat_parameters section and read COMMON_CONFIG.flavor
+ and place it under parameters tree.
+
+ :param testcase: the tescase for which the HOT file is fetched
+ :param common_config: the common config section
+ :return environment: a yaml object to be used as environment
+ """
+ fl = common_config.default_flavor
+ param_dict = testcase.heat_parameters
+ param_dict['flavor'] = fl
+ env_dict = {'parameters': param_dict}
+ return env_dict
+
+
+def get_vms_from_stack_outputs(conn, stack_id, vm_stack_output_keys):
+ """ Converts a vm name from a heat stack output to a nova vm object
+
+ :param stack_id: the id of the stack to fetch the vms from
+ :param vm_stack_output_keys: a list of stack outputs with the vm names
+ :return vms: a list of vm objects corresponding to the outputs
+ """
+ vms = []
+ for vmk in vm_stack_output_keys:
+ vm_output = os_utils.get_output(conn, stack_id, vmk)
+ if vm_output is not None:
+ vm_name = vm_output['output_value']
+ logger.debug("vm '%s' read from heat output" % vm_name)
+ vm = os_utils.get_instance_by_name(conn, vm_name)
+ if vm is not None:
+ vms.append(vm)
+ return vms