summaryrefslogtreecommitdiffstats
path: root/vnftest/common
diff options
context:
space:
mode:
Diffstat (limited to 'vnftest/common')
-rw-r--r--vnftest/common/exceptions.py4
-rw-r--r--vnftest/common/openstack_utils.py51
-rw-r--r--vnftest/common/rest_client.py15
-rw-r--r--vnftest/common/utils.py131
4 files changed, 183 insertions, 18 deletions
diff --git a/vnftest/common/exceptions.py b/vnftest/common/exceptions.py
index 85cb203..9e29c52 100644
--- a/vnftest/common/exceptions.py
+++ b/vnftest/common/exceptions.py
@@ -43,3 +43,7 @@ class MandatoryKeyException(VnftestException):
class InputParameterMissing(VnftestException):
message_tmplate = 'No value found for parameter "{param_name}" in "{source}"'
+
+
+class ResourceNotFound(VnftestException):
+ message_tmplate = 'Resource not found "{resource}"'
diff --git a/vnftest/common/openstack_utils.py b/vnftest/common/openstack_utils.py
index c97c1c2..829b916 100644
--- a/vnftest/common/openstack_utils.py
+++ b/vnftest/common/openstack_utils.py
@@ -27,6 +27,7 @@ from cinderclient import client as cinderclient
from novaclient import client as novaclient
from glanceclient import client as glanceclient
from neutronclient.neutron import client as neutronclient
+from heatclient.client import Client as heatclient
log = logging.getLogger(__name__)
@@ -159,6 +160,11 @@ def get_neutron_client(): # pragma: no cover
return neutronclient.Client(get_neutron_client_version(), session=sess)
+def get_heat_client(): # pragma: no cover
+ sess = get_session()
+ return heatclient(get_heat_api_version(), session=sess)
+
+
def get_glance_client_version(): # pragma: no cover
try:
api_version = os.environ['OS_IMAGE_API_VERSION']
@@ -199,6 +205,14 @@ def get_instance_by_name(nova_client, instance_name): # pragma: no cover
instance_name)
+def get_instance_by_id(instance_id): # pragma: no cover
+ try:
+ return get_nova_client().servers.find(id=instance_id)
+ except Exception:
+ log.exception("Error [get_instance_by_id(nova_client, '%s')]",
+ instance_id)
+
+
def get_aggregates(nova_client): # pragma: no cover
try:
return nova_client.aggregates.list()
@@ -440,6 +454,15 @@ def delete_keypair(nova_client, key): # pragma: no cover
# *********************************************
# NEUTRON
# *********************************************
+def get_network_by_name(network_name): # pragma: no cover
+ try:
+ networks = get_neutron_client().list_networks()['networks']
+ return next((n for n in networks if n['name'] == network_name), None)
+ except Exception:
+ log.exception("Error [get_instance_by_id(nova_client, '%s')]",
+ network_name)
+
+
def get_network_id(neutron_client, network_name): # pragma: no cover
networks = neutron_client.list_networks()['networks']
return next((n['id'] for n in networks if n['name'] == network_name), None)
@@ -760,3 +783,31 @@ def detach_volume(server_id, volume_id): # pragma: no cover
log.exception("Error [detach_server_volume(nova_client, '%s', '%s')]",
server_id, volume_id)
return False
+# *********************************************
+# HEAT
+# *********************************************
+
+
+def get_stack(heat_stack_id): # pragma: no cover
+ try:
+ client = get_heat_client()
+ return client.stacks.get(heat_stack_id)
+ except Exception as e:
+ log.exception("Error [get_stack(heat_stack_id)]", e)
+
+
+def get_stack_resources(heat_stack_id): # pragma: no cover
+ try:
+ client = get_heat_client()
+ return client.resources.list(heat_stack_id)
+ except Exception as e:
+ log.exception("Error [get_stack_resources(heat_stack_id)]", e)
+
+
+def get_stack_vms(heat_stack_id): # pragma: no cover
+ resources = get_stack_resources(heat_stack_id)
+ ret_vms = []
+ for resource in resources:
+ if resource.resource_type == "OS::Nova::Server":
+ ret_vms.append(resource)
+ return ret_vms
diff --git a/vnftest/common/rest_client.py b/vnftest/common/rest_client.py
index 23a108c..051f5dd 100644
--- a/vnftest/common/rest_client.py
+++ b/vnftest/common/rest_client.py
@@ -14,9 +14,17 @@
##############################################################################
import json
+
+import logging
+import os
import urllib2
import requests
+from vnftest.common import utils
+
+logger = logging.getLogger(__name__)
+os.putenv('PYTHONHTTPSVERIFY', "0")
+
def post(url, headers, data, logger):
return call(url, 'POST', headers, data, logger)
@@ -31,10 +39,15 @@ def call(url, method, headers, data, logger):
f = urllib2.urlopen(req)
return_code = f.code
response_body = f.read()
+ headers = f.headers
+ content_type = headers.dict['content-type'] if 'content-type' in headers.dict else 'application/json'
f.close()
if len(str(response_body)) == 0:
response_body = "{}"
- response_body = json.loads(response_body)
+ if 'application/xml' in content_type:
+ response_body = utils.xml_to_dict(response_body)
+ else:
+ response_body = json.loads(response_body)
result = {'return_code': return_code, 'body': response_body}
return result
diff --git a/vnftest/common/utils.py b/vnftest/common/utils.py
index ad1b2f3..406796d 100644
--- a/vnftest/common/utils.py
+++ b/vnftest/common/utils.py
@@ -15,10 +15,13 @@
# yardstick/common/utils.py
import collections
+import formatter
from contextlib import closing
import datetime
import errno
import importlib
+from string import Formatter
+
import ipaddress
import logging
import os
@@ -27,16 +30,21 @@ import socket
import subprocess
import sys
+import pkg_resources
import six
from flask import jsonify
from six.moves import configparser
from oslo_serialization import jsonutils
-
+import xml.etree.ElementTree
import vnftest
+from vnftest.common.exceptions import ResourceNotFound
+
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
+class_implementations = {}
+
# Decorator for cli-args
def cliargs(*args, **kwargs):
@@ -46,23 +54,24 @@ def cliargs(*args, **kwargs):
return _decorator
-def itersubclasses(cls, _seen=None):
- """Generator over all subclasses of a given class in depth first order."""
+def findsubclasses(cls):
+ if cls.__name__ not in class_implementations:
+ # Load entrypoint classes just once.
+ if len(class_implementations) == 0:
+ for entrypoint in pkg_resources.iter_entry_points(group='vnftest.extension'):
+ loaded_type = entrypoint.load()
+ logger.info("Loaded: " + str(loaded_type))
- if not isinstance(cls, type):
- raise TypeError("itersubclasses must be called with "
- "new-style classes, not %.100r" % cls)
- _seen = _seen or set()
- try:
- subs = cls.__subclasses__()
- except TypeError: # fails only when cls is type
- subs = cls.__subclasses__(cls)
- for sub in subs:
- if sub not in _seen:
- _seen.add(sub)
- yield sub
- for sub in itersubclasses(sub, _seen):
- yield sub
+ subclasses = []
+ class_implementations[cls.__name__] = subclasses
+
+ def getallnativesubclasses(clazz):
+ for subclass in clazz.__subclasses__():
+ subclasses.append(subclass)
+ getallnativesubclasses(subclass)
+
+ getallnativesubclasses(cls)
+ return class_implementations[cls.__name__]
def import_modules_from_package(package):
@@ -431,3 +440,91 @@ class dotdict(dict):
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
+
+
+def normalize_data_struct(obj):
+ if isinstance(obj, basestring):
+ return [obj]
+ if isinstance(obj, list):
+ nomalized_list = []
+ for element in obj:
+ element = normalize_data_struct(element)
+ nomalized_list.append(element)
+ return nomalized_list
+ if isinstance(obj, dict):
+ normalized_dict = {}
+ for k, v in obj:
+ v = normalize_data_struct(v)
+ normalized_dict[k] = v
+ return normalized_dict
+ return change_obj_to_dict(obj)
+
+
+def xml_to_dict(xml_str):
+ return element_tree_to_dict(xml.etree.ElementTree.fromstring(xml_str))
+
+
+def element_tree_to_dict(element_tree):
+ def internal_iter(tree, accum):
+ if tree is None:
+ return accum
+ attribute_target = None
+ if tree.getchildren():
+ accum[tree.tag] = {}
+ attribute_target = accum[tree.tag]
+ for each in tree.getchildren():
+ result = internal_iter(each, {})
+ if each.tag in accum[tree.tag]:
+ if not isinstance(accum[tree.tag][each.tag], list):
+ accum[tree.tag][each.tag] = [
+ accum[tree.tag][each.tag]
+ ]
+ accum[tree.tag][each.tag].append(result[each.tag])
+ else:
+ accum[tree.tag].update(result)
+ else:
+ attribute_target = accum
+ accum[tree.tag] = tree.text
+ # Add attributes
+ attributes = tree.attrib or {}
+ for att_name, att_value in attributes.iteritems():
+ attribute_target[att_name] = att_value
+
+ return accum
+
+ return internal_iter(element_tree, {})
+
+
+def resource_as_string(path):
+ split_path = os.path.split(path)
+ package = split_path[0].replace("/", ".")
+ if not pkg_resources.resource_exists(package, split_path[1]):
+ raise ResourceNotFound(resource=path)
+ return pkg_resources.resource_string(package, split_path[1])
+
+
+def load_resource(path):
+ split_path = os.path.split(path)
+ package = split_path[0].replace("/", ".")
+ if not pkg_resources.resource_exists(package, split_path[1]):
+ raise ResourceNotFound(resource=path)
+ return pkg_resources.resource_stream(package, split_path[1])
+
+
+def format(st, params):
+ if not isinstance(st, basestring):
+ return st
+ ret_str = ""
+ ret_obj = None
+ for literal_text, field_name, format_spec, conversion in \
+ Formatter().parse(st):
+ if field_name is None:
+ ret_str = ret_str + literal_text
+ else:
+ dict = ret_obj or params
+ value = dict[field_name]
+ if isinstance(value, basestring):
+ ret_str = ret_str + value
+ else:
+ ret_obj = value
+ return ret_obj or ret_str