From 26539264361e2fc0bc65040116f5a377002d9b2b Mon Sep 17 00:00:00 2001
From: Major Hayden <major@mhtx.net>
Date: Tue, 6 Sep 2016 14:16:42 -0500
Subject: [PATCH] Ansible 2.1.1 update

Co-Authored-By: Major Hayden <major@mhtx.net>
Change-Id: Ic59abac5d7f15da37748d5b9121b74cd8e75d3c3
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
---
 .gitignore                                    |  7 +-
 Vagrantfile                                   |  4 +
 bindep.txt                                    |  2 +
 manual-test.rc                                | 33 +++++++
 run_tests.sh                                  | 10 +-
 tests/ansible-role-requirements.yml           |  5 +
 .../{all_containers => all_containers.yml}    |  5 +-
 .../localhost.yml}                            | 14 +--
 tests/inventory                               | 23 +++--
 tests/test-cinder-functional.yml              | 11 ++-
 tests/test-install-cinder.yml                 |  9 +-
 tests/test-install-infra.yml                  | 32 ------
 tests/test-install-keystone.yml               | 65 ------------
 tests/test-prepare-containers.yml             | 33 -------
 tests/test-prepare-host.yml                   | 46 ---------
 tests/test-prepare-keys.yml                   | 33 -------
 tests/test-vars.yml                           | 83 +++++-----------
 tests/test.yml                                | 16 +--
 tox.ini                                       | 98 +++++++------------
 vars/redhat-7.yml                             |  1 +
 20 files changed, 156 insertions(+), 374 deletions(-)
 create mode 100644 manual-test.rc
 rename tests/group_vars/{all_containers => all_containers.yml} (90%)
 rename tests/{test-install-tempest.yml => host_vars/localhost.yml} (73%)
 delete mode 100644 tests/test-install-infra.yml
 delete mode 100644 tests/test-install-keystone.yml
 delete mode 100644 tests/test-prepare-containers.yml
 delete mode 100644 tests/test-prepare-host.yml
 delete mode 100644 tests/test-prepare-keys.yml

diff --git a/.gitignore b/.gitignore
index ca2ac14c..21adf3c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@ doc/build/
 *.log
 *.sql
 *.sqlite
+logs/*
 
 # OS generated files #
 ######################
@@ -61,6 +62,10 @@ releasenotes/build
 
 # Test temp files
 tests/plugins
+tests/playbooks
+tests/test.retry
 
-# Vagrant testing artifacts
+# Vagrant artifacts
 .vagrant
+
+
diff --git a/Vagrantfile b/Vagrantfile
index 44872e1e..54f0e352 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,5 +1,9 @@
 Vagrant.configure(2) do |config|
   config.vm.box = "ubuntu/trusty64"
+  config.vm.provider "virtualbox" do |v|
+    v.memory = 2048
+    v.cpus = 2
+  end
   config.vm.provision "shell", inline: <<-SHELL
     sudo su -
     cd /vagrant
diff --git a/bindep.txt b/bindep.txt
index fe589259..f8d80fde 100644
--- a/bindep.txt
+++ b/bindep.txt
@@ -15,6 +15,7 @@ build-essential   [platform:dpkg]
 git-core          [platform:dpkg]
 libssl-dev        [platform:dpkg]
 libffi-dev        [platform:dpkg]
+lxc-dev           [platform:dpkg]
 python2.7         [platform:dpkg]
 python-dev        [platform:dpkg]
 
@@ -22,6 +23,7 @@ python-dev        [platform:dpkg]
 gcc               [platform:rpm]
 gcc-c++           [platform:rpm]
 git               [platform:rpm]
+lxc-devel         [platform:rpm]
 python-devel      [platform:rpm]
 libffi-devel      [platform:rpm]
 openssl-devel     [platform:rpm]
diff --git a/manual-test.rc b/manual-test.rc
new file mode 100644
index 00000000..7016c453
--- /dev/null
+++ b/manual-test.rc
@@ -0,0 +1,33 @@
+export VIRTUAL_ENV=$(pwd)
+export ANSIBLE_HOST_KEY_CHECKING=False
+export ANSIBLE_SSH_CONTROL_PATH=/tmp/%%h-%%r
+
+# TODO (odyssey4me) These are only here as they are non-standard folder
+# names for Ansible 1.9.x. We are using the standard folder names for
+# Ansible v2.x. We can remove this when we move to Ansible 2.x.
+export ANSIBLE_ACTION_PLUGINS=${HOME}/.ansible/plugins/action
+export ANSIBLE_CALLBACK_PLUGINS=${HOME}/.ansible/plugins/callback
+export ANSIBLE_FILTER_PLUGINS=${HOME}/.ansible/plugins/filter
+export ANSIBLE_LOOKUP_PLUGINS=${HOME}/.ansible/plugins/lookup
+
+# This is required as the default is the current path or a path specified
+# in ansible.cfg
+export ANSIBLE_LIBRARY=${HOME}/.ansible/plugins/library
+
+# This is required as the default is '/etc/ansible/roles' or a path
+# specified in ansible.cfg
+export ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:$(pwd)/..
+
+export ANSIBLE_SSH_ARGS="-o ControlMaster=no \
+  -o UserKnownHostsFile=/dev/null \
+  -o StrictHostKeyChecking=no \
+  -o ServerAliveInterval=64 \
+  -o ServerAliveCountMax=1024 \
+  -o Compression=no \
+  -o TCPKeepAlive=yes \
+  -o VerifyHostKeyDNS=no \
+  -o ForwardX11=no \
+  -o ForwardAgent=yes"
+
+echo "Run manual functional tests by executing the following:"
+echo "# ./.tox/functional/bin/ansible-playbook -i tests/inventory tests/test.yml"
diff --git a/run_tests.sh b/run_tests.sh
index 0a49aa3e..482a3894 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -24,23 +24,23 @@ if [ ! "$(which pip)" ]; then
 fi
 
 # Install bindep and tox
-pip install bindep tox
+sudo pip install bindep tox
 
 # CentOS 7 requires two additional packages:
 #   redhat-lsb-core - for bindep profile support
 #   epel-release    - required to install python-ndg_httpsclient/python2-pyasn1
 if [ "$(which yum)" ]; then
-    yum -y install redhat-lsb-core epel-release
+    sudo yum -y install redhat-lsb-core epel-release
 fi
 
 # Install OS packages using bindep
 if apt-get -v >/dev/null 2>&1 ; then
-    apt-get update
+    sudo apt-get update
     DEBIAN_FRONTEND=noninteractive \
-      apt-get -q --option "Dpkg::Options::=--force-confold" \
+      sudo apt-get -q --option "Dpkg::Options::=--force-confold" \
       --assume-yes install `bindep -b -f bindep.txt test`
 else
-    yum install -y `bindep -b -f bindep.txt test`
+    sudo yum install -y `bindep -b -f bindep.txt test`
 fi
 
 # run through each tox env and execute the test
diff --git a/tests/ansible-role-requirements.yml b/tests/ansible-role-requirements.yml
index e0b9e5c9..d27185d0 100644
--- a/tests/ansible-role-requirements.yml
+++ b/tests/ansible-role-requirements.yml
@@ -42,3 +42,8 @@
   src: https://git.openstack.org/openstack/openstack-ansible-os_tempest
   scm: git
   version: master
+- name: "openstack_hosts"
+  src: "https://github.com/openstack/openstack-ansible-openstack_hosts"
+  scm: git
+  version: "master"
+
diff --git a/tests/group_vars/all_containers b/tests/group_vars/all_containers.yml
similarity index 90%
rename from tests/group_vars/all_containers
rename to tests/group_vars/all_containers.yml
index 4cc97942..f37df47c 100644
--- a/tests/group_vars/all_containers
+++ b/tests/group_vars/all_containers.yml
@@ -13,14 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ansible_ssh_host: "{{ ansible_host }}"
 container_name: "{{ inventory_hostname }}"
 container_networks:
   management_address:
     address: "{{ ansible_host }}"
-    bridge: "lxcbr0"
+    bridge: "br-mgmt"
     interface: "eth1"
-    netmask: "255.255.252.0"
+    netmask: "255.255.255.0"
     type: "veth"
 physical_host: localhost
 properties:
diff --git a/tests/test-install-tempest.yml b/tests/host_vars/localhost.yml
similarity index 73%
rename from tests/test-install-tempest.yml
rename to tests/host_vars/localhost.yml
index 201755ee..65ddeaa0 100644
--- a/tests/test-install-tempest.yml
+++ b/tests/host_vars/localhost.yml
@@ -1,5 +1,5 @@
 ---
-# Copyright 2015, Rackspace US, Inc.
+# Copyright 2016, Rackspace US, Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -13,11 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-- name: Playbook for deploying tempest
-  hosts: openstack1
-  user: root
-  gather_facts: true
-  roles:
-    - role: "os_tempest"
-  vars_files:
-    - test-vars.yml
+bridges:
+  - "br-mgmt"
+
+ansible_python_interpreter: "/usr/bin/python2"
diff --git a/tests/inventory b/tests/inventory
index 47f85d72..1d6647ad 100644
--- a/tests/inventory
+++ b/tests/inventory
@@ -1,11 +1,13 @@
 [all]
-localhost ansible_connection=local ansible_become=True
+localhost ansible_become=True
 infra1 ansible_host=10.100.100.2 ansible_become=True ansible_user=root
-openstack1 ansible_host=10.100.100.3 ansible_become=True ansible_user=root
+keystone ansible_host=10.100.100.3 ansible_become=True ansible_user=root
+cinder ansible_host=10.100.100.4 ansible_become=True ansible_user=root
 
 [all_containers]
 infra1
-openstack1
+keystone
+cinder
 
 [rabbitmq_all]
 infra1
@@ -13,21 +15,28 @@ infra1
 [galera_all]
 infra1
 
+[memcached_all]
+infra1
+
 [service_all:children]
 rabbitmq_all
 galera_all
+memcached_all
 
 [keystone_all]
-openstack1
+keystone
+
+[utility_all]
+keystone
 
 [cinder_api]
-openstack1
+cinder
 
 [cinder_scheduler]
-openstack1
+cinder
 
 [cinder_backup]
-openstack1
+cinder
 
 [cinder_volume]
 localhost
diff --git a/tests/test-cinder-functional.yml b/tests/test-cinder-functional.yml
index af7a8c64..74a48905 100644
--- a/tests/test-cinder-functional.yml
+++ b/tests/test-cinder-functional.yml
@@ -22,11 +22,16 @@
       uri:
         url: "http://localhost:8776"
         status_code: 200,300
+
+- name: Playbook for tempest testing of cinder
+  hosts: utility_all
+  user: root
+  gather_facts: false
+  tasks:
     - name: Run tempest
       shell: |
         . {{ tempest_venv_bin }}/activate
-        {{ tempest_venv_bin | dirname }}/run_tempest.sh --no-virtual-env ${RUN_TEMPEST_OPTS} tempest.api.volume.test_volumes_get
-      environment:
-        RUN_TEMPEST_OPTS: "--serial"
+        {{ tempest_venv_bin | dirname }}/run_tempest.sh --no-virtual-env --serial tempest.api.volume.test_volumes_get
   vars_files:
+    - common/test-vars.yml
     - test-vars.yml
diff --git a/tests/test-install-cinder.yml b/tests/test-install-cinder.yml
index 46722d08..07c8ce33 100644
--- a/tests/test-install-cinder.yml
+++ b/tests/test-install-cinder.yml
@@ -22,7 +22,7 @@
       rabbitmq_vhost:
         name: "{{ cinder_rabbitmq_vhost }}"
         state: "present"
-      delegate_to: "10.100.100.2"
+      delegate_to: "{{ hostvars[groups['rabbitmq_all'][0]]['ansible_host'] }}"
       when: inventory_hostname == groups['cinder_all'][0]
     - name: Ensure rabbitmq user
       rabbitmq_user:
@@ -33,7 +33,7 @@
         read_priv: ".*"
         write_priv: ".*"
         state: "present"
-      delegate_to: "10.100.100.2"
+      delegate_to: "{{ hostvars[groups['rabbitmq_all'][0]]['ansible_host'] }}"
       when: inventory_hostname == groups['cinder_all'][0]
     - name: Create DB for service
       mysql_db:
@@ -44,6 +44,7 @@
         state: "present"
       delegate_to: "10.100.100.2"
       when: inventory_hostname == groups['cinder_all'][0]
+      delegate_to: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}"
       tags:
         - mysql-db-setup
     - name: Grant access to the DB for the service
@@ -58,12 +59,14 @@
         priv: "{{ cinder_galera_database }}.*:ALL"
       delegate_to: "10.100.100.2"
       when: inventory_hostname == groups['cinder_all'][0]
+      delegate_to: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}"
       with_items:
         - "localhost"
         - "%"
       tags:
         - mysql-db-setup
   roles:
-    - role: "{{ rolename | basename }}"
+    - role: "os_cinder"
   vars_files:
+    - common/test-vars.yml
     - test-vars.yml
diff --git a/tests/test-install-infra.yml b/tests/test-install-infra.yml
deleted file mode 100644
index 7b3acf0b..00000000
--- a/tests/test-install-infra.yml
+++ /dev/null
@@ -1,32 +0,0 @@
----
-# Copyright 2015, Rackspace US, Inc.
-#
-# 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.
-
-- name: Deploy infra services
-  hosts: service_all
-  user: root
-  gather_facts: true
-  roles:
-    - role: "rabbitmq_server"
-      rabbitmq_cookie_token: secrete
-    - role: "galera_server"
-      galera_root_password: secrete
-      galera_root_user: root
-      galera_innodb_buffer_pool_size: 512M
-      galera_innodb_log_buffer_size: 32M
-      galera_server_id: "{{ inventory_hostname | string_2_int }}"
-      galera_wsrep_node_name: "{{ inventory_hostname }}"
-      galera_wsrep_provider_options:
-        - { option: "gcache.size", value: "32M" }
-      galera_server_id: "{{ inventory_hostname | string_2_int }}"
diff --git a/tests/test-install-keystone.yml b/tests/test-install-keystone.yml
deleted file mode 100644
index fd3fec26..00000000
--- a/tests/test-install-keystone.yml
+++ /dev/null
@@ -1,65 +0,0 @@
----
-# Copyright 2015, Rackspace US, Inc.
-#
-# 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.
-
-- name: Deploy keystone
-  hosts: keystone_all
-  user: root
-  gather_facts: true
-  pre_tasks:
-    - name: Ensure rabbitmq vhost
-      rabbitmq_vhost:
-        name: "{{ keystone_rabbitmq_vhost }}"
-        state: "present"
-      delegate_to: "10.100.100.2"
-      when: inventory_hostname == groups['keystone_all'][0]
-    - name: Ensure rabbitmq user
-      rabbitmq_user:
-        user: "{{ keystone_rabbitmq_userid }}"
-        password: "{{ keystone_rabbitmq_password }}"
-        vhost: "{{ keystone_rabbitmq_vhost }}"
-        configure_priv: ".*"
-        read_priv: ".*"
-        write_priv: ".*"
-        state: "present"
-      delegate_to: "10.100.100.2"
-      when: inventory_hostname == groups['keystone_all'][0]
-    - name: Create DB for service
-      mysql_db:
-        login_user: "root"
-        login_password: "secrete"
-        login_host: "{{ keystone_galera_address }}"
-        name: "{{ keystone_galera_database }}"
-        state: "present"
-      delegate_to: "10.100.100.2"
-      when: inventory_hostname == groups['keystone_all'][0]
-    - name: Grant access to the DB for the service
-      mysql_user:
-        login_user: "root"
-        login_password: "secrete"
-        login_host: "{{ keystone_galera_address }}"
-        name: "{{ keystone_galera_database }}"
-        password: "{{ keystone_container_mysql_password }}"
-        host: "{{ item }}"
-        state: "present"
-        priv: "{{ keystone_galera_database }}.*:ALL"
-      with_items:
-        - "localhost"
-        - "%"
-      delegate_to: "10.100.100.2"
-      when: inventory_hostname == groups['keystone_all'][0]
-  roles:
-    - role: os_keystone
-  vars_files:
-    - test-vars.yml
diff --git a/tests/test-prepare-containers.yml b/tests/test-prepare-containers.yml
deleted file mode 100644
index 914c17f1..00000000
--- a/tests/test-prepare-containers.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-# Copyright 2015, Rackspace US, Inc.
-#
-# 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.
-
-- name: Create test containers
-  hosts: all_containers
-  connection: local
-  gather_facts: false
-  roles:
-    - role: "lxc_container_create"
-      lxc_container_release: trusty
-      lxc_container_backing_store: dir
-      global_environment_variables:
-        PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-  post_tasks:
-    - name: Wait for ssh to be available
-      local_action:
-        module: wait_for
-        port: "{{ ansible_ssh_port | default('22') }}"
-        host: "{{ ansible_ssh_host | default(inventory_hostname) }}"
-        search_regex: OpenSSH
-        delay: 1
diff --git a/tests/test-prepare-host.yml b/tests/test-prepare-host.yml
deleted file mode 100644
index 1083f89d..00000000
--- a/tests/test-prepare-host.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-# Copyright 2015, Rackspace US, Inc.
-#
-# 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.
-
-- name: Perform basic LXC host setup
-  hosts: localhost
-  pre_tasks:
-    # Make sure OS does not have a stale package cache.
-    - name: Update apt cache
-      apt:
-        update_cache: yes
-      when: ansible_os_family == 'Debian'
-    - name: Ensure root's new public ssh key is in authorized_keys
-      authorized_key:
-        user: root
-        key: "{{ hostvars['localhost']['lxc_container_ssh_key'] }}"
-        manage_dir: no
-    - set_fact:
-        lxc_container_ssh_key: "{{ hostvars['localhost']['lxc_container_ssh_key'] }}"
-    - name: Check if this is an OpenStack-CI nodepool instance
-      stat:
-        path: /etc/nodepool/provider
-      register: nodepool
-    - name: Set the files to copy into the container cache for OpenStack-CI instances
-      set_fact:
-        lxc_container_cache_files:
-          - { src: '/etc/pip.conf', dest: '/etc/pip.conf' }
-      when: nodepool.stat.exists | bool
-  roles:
-    - role: "lxc_hosts"
-      lxc_net_address: 10.100.100.1
-      lxc_net_dhcp_range: 10.100.100.8,10.100.100.253
-      lxc_net_bridge: lxcbr0
-      lxc_kernel_options:
-        - { key: 'fs.inotify.max_user_instances', value: 1024 }
diff --git a/tests/test-prepare-keys.yml b/tests/test-prepare-keys.yml
deleted file mode 100644
index d9c96361..00000000
--- a/tests/test-prepare-keys.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-# Copyright 2015, Rackspace US, Inc.
-#
-# 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.
-
-# NOTE: we use become_user because setting become: no or become: false
-#       doesn't seem to override the ansible_become=true in the
-#       inventory
-- name: Create ssh key pairs for use with containers
-  hosts: localhost
-  become_user: "{{ ansible_ssh_user }}"
-  pre_tasks:
-    - name: Create ssh key pair for root
-      user:
-        name: "{{ ansible_ssh_user }}"
-        generate_ssh_key: "yes"
-        ssh_key_bits: 2048
-        ssh_key_file: ".ssh/id_rsa"
-    - name: Get the calling user's key
-      command: cat ~/.ssh/id_rsa.pub
-      register: key_get
-    - set_fact:
-        lxc_container_ssh_key: "{{ key_get.stdout }}"
diff --git a/tests/test-vars.yml b/tests/test-vars.yml
index 1f7729ea..37dcac33 100644
--- a/tests/test-vars.yml
+++ b/tests/test-vars.yml
@@ -3,73 +3,40 @@ cinder_backends:
     volume_group: cinder-volumes
     volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver
     volume_backend_name: LVM_iSCSI
+cinder_default_volume_type: lvm
+
 cinder_container_mysql_password: "SuperSecrete"
 cinder_developer_mode: true
-cinder_galera_address: 10.100.100.2
+cinder_galera_address: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}"
 cinder_git_install_branch: master
 cinder_glance_api_servers: "http://glance_server:9292"
 cinder_profiler_hmac_key: "secrete"
-cinder_rabbitmq_port: 5672
-cinder_rabbitmq_servers: 10.100.100.2
-cinder_rabbitmq_use_ssl: False
-cinder_rabbitmq_password: "secrete"
+cinder_rabbitmq_port: "{{ rabbitmq_port }}"
+cinder_rabbitmq_servers: "{{ hostvars[groups['rabbitmq_all'][0]]['ansible_host'] }}"
+cinder_rabbitmq_use_ssl: "{{ rabbitmq_use_ssl }}"
+cinder_rabbitmq_password: "{{ rabbitmq_password }}"
 cinder_rabbitmq_userid: cinder
 cinder_rabbitmq_vhost: /cinder
 cinder_galera_user: cinder
 cinder_galera_database: cinder
 cinder_requirements_git_install_branch: master
 cinder_service_password: "secrete"
-cinder_default_volume_type: lvm
 cinder_venv_tag: "testing"
-debug: true
-external_lb_vip_address: 10.100.100.3
-galera_client_drop_config_file: false
-galera_root_user: "root"
-galera_root_password: "secrete"
-internal_lb_vip_address: 10.100.100.3
-keystone_admin_tenant_name: admin
-keystone_admin_user_name: admin
-keystone_auth_admin_password: "SuperSecretePassword"
-keystone_container_mysql_password: "SuperSecrete"
-keystone_developer_mode: true
-keystone_galera_address: 10.100.100.2
-keystone_galera_database: keystone
-keystone_git_install_branch: master
-keystone_rabbitmq_password: "secrete"
-keystone_rabbitmq_port: 5672
-keystone_rabbitmq_servers: 10.100.100.2
-keystone_rabbitmq_use_ssl: False
-keystone_rabbitmq_userid: keystone
-keystone_rabbitmq_vhost: /keystone
-keystone_requirements_git_install_branch: master
-keystone_service_adminuri: "http://{{ internal_lb_vip_address }}:35357"
-keystone_service_adminuri_insecure: false
-keystone_service_adminurl: "{{ keystone_service_adminuri }}/v3"
-keystone_service_internaluri: "http://{{ internal_lb_vip_address }}:5000"
-keystone_service_internaluri_insecure: false
-keystone_service_internalurl: "{{ keystone_service_internaluri }}/v3"
-keystone_service_password: "secrete"
-keystone_service_region: RegionOne
-keystone_venv_tag: "testing"
-memcached_encryption_key: "secrete"
-memcached_servers: 127.0.0.1
-openrc_os_auth_url: "{{ keystone_service_internalurl }}"
-openrc_os_domain_name: "Default"
-openrc_os_password: "{{ keystone_auth_admin_password }}"
-tempest_developer_mode: True
-tempest_git_install_branch: master
-tempest_venv_tag: "{{ tempest_git_install_branch }}"
-# tempest_venv_bin is the same as the default in os_tempest role, but we set
-# it again here so we can refer to it in test-cinder-functional.yml
-tempest_venv_bin: "/opt/tempest_{{ tempest_venv_tag }}/bin"
-tempest_log_dir: "/var/log/"
-tempest_main_group: cinder_all
-tempest_service_available_aodh: False
-tempest_service_available_ceilometer: False
-tempest_service_available_cinder: True
-tempest_service_available_glance: False
-tempest_service_available_heat: False
-tempest_service_available_horizon: False
-tempest_service_available_neutron: False
-tempest_service_available_nova: False
-tempest_service_available_swift: False
+
+cinder_service_port: 8776
+cinder_service_proto: http
+cinder_service_publicuri: "{{ cinder_service_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_port }}"
+cinder_service_publicurl: "{{ cinder_service_publicuri }}/v1/%(tenant_id)s"
+cinder_service_adminuri: "{{ cinder_service_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_port }}"
+cinder_service_adminurl: "{{ cinder_service_adminuri }}/v1/%(tenant_id)s"
+cinder_service_internaluri: "{{ cinder_service_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_port }}"
+cinder_service_internalurl: "{{ cinder_service_internaluri }}/v1/%(tenant_id)s"
+
+cinder_service_v2_port: 8776
+cinder_service_v2_proto: http
+cinder_service_v2_publicuri: "{{ cinder_service_v2_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_v2_port }}"
+cinder_service_v2_publicurl: "{{ cinder_service_publicuri }}/v2/%(tenant_id)s"
+cinder_service_v2_adminuri: "{{ cinder_service_v2_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_v2_port }}"
+cinder_service_v2_adminurl: "{{ cinder_service_adminuri }}/v2/%(tenant_id)s"
+cinder_service_v2_internaluri: "{{ cinder_service_v2_proto }}://{{ hostvars[groups['cinder_api'][0]]['ansible_host'] }}:{{ cinder_service_v2_port }}"
+cinder_service_v2_internalurl: "{{ cinder_service_internaluri }}/v2/%(tenant_id)s"
\ No newline at end of file
diff --git a/tests/test.yml b/tests/test.yml
index b4363e40..977fcb68 100644
--- a/tests/test.yml
+++ b/tests/test.yml
@@ -13,29 +13,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Prepare the user ssh keys
-- include: test-prepare-keys.yml
-
-# Prepare the host
-- include: test-prepare-host.yml
+# Setup the host
+- include: common/test-setup-host.yml
 
 # Prepare the cinder-volumes VG
 - include: test-prepare-vg.yml
 
-# Prepare the containers
-- include: test-prepare-containers.yml
-
 # Install RabbitMQ/MariaDB
-- include: test-install-infra.yml
+- include: common/test-install-infra.yml
 
 # Install Keystone
-- include: test-install-keystone.yml
+- include: common/test-install-keystone.yml
 
 # Install Cinder
 - include: test-install-cinder.yml
 
 # Install Tempest
-- include: test-install-tempest.yml
+- include: common/test-install-tempest.yml
 
 # Test Cinder
 - include: test-cinder-functional.yml
diff --git a/tox.ini b/tox.ini
index fbac1d9b..6c4310b0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -22,12 +22,11 @@ passenv =
     NO_PROXY
 whitelist_externals =
     bash
-    git
-    rm
-    wget
 setenv =
-    VIRTUAL_ENV={envdir}
     PYTHONUNBUFFERED=1
+    ROLE_NAME=os_cinder
+    VIRTUAL_ENV={envdir}
+    WORKING_DIR={toxinidir}
 
 
 [testenv:docs]
@@ -53,17 +52,17 @@ commands =
     {posargs}
 
 
+[testenv:tests_clone]
+commands =
+    bash -c "if [ ! -d "{toxinidir}/tests/common" ]; then \
+               git clone https://git.openstack.org/openstack/openstack-ansible-tests {toxinidir}/tests/common; \
+             fi"
+
+
 [testenv:pep8]
 commands =
-    # Run hacking/flake8 check for all python files
-    bash -c "grep --recursive --binary-files=without-match \
-        --files-with-match '^.!.*python$' \
-        --exclude-dir .eggs \
-        --exclude-dir .git \
-        --exclude-dir .tox \
-        --exclude-dir *.egg-info \
-        --exclude-dir doc \
-        {toxinidir} | xargs flake8 --verbose"
+    {[testenv:tests_clone]commands}
+    bash -c "{toxinidir}/tests/common/test-pep8.sh"
 
 
 [flake8]
@@ -76,64 +75,27 @@ ignore=F403
 
 [testenv:bashate]
 commands =
-    # Run bashate check for all bash scripts
-    # Ignores the following rules:
-    #     E003: Indent not multiple of 4 (we prefer to use multiples of 2)
-    #     E006: Line longer than 79 columns (as many scripts use jinja
-    #           templating, this is very difficult)
-    #     E040: Syntax error determined using `bash -n` (as many scripts
-    #           use jinja templating, this will often fail and the syntax
-    #           error will be discovered in execution anyway)
-    bash -c "grep --recursive --binary-files=without-match \
-        --files-with-match '^.!.*\(ba\)\?sh$' \
-        --exclude-dir .tox \
-        --exclude-dir .git \
-        {toxinidir} | xargs bashate --error . --verbose --ignore=E003,E006,E040"
+    {[testenv:tests_clone]commands}
+    bash -c "{toxinidir}/tests/common/test-bashate.sh"
 
 
 [testenv:ansible]
 deps =
     {[testenv]deps}
-    ansible==1.9.4
-    ansible-lint>=2.7.0,<3.0.0
-setenv =
-    {[testenv]setenv}
-    ANSIBLE_HOST_KEY_CHECKING = False
-    ANSIBLE_SSH_CONTROL_PATH = /tmp/%%h-%%r
-    # TODO (odyssey4me) These are only here as they are non-standard folder
-    # names for Ansible 1.9.x. We are using the standard folder names for
-    # Ansible v2.x. We can remove this when we move to Ansible 2.x.
-    ANSIBLE_ACTION_PLUGINS = {homedir}/.ansible/plugins/action
-    ANSIBLE_CALLBACK_PLUGINS = {homedir}/.ansible/plugins/callback
-    ANSIBLE_FILTER_PLUGINS = {homedir}/.ansible/plugins/filter
-    ANSIBLE_LOOKUP_PLUGINS = {homedir}/.ansible/plugins/lookup
-    # This is required as the default is the current path or a path specified
-    # in ansible.cfg
-    ANSIBLE_LIBRARY = {homedir}/.ansible/plugins/library
-    # This is required as the default is '/etc/ansible/roles' or a path
-    # specified in ansible.cfg
-    ANSIBLE_ROLES_PATH = {homedir}/.ansible/roles:{toxinidir}/..
+    -rhttp://git.openstack.org/cgit/openstack/openstack-ansible-tests/plain/test-ansible-deps.txt
 commands =
-    rm -rf {homedir}/.ansible/plugins
-    git clone https://git.openstack.org/openstack/openstack-ansible-plugins \
-              {homedir}/.ansible/plugins
-    rm -rf {homedir}/.ansible/roles
-    ansible-galaxy install \
-                   --role-file={toxinidir}/tests/ansible-role-requirements.yml \
-                   --force
+    {[testenv:tests_clone]commands}
+    bash -c "{toxinidir}/tests/common/test-ansible-env-prep.sh"
 
 
 [testenv:ansible-syntax]
 deps =
     {[testenv:ansible]deps}
-setenv =
-    {[testenv:ansible]setenv}
 commands =
     {[testenv:ansible]commands}
     ansible-playbook -i {toxinidir}/tests/inventory \
                      --syntax-check \
                      --list-tasks \
-                     -e "rolename={toxinidir}" \
                      {toxinidir}/tests/test.yml
 
 
@@ -145,6 +107,19 @@ commands =
     ansible-lint {toxinidir}
 
 
+[testenv:func_base]
+# NOTE(odyssey4me): this target does not use constraints because
+# it doesn't work in OpenStack-CI yet. Once that's fixed, we can
+# drop the install_command.
+install_command =
+    pip install -U --force-reinstall {opts} {packages}
+
+
+[testenv:func_logs]
+commands =
+    bash -c "{toxinidir}/tests/common/test-log-collect.sh"
+
+
 [testenv:functional]
 # Ignore_errors is set to true so that the logs are collected at the
 #  end of the run. This will not produce a false positive. Any
@@ -155,28 +130,21 @@ ignore_errors = True
 # it doesn't work in OpenStack-CI yet. Once that's fixed, we can
 # drop the install_command.
 install_command =
-    pip install -U --force-reinstall {opts} {packages}
+    {[testenv:func_base]install_command}
 deps =
     {[testenv:ansible]deps}
-setenv =
-    {[testenv:ansible]setenv}
 commands =
     {[testenv:ansible]commands}
     ansible-playbook -i {toxinidir}/tests/inventory \
-                     -e "rolename={toxinidir}" \
                      -e "install_test_packages=True" \
+                     -e @{toxinidir}/tests/test-vars.yml \
                      {toxinidir}/tests/test.yml -vvvv
-    bash -c 'mkdir -p {toxinidir}/logs'
-    bash -c 'rsync --archive --verbose --ignore-errors /var/log/ /openstack/log/ {toxinidir}/logs/ || true'
-    bash -c 'find "{toxinidir}/logs/" -type f | sed "p;s|$|.txt|" | xargs -n2 mv'
-    bash -c 'command gzip --best --recursive "{toxinidir}/logs/"'
+    {[testenv:func_logs]commands}
 
 
 [testenv:linters]
 deps =
     {[testenv:ansible]deps}
-setenv =
-    {[testenv:ansible]setenv}
 commands =
     {[testenv:pep8]commands}
     {[testenv:bashate]commands}
diff --git a/vars/redhat-7.yml b/vars/redhat-7.yml
index ad09daaa..fb489c95 100644
--- a/vars/redhat-7.yml
+++ b/vars/redhat-7.yml
@@ -25,6 +25,7 @@ cinder_distro_packages:
   - kmod-devel
   - kmod-libs
   - zlib-devel
+  - git
 
 cinder_volume_distro_packages:
   - qemu-img