Merge "Replace domain name from Default to default"
authorJose Lausuch <jose.lausuch@ericsson.com>
Thu, 23 Mar 2017 14:43:56 +0000 (14:43 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Thu, 23 Mar 2017 14:43:56 +0000 (14:43 +0000)
18 files changed:
.gitmodules [new file with mode: 0644]
docker/Dockerfile
docs/com/README.txt [deleted file]
docs/com/pres/Summit/Berlin-2016/conversation.html
docs/com/pres/Summit/Berlin-2016/summit-Berlin.html
docs/com/pres/Summit/Berlin-2016/testapi.html
docs/com/pres/dashboard/dashboard_status.html
docs/com/pres/reveal.js [new submodule]
functest/ci/check_os.sh
functest/ci/config_functest.yaml
functest/ci/prepare_env.py
functest/opnfv_tests/features/odl_sfc.py
functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.txt
functest/tests/unit/utils/test_openstack_utils.py
functest/utils/decorators.py
functest/utils/functest_logger.py
functest/utils/openstack_utils.py
kingbird_requirements.txt [new file with mode: 0644]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..78668cf
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "docs/com/pres/reveal.js"]
+       path = docs/com/pres/reveal.js
+       url = https://github.com/hakimel/reveal.js.git
index af3f8ec..4c0995b 100644 (file)
@@ -156,6 +156,7 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install -e .
 
 # Kingbird integration
 RUN cd ${REPOS_DIR}/kingbird && pip install -e .
+RUN cd ${FUNCTEST_REPO_DIR} && pip install -r kingbird_requirements.txt
 
 # refstack-client integration
 RUN cd ${REPOS_DIR}/refstack-client && ./setup_env -t ${REFSTACK_TAG}
diff --git a/docs/com/README.txt b/docs/com/README.txt
deleted file mode 100644 (file)
index 62d616b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-This com folder contains the images, html and css files used to create
-communication based on reveal.js
-All the files are licensed under Creative Commons Attribution 4.0
-International License.
-.. http://creativecommons.org/licenses/by/4.0
-
-You can download reveal.js at:  https://github.com/hakimel/reveal.js/
-Then you must put images and css on existing directory and add the pres
-directory
index b56b1e1..356c2ad 100755 (executable)
 
                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
 
-               <link rel="stylesheet" href="../../../css/reveal.css">
+               <link rel="stylesheet" href="../../reveal.js/css/reveal.css">
                <link rel="stylesheet" href="../../../css/theme/OPNFV-Berlin.css" id="theme">
 
                <!-- Code syntax highlighting -->
-               <link rel="stylesheet" href="../../../lib/css/zenburn.css">
+               <link rel="stylesheet" href="../../reveal.js/lib/css/zenburn.css">
 
                <!-- Printing and PDF exports -->
                <script>
                        var link = document.createElement( 'link' );
                        link.rel = 'stylesheet';
                        link.type = 'text/css';
-                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../../css/print/pdf.css' : '../../../css/print/paper.css';
+                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../reveal.js/css/print/pdf.css' : '../../reveal.js/css/print/paper.css';
                        document.getElementsByTagName( 'head' )[0].appendChild( link );
                </script>
 
                </div>
                </div>
 
-               <script src="../../../lib/js/head.min.js"></script>
-               <script src="../../../js/reveal.js"></script>
+               <script src="../../reveal.js/lib/js/head.min.js"></script>
+               <script src="../../reveal.js/js/reveal.js"></script>
 
                <script>
 
 
                                // Optional reveal.js plugins
                                dependencies: [
-                                       { src: '../../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
-                                       { src: '../../../plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
-                                       { src: '../../../plugin/zoom-js/zoom.js', async: true },
-                                       { src: '../../../plugin/notes/notes.js', async: true }
+                                       { src: '../../reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+                                       { src: '../../reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
+                                       { src: '../../reveal.js/plugin/zoom-js/zoom.js', async: true },
+                                       { src: '../../reveal.js/plugin/notes/notes.js', async: true }
                                ]
                        });
 
index 8369443..97fa66c 100755 (executable)
 
                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
 
-               <link rel="stylesheet" href="../../../css/reveal.css">
+               <link rel="stylesheet" href="../../reveal.js/css/reveal.css">
                <link rel="stylesheet" href="../../../css/theme/OPNFV-Berlin.css" id="theme">
 
                <!-- Code syntax highlighting -->
-               <link rel="stylesheet" href="../../../lib/css/zenburn.css">
+               <link rel="stylesheet" href="../../reveal.js/lib/css/zenburn.css">
 
                <!-- Printing and PDF exports -->
                <script>
                        var link = document.createElement( 'link' );
                        link.rel = 'stylesheet';
                        link.type = 'text/css';
-                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../../css/print/pdf.css' : '../../../css/print/paper.css';
+                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../reveal.js/css/print/pdf.css' : '../../../css/print/paper.css';
                        document.getElementsByTagName( 'head' )[0].appendChild( link );
                </script>
 
                <!--[if lt IE 9]>
-               <script src="lib/js/html5shiv.js"></script>
+               <script src="l../../reveal.jsml5shiv.js"></script>
                <![endif]-->
        </head>
 
 
                        </div>
             <div class='footer'>
-                                <img src="../../../img/logo-OPNFV-Berlin.png" alt="OPNFV logo"> 
+                                <img src="../../../img/logo-OPNFV-Berlin.png" alt="OPNFV logo">
                </div>
                </div>
 
-               <script src="../../../lib/js/head.min.js"></script>
-               <script src="../../../js/reveal.js"></script>
+               <script src="../../reveal.js/lib/js/head.min.js"></script>
+               <script src="../../reveal.js/js/reveal.js"></script>
 
                <script>
 
 
                                // Optional reveal.js plugins
                                dependencies: [
-                                       { src: '../../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
-                                       { src: '../../../plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
-                                       { src: '../../../plugin/zoom-js/zoom.js', async: true },
-                                       { src: '../../../plugin/notes/notes.js', async: true }
+                                       { src: '../../reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+                                       { src: '../../reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
+                                       { src: '../../reveal.js/plugin/zoom-js/zoom.js', async: true },
+                                       { src: '../../reveal.js/plugin/notes/notes.js', async: true }
                                ]
                        });
 
index 16f97c4..c40637c 100755 (executable)
 
                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
 
-               <link rel="stylesheet" href="../../../css/reveal.css">
+               <link rel="stylesheet" href="../../reveal.js/css/reveal.css">
                <link rel="stylesheet" href="../../../css/theme/OPNFV-Berlin.css" id="theme">
 
                <!-- Code syntax highlighting -->
-               <link rel="stylesheet" href="../../../lib/css/zenburn.css">
+               <link rel="stylesheet" href="../../reveal.js/lib/css/zenburn.css">
 
                <!-- Printing and PDF exports -->
                <script>
                        var link = document.createElement( 'link' );
                        link.rel = 'stylesheet';
                        link.type = 'text/css';
-                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../../css/print/pdf.css' : '../../../css/print/paper.css';
+                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../reveal.js/css/print/pdf.css' : '../../reveal.js/css/print/paper.css';
                        document.getElementsByTagName( 'head' )[0].appendChild( link );
                </script>
 
@@ -242,8 +242,8 @@ OK
                        </div>
                </div>
 
-               <script src="../../../lib/js/head.min.js"></script>
-               <script src="../../../js/reveal.js"></script>
+               <script src="../../reveal.js/lib/js/head.min.js"></script>
+               <script src="../../reveal.js/js/reveal.js"></script>
 
                <script>
 
@@ -259,12 +259,12 @@ OK
 
                                // Optional reveal.js plugins
                                dependencies: [
-                                       { src: '../../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
-                                       { src: '../../../plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../../plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
-                                       { src: '../../../plugin/zoom-js/zoom.js', async: true },
-                                       { src: '../../../plugin/notes/notes.js', async: true }
+                                       { src: '../../reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+                                       { src: '../../reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../../reveal.js/plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
+                                       { src: '../../reveal.js/plugin/zoom-js/zoom.js', async: true },
+                                       { src: '../../reveal.js/plugin/notes/notes.js', async: true }
                                ]
                        });
 
index 7d46a74..1321afa 100755 (executable)
 
                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
 
-               <link rel="stylesheet" href="../../css/reveal.css">
+               <link rel="stylesheet" href="../reveal.js/css/reveal.css">
                <link rel="stylesheet" href="../../css/theme/OPNFV.css" id="theme">
 
                <!-- Code syntax highlighting -->
-               <link rel="stylesheet" href="../../lib/css/zenburn.css">
+               <link rel="stylesheet" href="../reveal.js/lib/css/zenburn.css">
 
                <!-- Printing and PDF exports -->
                <script>
                        var link = document.createElement( 'link' );
                        link.rel = 'stylesheet';
                        link.type = 'text/css';
-                       link.href = window.location.search.match( /print-pdf/gi ) ? '../../css/print/pdf.css' : '../../css/print/paper.css';
+                       link.href = window.location.search.match( /print-pdf/gi ) ? '../reveal.js/css/print/pdf.css' : '../reveal.js/css/print/paper.css';
                        document.getElementsByTagName( 'head' )[0].appendChild( link );
                </script>
 
                </div>
                </div>
 
-               <script src="../../lib/js/head.min.js"></script>
-               <script src="../../js/reveal.js"></script>
+               <script src="../reveal.js/lib/js/head.min.js"></script>
+               <script src="../reveal.js/js/reveal.js"></script>
 
                <script>
 
 
                                // Optional reveal.js plugins
                                dependencies: [
-                                       { src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
-                                       { src: '../../plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
-                                       { src: '../../plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
-                                       { src: '../../plugin/zoom-js/zoom.js', async: true },
-                                       { src: '../../plugin/notes/notes.js', async: true }
+                                       { src: '../reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+                                       { src: '../reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+                                       { src: '../reveal.js/plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
+                                       { src: '../reveal.js/plugin/zoom-js/zoom.js', async: true },
+                                       { src: '../reveal.js/plugin/notes/notes.js', async: true }
                                ]
                        });
 
diff --git a/docs/com/pres/reveal.js b/docs/com/pres/reveal.js
new file mode 160000 (submodule)
index 0000000..a349ff4
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit a349ff43c58c23f9c837b8ea9b5fc7d4761b8de3
index 2c5c021..3920b7a 100755 (executable)
@@ -26,6 +26,11 @@ verify_connectivity() {
     return 1
 }
 
+verify_SSL_connectivity() {
+    openssl s_client -connect $1:$2 &>/dev/null
+    return $?
+}
+
 check_service() {
     local service cmd
     service=$1
@@ -63,10 +68,16 @@ fi
 
 echo "Checking OpenStack endpoints:"
 publicURL=$(openstack catalog show  identity |awk '/public/ {print $4}')
-publicIP=$(echo $publicURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
+publicIP=$(echo $publicURL|sed 's/^.*http.*\:\/\///'|sed 's/.[^:]*$//')
 publicPort=$(echo $publicURL|sed 's/^.*://'|sed 's/\/.*$//')
-echo ">>Verifying connectivity to the public endpoint $publicIP:$publicPort..."
-verify_connectivity $publicIP $publicPort
+https_enabled=$(echo $publicURL | grep 'https')
+if [[ -n $https_enabled ]]; then
+    echo ">>Verifying SSL connectivity to the public endpoint $publicIP:$publicPort..."
+    verify_SSL_connectivity $publicIP $publicPort
+else
+    echo ">>Verifying connectivity to the public endpoint $publicIP:$publicPort..."
+    verify_connectivity $publicIP $publicPort
+fi
 RETVAL=$?
 if [ $RETVAL -ne 0 ]; then
     echo "ERROR: Cannot talk to the public endpoint $publicIP:$publicPort ."
@@ -81,10 +92,16 @@ if [ -z ${adminURL} ]; then
     openstack catalog show identity
     exit 1
 fi
-adminIP=$(echo $adminURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
+adminIP=$(echo $adminURL|sed 's/^.*http.*\:\/\///'|sed 's/.[^:]*$//')
 adminPort=$(echo $adminURL|sed 's/^.*://'|sed 's/.[^\/]*$//')
-echo ">>Verifying connectivity to the admin endpoint $adminIP:$adminPort..."
-verify_connectivity $adminIP $adminPort
+https_enabled=$(echo $adminURL | grep 'https')
+if [[ -n $https_enabled ]]; then
+    echo ">>Verifying SSL connectivity to the admin endpoint $adminIP:$adminPort..."
+    verify_SSL_connectivity $adminIP $adminPort
+else
+    echo ">>Verifying connectivity to the admin endpoint $adminIP:$adminPort..."
+    verify_connectivity $adminIP $adminPort
+fi
 RETVAL=$?
 if [ $RETVAL -ne 0 ]; then
     echo "ERROR: Cannot talk to the admin endpoint $adminIP:$adminPort ."
index 4d5a621..78f6257 100755 (executable)
@@ -200,4 +200,6 @@ example:
     sg_desc: Example Security group
 
 results:
+    # you can also set a dir (e.g. /home/opnfv/db) to dump results
+    # test_db_url: file:///home/opnfv/db
     test_db_url: http://testresults.opnfv.org/test/api/v1
index 724ea14..e9a470f 100755 (executable)
@@ -312,7 +312,7 @@ def install_tempest():
             logger.debug("Tempest %s does not exist" %
                          CONST.tempest_deployment_name)
             cmd = ("rally verify create-verifier --source {0} "
-                   "--name {1} --type tempest"
+                   "--name {1} --type tempest --system-wide"
                    .format(CONST.dir_repo_tempest,
                            CONST.tempest_deployment_name))
             error_msg = "Problem while installing Tempest."
index 1956c9c..431cd47 100644 (file)
@@ -8,6 +8,7 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 #
 import functest.core.feature_base as base
+from sfc.tests.functest import run_tests
 
 
 class OpenDaylightSFC(base.FeatureBase):
@@ -16,5 +17,6 @@ class OpenDaylightSFC(base.FeatureBase):
         super(OpenDaylightSFC, self).__init__(project='sfc',
                                               case='functest-odl-sfc',
                                               repo='dir_repo_sfc')
-        dir_sfc_functest = '{}/sfc/tests/functest'.format(self.repo)
-        self.cmd = 'cd %s && python ./run_tests.py' % dir_sfc_functest
+
+    def execute(self):
+        return run_tests.main()
index fcdfe22..43edabc 100644 (file)
         - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
         - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_volume_boot_pattern
         - tempest.scenario.test_volume_boot_pattern.TestVolumeBootPatternV2.test_volume_boot_pattern
+
+-
+    # https://bugs.launchpad.net/tempest/+bug/1577632
+    scenarios:
+        - os-odl_l2-nofeature-ha
+        - os-odl_l2-nofeature-noha
+        - os-odl_l2-sfc-ha
+        - os-odl_l2-sfc-noha
+        - os-odl_l2-bgpvpn-ha
+        - os-odl_l2-bgpvpn-noha
+        - os-odl_l3-nofeature-ha
+        - os-odl_l3-nofeature-noha
+    installers:
+        - fuel
+    tests:
+        - tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
index ef3764c..f51a499 100644 (file)
@@ -28,7 +28,8 @@ class OSUtilsTesting(unittest.TestCase):
                 'OS_PROJECT_DOMAIN_NAME': os_prefix + 'project_domain_name',
                 'OS_PROJECT_NAME': os_prefix + 'project_name',
                 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type',
-                'OS_REGION_NAME': os_prefix + 'region_name'}
+                'OS_REGION_NAME': os_prefix + 'region_name',
+                'OS_CACERT': os_prefix + 'https_cacert'}
 
     def _get_os_env_vars(self):
         return {'username': 'test_username', 'password': 'test_password',
@@ -37,7 +38,8 @@ class OSUtilsTesting(unittest.TestCase):
                 'project_domain_name': 'test_project_domain_name',
                 'project_name': 'test_project_name',
                 'endpoint_type': 'test_endpoint_type',
-                'region_name': 'test_region_name'}
+                'region_name': 'test_region_name',
+                'https_cacert': 'test_https_cacert'}
 
     def setUp(self):
         self.env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD']
@@ -299,7 +301,7 @@ class OSUtilsTesting(unittest.TestCase):
                          'OS_PROJECT_DOMAIN_NAME'])
         self.assertEqual(openstack_utils.get_rc_env_vars(), exp_resp)
 
-    @mock.patch('functest.utils.openstack_utils.get_rc_env_vars')
+    @mock.patch('functest.utils.openstack_utils')
     def test_check_credentials_missing_env(self, mock_get_rc_env):
         exp_resp = self.env_vars
         exp_resp.extend(['OS_TENANT_NAME'])
index 99bcef3..276235d 100644 (file)
@@ -1,6 +1,8 @@
 #!/usr/bin/env python
 
+import errno
 import mock
+import os
 import requests.sessions
 import urlparse
 
@@ -10,7 +12,12 @@ def can_dump_request_to_file(method):
     def dump_preparedrequest(request, **kwargs):
         parseresult = urlparse.urlparse(request.url)
         if parseresult.scheme == "file":
-            with open(parseresult.path.replace('/results', ''), 'a') as f:
+            try:
+                os.makedirs(parseresult.path)
+            except OSError as e:
+                if e.errno != errno.EEXIST:
+                    raise
+            with open(os.path.join(parseresult.path, 'dump.txt'), 'a') as f:
                 headers = ""
                 for key in request.headers:
                     headers += key + " " + request.headers[key] + "\n"
index 022211c..555e9c2 100644 (file)
@@ -28,13 +28,24 @@ import json
 
 from functest.utils.constants import CONST
 
+ignore = ["paramiko",
+          "stevedore.extension",
+          "keystoneauth.session",
+          "keystoneauth.identity.v3.base",
+          "novaclient.v2.client",
+          "neutronclient.v2_0.client",
+          "glanceclient.common.http",
+          "cinderclient.v2.client",
+          "cinderclient.client"]
+
 
 class Logger(object):
 
     def __init__(self, logger_name):
         self.setup_logging()
         self.logger = logging.getLogger(logger_name)
-        logging.getLogger("paramiko").setLevel(logging.WARNING)
+        for module_name in ignore:
+            logging.getLogger(module_name).setLevel(logging.WARNING)
 
     def getLogger(self):
         return self.logger
index e33af63..ffc870f 100644 (file)
@@ -82,7 +82,8 @@ def get_env_cred_dict():
         'OS_PROJECT_DOMAIN_NAME': 'project_domain_name',
         'OS_PROJECT_NAME': 'project_name',
         'OS_ENDPOINT_TYPE': 'endpoint_type',
-        'OS_REGION_NAME': 'region_name'
+        'OS_REGION_NAME': 'region_name',
+        'OS_CACERT': 'https_cacert'
     }
     return env_cred_dict
 
@@ -149,6 +150,11 @@ def get_credentials_for_rally():
     if region_name is not None:
         cred_key = env_cred_dict.get('OS_REGION_NAME')
         rally_conf[cred_key] = region_name
+
+    cacert = os.getenv('OS_CACERT')
+    if cacert is not None:
+        cred_key = env_cred_dict.get('OS_CACERT')
+        rally_conf[cred_key] = cacert
     return rally_conf
 
 
@@ -168,7 +174,14 @@ def get_endpoint(service_type, endpoint_type='publicURL'):
 
 def get_session(other_creds={}):
     auth = get_session_auth(other_creds)
-    return session.Session(auth=auth)
+    cacert = os.getenv('OS_CACERT')
+    if cacert is not None:
+        if not os.path.isfile(cacert):
+            raise Exception("The 'OS_CACERT' environment"
+                            "variable is set to %s but the file"
+                            "does not exist.", cacert)
+
+    return session.Session(auth=auth, verify=cacert)
 
 
 # *********************************************
diff --git a/kingbird_requirements.txt b/kingbird_requirements.txt
new file mode 100644 (file)
index 0000000..adf1082
--- /dev/null
@@ -0,0 +1,15 @@
+#
+#
+# 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
+#
+ddt==1.1.1
+oslosphinx==4.11.0
+oslotest==2.14.0
+pylint==1.4.5
+requests-mock==1.3.0
+tempest-lib==1.0.0
+testresources==2.0.1
+testscenarios==0.5.0