From 99736a3882982aef0776f80056202ee745eb3fa4 Mon Sep 17 00:00:00 2001
From: JingLu5 <lvjing5@huawei.com>
Date: Tue, 13 Dec 2016 05:42:41 +0000
Subject: Add support for OpenSrack Newton

JIRA: YARDSTICK-410

This patch uses keystoneauth1.session to initialize the client for Heat
The keystoneauth1.session.Session class was introduced into keystoneauth1
as an attempt to bring a unified interface to the various OpenStack clients
that share common authentication and request parameters between a variety of
services.

Change-Id: Ie6287b50a36cf03950fa1174791df826e9bdafd3
Signed-off-by: JingLu5 <lvjing5@huawei.com>
---
 tests/unit/common/test_openstack_utils.py | 41 +++++++++++++
 yardstick/common/openstack_utils.py       | 97 +++++++++++++++++++++++++++++++
 yardstick/orchestrator/heat.py            | 31 +++-------
 3 files changed, 146 insertions(+), 23 deletions(-)
 create mode 100644 tests/unit/common/test_openstack_utils.py
 create mode 100644 yardstick/common/openstack_utils.py

diff --git a/tests/unit/common/test_openstack_utils.py b/tests/unit/common/test_openstack_utils.py
new file mode 100644
index 000000000..ef619aace
--- /dev/null
+++ b/tests/unit/common/test_openstack_utils.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+# Unittest for yardstick.common.openstack_utils
+
+import unittest
+import mock
+
+from yardstick.common import openstack_utils
+
+
+class GetCredentialsTestCase(unittest.TestCase):
+
+    @mock.patch('yardstick.common.openstack_utils.os')
+    def test_get_credentials(self, mock_os):
+        mock_os.getenv.return_value = ('2')
+        openstack_utils.get_credentials()
+
+
+class GetHeatApiVersionTestCase(unittest.TestCase):
+
+    @mock.patch('yardstick.common.openstack_utils.os')
+    def test_get_heat_api_version(self, mock_os):
+        API = 'HEAT_API_VERSION'
+        openstack_utils.get_heat_api_version()
+        mock_os.getenv.assert_called_with(API)
+
+    @mock.patch('yardstick.common.openstack_utils.os')
+    def test_get_heat_api_version(self, mock_os):
+        mock_os.getenv.return_value = ('2')
+        expected_result = '2'
+        api_version = openstack_utils.get_heat_api_version()
+        self.assertEqual(api_version, expected_result)
diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py
new file mode 100644
index 000000000..25dcffadd
--- /dev/null
+++ b/yardstick/common/openstack_utils.py
@@ -0,0 +1,97 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+# yardstick: this file is copied from rally and slightly modified
+##############################################################################
+
+import os
+import logging
+
+from keystoneauth1 import loading
+from keystoneauth1 import session
+
+log = logging.getLogger(__name__)
+
+DEFAULT_HEAT_API_VERSION = '1'
+
+
+def get_credentials():
+    """Returns a creds dictionary filled with parsed from env"""
+    creds = {}
+
+    keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
+
+    if keystone_api_version is None or keystone_api_version == '2':
+        keystone_v3 = False
+        tenant_env = 'OS_TENANT_NAME'
+        tenant = 'tenant_name'
+    else:
+        keystone_v3 = True
+        tenant_env = 'OS_PROJECT_NAME'
+        tenant = 'project_name'
+
+    # The most common way to pass these info to the script is to do it
+    # through environment variables.
+    creds.update({
+        "username": os.environ.get("OS_USERNAME"),
+        "password": os.environ.get("OS_PASSWORD"),
+        "auth_url": os.environ.get("OS_AUTH_URL"),
+        tenant: os.environ.get(tenant_env)
+    })
+
+    if keystone_v3:
+        if os.getenv('OS_USER_DOMAIN_NAME') is not None:
+            creds.update({
+                "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
+            })
+        if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
+            creds.update({
+                "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
+            })
+
+    cacert = os.environ.get("OS_CACERT")
+
+    if cacert is not None:
+        # each openstack client uses differnt kwargs for this
+        creds.update({"cacert": cacert,
+                      "ca_cert": cacert,
+                      "https_ca_cert": cacert,
+                      "https_cacert": cacert,
+                      "ca_file": cacert})
+        creds.update({"insecure": "True", "https_insecure": "True"})
+        if not os.path.isfile(cacert):
+            log.info("WARNING: The 'OS_CACERT' environment variable is set\
+                      to %s but the file does not exist." % cacert)
+
+    return creds
+
+
+def get_session_auth():
+    loader = loading.get_plugin_loader('password')
+    creds = get_credentials()
+    auth = loader.load_from_options(**creds)
+    return auth
+
+
+def get_session():
+    auth = get_session_auth()
+    return session.Session(auth=auth)
+
+
+def get_endpoint(service_type, endpoint_type='publicURL'):
+    auth = get_session_auth()
+    return get_session().get_endpoint(auth=auth,
+                                      service_type=service_type,
+                                      endpoint_type=endpoint_type)
+
+
+def get_heat_api_version():
+    api_version = os.getenv('HEAT_API_VERSION')
+    if api_version is not None:
+        log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
+        return api_version
+    return DEFAULT_HEAT_API_VERSION
diff --git a/yardstick/orchestrator/heat.py b/yardstick/orchestrator/heat.py
index f3a191503..4839455e1 100644
--- a/yardstick/orchestrator/heat.py
+++ b/yardstick/orchestrator/heat.py
@@ -7,10 +7,8 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
-""" Heat template and stack management
-"""
+"""Heat template and stack management"""
 
-import os
 import time
 import datetime
 import getpass
@@ -18,10 +16,11 @@ import socket
 import logging
 import pkg_resources
 import json
-import heatclient.client
-import keystoneclient
+
+import heatclient
 
 from yardstick.common import template_format
+import yardstick.common.openstack_utils as op_utils
 
 
 log = logging.getLogger(__name__)
@@ -30,32 +29,18 @@ log = logging.getLogger(__name__)
 class HeatObject(object):
     ''' base class for template and stack'''
     def __init__(self):
-        self._keystone_client = None
         self._heat_client = None
         self.uuid = None
 
-    def _get_keystone_client(self):
-        '''returns a keystone client instance'''
-
-        if self._keystone_client is None:
-            self._keystone_client = keystoneclient.v2_0.client.Client(
-                auth_url=os.environ.get('OS_AUTH_URL'),
-                username=os.environ.get('OS_USERNAME'),
-                password=os.environ.get('OS_PASSWORD'),
-                tenant_name=os.environ.get('OS_TENANT_NAME'),
-                cacert=os.environ.get('OS_CACERT'))
-
-        return self._keystone_client
-
     def _get_heat_client(self):
         '''returns a heat client instance'''
 
         if self._heat_client is None:
-            keystone = self._get_keystone_client()
-            heat_endpoint = keystone.service_catalog.url_for(
-                service_type='orchestration')
+            sess = op_utils.get_session()
+            heat_endpoint = op_utils.get_endpoint(service_type='orchestration')
             self._heat_client = heatclient.client.Client(
-                '1', endpoint=heat_endpoint, token=keystone.auth_token)
+                op_utils.get_heat_api_version(),
+                endpoint=heat_endpoint, session=sess)
 
         return self._heat_client
 
-- 
cgit