Merge "Skip some tests in "network.admin.test_ports" if nova is not enabled"
diff --git a/.zuul.yaml b/.zuul.yaml
index 2f5d7da..4ca14ad 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -7,12 +7,12 @@
       This Tempest job provides the base for both the single and multi-node
       test setup. To run a multi-node test inherit from devstack-tempest and
       set the nodeset to a multi-node one.
-    required-projects:
+    required-projects: &base_required-projects
       - opendev.org/openstack/tempest
     timeout: 7200
-    roles:
+    roles: &base_roles
       - zuul: opendev.org/openstack/devstack
-    vars:
+    vars: &base_vars
       devstack_services:
         tempest: true
       devstack_local_conf:
@@ -53,37 +53,37 @@
     name: devstack-tempest-ipv6
     parent: devstack-ipv6
     description: |
-      Base Tempest IPv6 job.
-    required-projects:
-      - opendev.org/openstack/tempest
+      Base Tempest IPv6 job. This job is derived from 'devstack-ipv6'
+      which set the IPv6-only setting for OpenStack services. As part of
+      run phase, this job will verify the IPv6 setting and check the services
+      endpoints and listen addresses are IPv6. Basically it will run the script
+      ./tool/verify-ipv6-only-deployments.sh
+
+      Child jobs of this job can run their own set of tests and can
+      add post-run playebooks to extend the IPv6 verification specific
+      to their deployed services.
+      Check the wiki page for more details about project jobs setup
+      - https://wiki.openstack.org/wiki/Goal-IPv6-only-deployments-and-testing
+    required-projects: *base_required-projects
     timeout: 7200
-    roles:
-      - zuul: opendev.org/openstack/devstack
-    vars:
-      devstack_services:
-        tempest: true
-      devstack_local_conf:
-        test-config:
-          $TEMPEST_CONFIG:
-            compute:
-              min_compute_nodes: "{{ groups['compute'] | default(['controller']) | length }}"
-      test_results_stage_name: test_results
-      zuul_copy_output:
-        '{{ devstack_base_dir }}/tempest/etc/tempest.conf': logs
-        '{{ devstack_base_dir }}/tempest/etc/accounts.yaml': logs
-        '{{ devstack_base_dir }}/tempest/tempest.log': logs
-        '{{ stage_dir }}/{{ test_results_stage_name }}.subunit': logs
-        '{{ stage_dir }}/{{ test_results_stage_name }}.html': logs
-        '{{ stage_dir }}/stackviz': logs
-      extensions_to_txt:
-        conf: true
-        log: true
-        yaml: true
-        yml: true
-    run: playbooks/devstack-tempest.yaml
+    roles: *base_roles
+    vars: *base_vars
+    run: playbooks/devstack-tempest-ipv6.yaml
     post-run: playbooks/post-tempest.yaml
 
 - job:
+    name: tempest-ipv6-only
+    parent: devstack-tempest-ipv6
+    # This currently works from stable/pike on.
+    branches: ^(?!stable/ocata).*$
+    description: |
+      Integration test of IPv6-only deployments. This job runs
+      smoke and IPv6 relates tests only. Basic idea is to test
+      whether OpenStack Services listen on IPv6 addrress or not.
+    vars:
+      tox_envlist: ipv6-only
+
+- job:
     name: tempest-full
     parent: devstack-tempest
     # This currently works from stable/pike on.
@@ -439,12 +439,6 @@
     override-checkout: stable/queens
 
 - job:
-    name: tempest-full-pike
-    parent: tempest-full
-    nodeset: openstack-single-node-xenial
-    override-checkout: stable/pike
-
-- job:
     name: tempest-tox-plugin-sanity-check
     parent: tox
     description: |
@@ -715,14 +709,12 @@
             irrelevant-files: *tempest-irrelevant-files
         - tempest-full-queens-py3:
             irrelevant-files: *tempest-irrelevant-files
-        - tempest-full-pike:
-            irrelevant-files: *tempest-irrelevant-files
         - tempest-multinode-full:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-multinode-full-py3:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-tox-plugin-sanity-check:
-            irrelevant-files:
+            irrelevant-files: &tempest-irrelevant-files-2
               - ^.*\.rst$
               - ^doc/.*$
               - ^etc/.*$
@@ -731,6 +723,8 @@
               - ^tempest/hacking/.*$
               - ^tempest/tests/.*$
               # tools/ is not here since this relies on a script in tools/.
+        - tempest-ipv6-only:
+            irrelevant-files: *tempest-irrelevant-files-2
         - tempest-slow:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-slow-py3:
@@ -771,6 +765,7 @@
         - tempest-full-test-account-no-admin-py3:
             voting: false
             irrelevant-files: *tempest-irrelevant-files
+        - openstack-tox-bashate
     gate:
       jobs:
         - tempest-slow-py3:
@@ -783,6 +778,8 @@
             irrelevant-files: *tempest-irrelevant-files
         - grenade-py3:
             irrelevant-files: *tempest-irrelevant-files
+        - tempest-ipv6-only:
+            irrelevant-files: *tempest-irrelevant-files-2
     experimental:
       jobs:
         - tempest-cinder-v2-api:
@@ -811,7 +808,6 @@
         - tempest-full-rocky-py3
         - tempest-full-queens
         - tempest-full-queens-py3
-        - tempest-full-pike
     periodic:
       jobs:
         - tempest-all
diff --git a/playbooks/devstack-tempest-ipv6.yaml b/playbooks/devstack-tempest-ipv6.yaml
new file mode 100644
index 0000000..5f72345
--- /dev/null
+++ b/playbooks/devstack-tempest-ipv6.yaml
@@ -0,0 +1,24 @@
+# Changes that run through devstack-tempest-ipv6 are likely to have an impact on
+# the devstack part of the job, so we keep devstack in the main play to
+# avoid zuul retrying on legitimate failures.
+- hosts: all
+  roles:
+    - orchestrate-devstack
+
+# We run tests only on one node, regardless how many nodes are in the system
+- hosts: tempest
+  environment:
+    # This enviroment variable is used by the optional tempest-gabbi
+    # job provided by the gabbi-tempest plugin. It can be safely ignored
+    # if that plugin is not being used.
+    GABBI_TEMPEST_PATH: "{{ gabbi_tempest_path | default('') }}"
+  roles:
+    - setup-tempest-run-dir
+    - setup-tempest-data-dir
+    - acl-devstack-files
+    # Verify the IPv6-only deployments. This role will perform check for
+    # IPv6 only env for example Devstack IPv6 settings and services listen
+    # address is IPv6 etc. This is invoked before tests are run so that we can
+    # fail early if anything missing the IPv6 settings or deployments.
+    - ipv6-only-deployments-verification
+    - run-tempest
diff --git a/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
index 092014e..8787e0c 100644
--- a/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
+++ b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
@@ -4,5 +4,5 @@
     Adds subunit-describe-calls. A parser for subunit streams to determine what
     REST API calls are made inside of a test and in what order they are called.
 
-      * Input can be piped in or a file can be specified
-      * Output is shortened for stdout, the output file has more information
+    * Input can be piped in or a file can be specified
+    * Output is shortened for stdout, the output file has more information
diff --git a/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
index f9173a0..b857db8 100644
--- a/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
+++ b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
@@ -6,8 +6,8 @@
     so the other projects can use these modules as stable libraries without
     any maintenance changes.
 
-      * endpoints_client(v2)
-      * roles_client(v2)
-      * services_client(v2)
-      * tenants_client(v2)
-      * users_client(v2)
+    * endpoints_client(v2)
+    * roles_client(v2)
+    * services_client(v2)
+    * tenants_client(v2)
+    * users_client(v2)
diff --git a/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
index 1fa4ddd..492aac8 100644
--- a/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
+++ b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
@@ -6,10 +6,10 @@
     so the other projects can use these modules as stable libraries
     without any maintenance changes.
 
-      * image_members_client(v1)
-      * images_client(v1)
-      * image_members_client(v2)
-      * images_client(v2)
-      * namespaces_client(v2)
-      * resource_types_client(v2)
-      * schemas_client(v2)
+    * image_members_client(v1)
+    * images_client(v1)
+    * image_members_client(v2)
+    * images_client(v2)
+    * namespaces_client(v2)
+    * resource_types_client(v2)
+    * schemas_client(v2)
diff --git a/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
index 3ec8b56..6e08743 100644
--- a/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
+++ b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
@@ -6,8 +6,8 @@
     so the other projects can use these modules as stable libraries without
     any maintenance changes.
 
-     * endpoints_client(v3)
-     * policies_client (v3)
-     * regions_client(v3)
-     * services_client(v3)
-     * projects_client(v3)
+    * endpoints_client(v3)
+    * policies_client (v3)
+    * regions_client(v3)
+    * services_client(v3)
+    * projects_client(v3)
diff --git a/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
index cf504ad..32cd182 100644
--- a/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
+++ b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
@@ -6,13 +6,13 @@
     so the other projects can use these modules as stable libraries
     without any maintenance changes.
 
-      * availability_zone_client(v1)
-      * availability_zone_client(v2)
-      * extensions_client(v1)
-      * extensions_client(v2)
-      * hosts_client(v1)
-      * hosts_client(v2)
-      * quotas_client(v1)
-      * quotas_client(v2)
-      * services_client(v1)
-      * services_client(v2)
+    * availability_zone_client(v1)
+    * availability_zone_client(v2)
+    * extensions_client(v1)
+    * extensions_client(v2)
+    * hosts_client(v1)
+    * hosts_client(v2)
+    * quotas_client(v1)
+    * quotas_client(v2)
+    * services_client(v1)
+    * services_client(v2)
diff --git a/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
index 9e828f6..a0de2c3 100644
--- a/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
+++ b/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml
@@ -5,11 +5,11 @@
     Add new service clients to the library interface so the other projects can use these modules as stable libraries without
     any maintenance changes.
 
-      * identity_client(v2)
-      * groups_client(v3)
-      * trusts_client(v3)
-      * users_client(v3)
-      * identity_client(v3)
-      * roles_client(v3)
-      * inherited_roles_client(v3)
-      * credentials_client(v3)
+    * identity_client(v2)
+    * groups_client(v3)
+    * trusts_client(v3)
+    * users_client(v3)
+    * identity_client(v3)
+    * roles_client(v3)
+    * inherited_roles_client(v3)
+    * credentials_client(v3)
diff --git a/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
index 7e40fd4..6346156 100644
--- a/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
+++ b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
@@ -5,5 +5,5 @@
     http://developer.openstack.org/api-ref/image/v2/metadefs-index.html,
     there are some apis are not included, add them.
 
-      * namespace_properties_client(v2)
+    * namespace_properties_client(v2)
 
diff --git a/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
index eaab1f0..a4e5791 100644
--- a/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
+++ b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
@@ -5,6 +5,6 @@
     http://developer.openstack.org/api-ref/image/v2/metadefs-index.html,
     there are some apis are not included, add them.
 
-      * namespace_objects_client(v2)
-      * namespace_tags_client(v2)
+    * namespace_objects_client(v2)
+    * namespace_tags_client(v2)
 
diff --git a/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
index 87a6af9..85e5f5f 100644
--- a/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
+++ b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
@@ -3,10 +3,10 @@
   - |
     Allow to specify new domain parameters:
 
-    * `user_domain_name`
-    * `user_domain_id`
-    * `project_domain_name`
-    * `project_domain_id`
+    * ``user_domain_name``
+    * ``user_domain_id``
+    * ``project_domain_name``
+    * ``project_domain_id``
 
     for CLIClient class, whose values will be substituted to
     ``--os-user-domain-name``, ``--os-user-domain-id``,
diff --git a/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml b/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml
index 6977e12..7940846 100644
--- a/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml
+++ b/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml
@@ -1,12 +1,12 @@
 ---
-prelude: >
+prelude: |
     This is an intermediate release during the Train development cycle to
     mark the end of support for Pike in Tempest.
     After this release, Tempest will support below OpenStack Releases:
 
-      * Stein
-      * Rocky
-      * Queens
+    * Stein
+    * Rocky
+    * Queens
 
     Current development of Tempest is for OpenStack Train development
     cycle.
diff --git a/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
index 2bba952..37eeec5 100644
--- a/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
+++ b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
@@ -6,6 +6,6 @@
     other projects can use these modules as stable libraries
     without any maintenance changes.
 
-      * account_client
-      * container_client
-      * object_client
+    * account_client
+    * container_client
+    * object_client
diff --git a/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml b/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
index 72b8e26..00829b9 100644
--- a/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
+++ b/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
@@ -6,5 +6,5 @@
     other projects can use these modules as stable libraries
     without any maintenance changes.
 
-      * bulk_middleware_client
-      * capabilities_client
+    * bulk_middleware_client
+    * capabilities_client
diff --git a/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
index e9c77a6..8406be6 100644
--- a/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
+++ b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
@@ -1,12 +1,12 @@
 ---
-prelude: >
+prelude: |
     This release is to tag the Tempest for OpenStack Rocky release.
     After this release, Tempest will support below OpenStack Releases:
 
-      * Rocky
-      * Queens
-      * Pike
-      * Ocata
+    * Rocky
+    * Queens
+    * Pike
+    * Ocata
 
     Current development of Tempest is for OpenStack Stein development
     cycle. Every Tempest commit is also tested against master during
diff --git a/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml b/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
index 212cf7d..c3537fc 100644
--- a/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
+++ b/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
@@ -1,14 +1,14 @@
 ---
-prelude: >
+prelude: |
     This release is to tag the Tempest for OpenStack Stein release.
     This release marks the start of Stein release support in Tempest and
     the end of support for Ocata in Tempest.
     After this release, Tempest will support below OpenStack Releases:
 
-      * Stein
-      * Rocky
-      * Queens
-      * Pike
+    * Stein
+    * Rocky
+    * Queens
+    * Pike
 
     Current development of Tempest is for OpenStack Train development
     cycle. Every Tempest commit is also tested against master during
diff --git a/roles/ipv6-only-deployments-verification/README.rst b/roles/ipv6-only-deployments-verification/README.rst
new file mode 100644
index 0000000..400a8da
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/README.rst
@@ -0,0 +1,16 @@
+Verify the IPv6-only deployments
+
+This role needs to be invoked from a playbook that
+run tests. This role verifies the IPv6 setting on
+devstack side and devstack deploy services on IPv6.
+This role is invoked before tests are run so that
+if any missing IPv6 setting or deployments can fail
+the job early.
+
+
+**Role Variables**
+
+.. zuul:rolevar:: devstack_base_dir
+   :default: /opt/stack
+
+   The devstack base directory.
diff --git a/roles/ipv6-only-deployments-verification/defaults/main.yaml b/roles/ipv6-only-deployments-verification/defaults/main.yaml
new file mode 100644
index 0000000..fea05c8
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/defaults/main.yaml
@@ -0,0 +1 @@
+devstack_base_dir: /opt/stack
diff --git a/roles/ipv6-only-deployments-verification/tasks/main.yaml b/roles/ipv6-only-deployments-verification/tasks/main.yaml
new file mode 100644
index 0000000..d73c79c
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/tasks/main.yaml
@@ -0,0 +1,4 @@
+- name: Verify the ipv6-only deployments
+  become: true
+  become_user: stack
+  shell: "{{ devstack_base_dir }}/tempest/tools/verify-ipv6-only-deployments.sh"
diff --git a/tempest/lib/services/network/floating_ips_client.py b/tempest/lib/services/network/floating_ips_client.py
index 893bcc8..a63150b 100644
--- a/tempest/lib/services/network/floating_ips_client.py
+++ b/tempest/lib/services/network/floating_ips_client.py
@@ -23,7 +23,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-floating-ip
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-floating-ip
         """
         uri = '/floatingips'
         post_data = {'floatingip': kwargs}
@@ -34,7 +34,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-floating-ip
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-floating-ip
         """
         uri = '/floatingips/%s' % floatingip_id
         post_data = {'floatingip': kwargs}
@@ -45,7 +45,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-floating-ip-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-floating-ip-details
         """
         uri = '/floatingips/%s' % floatingip_id
         return self.show_resource(uri, **fields)
@@ -59,7 +59,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-floating-ips
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-floating-ips
         """
         uri = '/floatingips'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/metering_labels_client.py b/tempest/lib/services/network/metering_labels_client.py
index be19b58..80ed51f 100644
--- a/tempest/lib/services/network/metering_labels_client.py
+++ b/tempest/lib/services/network/metering_labels_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-metering-label
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-metering-label
         """
         uri = '/metering/metering-labels'
         post_data = {'metering_label': kwargs}
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-metering-label-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-metering-label-details
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.show_resource(uri, **fields)
@@ -41,7 +41,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#delete-metering-label
+        https://docs.openstack.org/api-ref/network/v2/index.html#delete-metering-label
         """
         uri = '/metering/metering-labels/%s' % metering_label_id
         return self.delete_resource(uri)
@@ -51,7 +51,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-metering-labels
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-metering-labels
         """
         uri = '/metering/metering-labels'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/networks_client.py b/tempest/lib/services/network/networks_client.py
index 4043558..f0e735e 100644
--- a/tempest/lib/services/network/networks_client.py
+++ b/tempest/lib/services/network/networks_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-network
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-network
         """
         uri = '/networks'
         post_data = {'network': kwargs}
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-network
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-network
         """
         uri = '/networks/%s' % network_id
         post_data = {'network': kwargs}
@@ -42,7 +42,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-network-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-network-details
         """
         uri = '/networks/%s' % network_id
         return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-networks
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-networks
         """
         uri = '/networks'
         return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#bulk-create-networks
+        https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-networks
         """
         uri = '/networks'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index aad8515..d77b62f 100644
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -21,7 +21,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-port
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-port
         """
         uri = '/ports'
         post_data = {'port': kwargs}
@@ -32,7 +32,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-port
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-port
         """
         uri = '/ports/%s' % port_id
         post_data = {'port': kwargs}
@@ -43,7 +43,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-port-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-port-details
         """
         uri = '/ports/%s' % port_id
         return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#delete-port
+        https://docs.openstack.org/api-ref/network/v2/index.html#delete-port
         """
         uri = '/ports/%s' % port_id
         return self.delete_resource(uri)
@@ -63,7 +63,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-ports
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-ports
         """
         uri = '/ports'
         return self.list_resources(uri, **filters)
@@ -73,7 +73,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#bulk-create-ports
+        https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-ports
         """
         uri = '/ports'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/routers_client.py b/tempest/lib/services/network/routers_client.py
index 1ab9300..2af487f 100644
--- a/tempest/lib/services/network/routers_client.py
+++ b/tempest/lib/services/network/routers_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-router
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-router
         """
         post_body = {'router': kwargs}
         uri = '/routers'
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-router
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-router
         """
         uri = '/routers/%s' % router_id
         update_body = {'router': kwargs}
@@ -42,7 +42,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-router-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-router-details
         """
         uri = '/routers/%s' % router_id
         return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-routers
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-routers
         """
         uri = '/routers'
         return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#add-interface-to-router
+        https://docs.openstack.org/api-ref/network/v2/index.html#add-interface-to-router
         """
         uri = '/routers/%s/add_router_interface' % router_id
         return self.update_resource(uri, kwargs)
@@ -76,7 +76,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#remove-interface-from-router
+        https://docs.openstack.org/api-ref/network/v2/index.html#remove-interface-from-router
         """
         uri = '/routers/%s/remove_router_interface' % router_id
         return self.update_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/security_group_rules_client.py b/tempest/lib/services/network/security_group_rules_client.py
index 15dfc2a..d62b05f 100644
--- a/tempest/lib/services/network/security_group_rules_client.py
+++ b/tempest/lib/services/network/security_group_rules_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-security-group-rule
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-security-group-rule
         """
         uri = '/security-group-rules'
         post_data = {'security_group_rule': kwargs}
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-security-group-rule
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-security-group-rule
         """
         uri = '/security-group-rules/%s' % security_group_rule_id
         return self.show_resource(uri, **fields)
@@ -45,7 +45,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-security-group-rules
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-security-group-rules
         """
         uri = '/security-group-rules'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/security_groups_client.py b/tempest/lib/services/network/security_groups_client.py
index 4664432..b641839 100644
--- a/tempest/lib/services/network/security_groups_client.py
+++ b/tempest/lib/services/network/security_groups_client.py
@@ -21,7 +21,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-security-group
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-security-group
         """
         uri = '/security-groups'
         post_data = {'security_group': kwargs}
@@ -32,7 +32,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-security-group
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         post_data = {'security_group': kwargs}
@@ -43,7 +43,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-security-group
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#delete-security-group
+        https://docs.openstack.org/api-ref/network/v2/index.html#delete-security-group
         """
         uri = '/security-groups/%s' % security_group_id
         return self.delete_resource(uri)
@@ -63,7 +63,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-security-groups
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-security-groups
         """
         uri = '/security-groups'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/segments_client.py b/tempest/lib/services/network/segments_client.py
index dfdc418..30e6b23 100644
--- a/tempest/lib/services/network/segments_client.py
+++ b/tempest/lib/services/network/segments_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/networking/v2/index.html#create-segment
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-segment
         """
         uri = '/segments'
         post_data = {'segment': kwargs}
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/networking/v2/index.html#update-segment
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-segment
         """
         uri = '/segments/%s' % segment_id
         post_data = {'segment': kwargs}
@@ -42,7 +42,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/networking/v2/index.html#show-segment
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-segment-details
         """
         uri = '/segments/%s' % segment_id
         return self.show_resource(uri, **fields)
@@ -57,7 +57,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        http://developer.openstack.org/api-ref/networking/v2/index.html#list-segments
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-segments
         """
         uri = '/segments'
         return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/subnetpools_client.py b/tempest/lib/services/network/subnetpools_client.py
index 1f6a464..635c449 100644
--- a/tempest/lib/services/network/subnetpools_client.py
+++ b/tempest/lib/services/network/subnetpools_client.py
@@ -22,7 +22,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-subnet-pools
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-subnet-pools
         """
         uri = '/subnetpools'
         return self.list_resources(uri, **filters)
@@ -32,7 +32,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-subnet-pool
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-subnet-pool
         """
         uri = '/subnetpools'
         post_data = {'subnetpool': kwargs}
@@ -43,7 +43,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-subnet-pool
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-subnet-pool
         """
         uri = '/subnetpools/%s' % subnetpool_id
         return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-subnet-pool
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-subnet-pool
         """
         uri = '/subnetpools/%s' % subnetpool_id
         post_data = {'subnetpool': kwargs}
diff --git a/tempest/lib/services/network/subnets_client.py b/tempest/lib/services/network/subnets_client.py
index 9753b86..00dd423 100644
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -20,7 +20,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#create-subnet
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-subnet
         """
         uri = '/subnets'
         post_data = {'subnet': kwargs}
@@ -31,7 +31,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#update-subnet
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-subnet
         """
         uri = '/subnets/%s' % subnet_id
         post_data = {'subnet': kwargs}
@@ -42,7 +42,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#show-subnet-details
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-subnet-details
         """
         uri = '/subnets/%s' % subnet_id
         return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#list-subnets
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-subnets
         """
         uri = '/subnets'
         return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
 
         For a full list of available parameters, please refer to the official
         API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#bulk-create-subnet
+        https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-subnet
         """
         uri = '/subnets'
         return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/tags_client.py b/tempest/lib/services/network/tags_client.py
index c1ad00b..71e17c7 100644
--- a/tempest/lib/services/network/tags_client.py
+++ b/tempest/lib/services/network/tags_client.py
@@ -25,7 +25,7 @@
         """Adds a tag on the resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#add-a-tag
+        https://docs.openstack.org/api-ref/network/v2/index.html#add-a-tag
         """
         uri = '/%s/%s/tags/%s' % (resource_type, resource_id, tag)
         return self.update_resource(
@@ -36,7 +36,7 @@
         """Confirm that a given tag is set on the resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#confirm-a-tag
+        https://docs.openstack.org/api-ref/network/v2/index.html#confirm-a-tag
         """
         # TODO(felipemonteiro): Use the "check_resource" method in
         # ``BaseNetworkClient`` once it has been implemented.
@@ -50,7 +50,7 @@
         """Replace all tags on the resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#replace-all-tags
+        https://docs.openstack.org/api-ref/network/v2/index.html#replace-all-tags
         """
         uri = '/%s/%s/tags' % (resource_type, resource_id)
         put_body = {"tags": tags}
@@ -60,7 +60,7 @@
         """Removes a tag on the resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#remove-a-tag
+        https://docs.openstack.org/api-ref/network/v2/index.html#remove-a-tag
         """
         uri = '/%s/%s/tags/%s' % (resource_type, resource_id, tag)
         return self.delete_resource(uri)
@@ -69,7 +69,7 @@
         """Removes all tags on the resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#remove-all-tags
+        https://docs.openstack.org/api-ref/network/v2/index.html#remove-all-tags
         """
         uri = '/%s/%s/tags' % (resource_type, resource_id)
         return self.delete_resource(uri)
@@ -78,7 +78,7 @@
         """Retrieves the tags for a resource.
 
         For more information, please refer to the official API reference:
-        https://docs.openstack.org/api-ref/networking/v2/index.html#obtain-tag-list
+        https://docs.openstack.org/api-ref/network/v2/index.html#obtain-tag-list
         """
         uri = '/%s/%s/tags' % (resource_type, resource_id)
         return self.list_resources(uri)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 2782119..af79ea0 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -70,7 +70,6 @@
             raise lib_exc.TimeoutException
 
     @decorators.attr(type='slow')
-    @decorators.skip_because(bug="1664793")
     @decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
@@ -91,6 +90,11 @@
         # create and add floating IP to server1
         ip_for_server = self.get_server_ip(server)
 
+        # Make sure the machine ssh-able before attaching the volume
+        self.get_remote_client(ip_for_server,
+                               private_key=keypair['private_key'],
+                               server=server)
+
         self.nova_volume_attach(server, volume)
         self._wait_for_volume_available_on_the_system(ip_for_server,
                                                       keypair['private_key'])
@@ -119,6 +123,13 @@
         # create and add floating IP to server_from_snapshot
         ip_for_snapshot = self.get_server_ip(server_from_snapshot)
 
+        # Make sure the machine ssh-able before attaching the volume
+        # Just a live machine is responding
+        # for device attache/detach as expected
+        self.get_remote_client(ip_for_snapshot,
+                               private_key=keypair['private_key'],
+                               server=server_from_snapshot)
+
         # attach volume2 to instance2
         self.nova_volume_attach(server_from_snapshot, volume_from_snapshot)
         self._wait_for_volume_available_on_the_system(ip_for_snapshot,
diff --git a/tools/format.sh b/tools/format.sh
index dec8f1c..ef5cc92 100755
--- a/tools/format.sh
+++ b/tools/format.sh
@@ -15,7 +15,8 @@
 
 # isort is not compatible with the default flake8 (H306), maybe flake8-isort
 # isort -rc -sl -fss ../tempest ../setup.py
-$AUTOPEP8 --exit-code --max-line-length=79 --experimental --in-place -r ../tempest ../setup.py
+$AUTOPEP8 --exit-code --max-line-length=79 --experimental --in-place \
+          -r ../tempest ../setup.py
 ERROR=$?
 
 if [[ $ERROR -eq 0 ]]; then
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
index 6e473b7..b6a7c77 100755
--- a/tools/generate-tempest-plugins-list.sh
+++ b/tools/generate-tempest-plugins-list.sh
@@ -61,7 +61,7 @@
     printf " ===\n"
 }
 
-function print_plugin_table() {
+function print_plugin_table {
     title_underline ${name_col_len}
     printf "%-3s %-${name_col_len}s %s\n" "SR" "Plugin Name" "URL"
     title_underline ${name_col_len}
diff --git a/tools/tempest-plugin-sanity.sh b/tools/tempest-plugin-sanity.sh
index b652369..a087a4c 100644
--- a/tools/tempest-plugin-sanity.sh
+++ b/tools/tempest-plugin-sanity.sh
@@ -47,7 +47,7 @@
 BLACKLIST="$(python tools/generate-tempest-plugins-list.py blacklist)"
 
 # Function to clone project using zuul-cloner or from git
-function clone_project() {
+function clone_project {
     if [ -e /usr/zuul-env/bin/zuul-cloner ]; then
         /usr/zuul-env/bin/zuul-cloner --cache-dir /opt/git \
         https://opendev.org \
@@ -61,7 +61,7 @@
 }
 
 # function to create virtualenv to perform sanity operation
-function prepare_workspace() {
+function prepare_workspace {
     SANITY_DIR=$(pwd)
     virtualenv -p python3 --clear "$SANITY_DIR"/.venv
     export TVENV="$SANITY_DIR/tools/with_venv.sh"
@@ -72,7 +72,7 @@
 }
 
 # Function to install project
-function install_project() {
+function install_project {
     "$TVENV" pip install "$SANITY_DIR"/"$1"
     # Check for test-requirements.txt file in a project then install it.
     if [ -e "$SANITY_DIR"/"$1"/test-requirements.txt ]; then
@@ -81,7 +81,7 @@
 }
 
 # Function to perform sanity checking on Tempest plugin
-function tempest_sanity() {
+function tempest_sanity {
     "$TVENV" tempest init "$SANITY_DIR"/tempest_sanity && \
     cd "$SANITY_DIR"/tempest_sanity && \
     "$TVENV" tempest list-plugins && \
@@ -100,7 +100,7 @@
 }
 
 # Function to run sanity check on each project
-function plugin_sanity_check() {
+function plugin_sanity_check {
     prepare_workspace && \
     clone_project "$1" && \
     install_project "$1" && \
diff --git a/tools/verify-ipv6-only-deployments.sh b/tools/verify-ipv6-only-deployments.sh
new file mode 100755
index 0000000..90807a3
--- /dev/null
+++ b/tools/verify-ipv6-only-deployments.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+#
+#
+# NOTE(gmann): This script is used in 'devstack-tempest-ipv6' zuul job to verify that
+# services are deployed on IPv6 properly or not. This will capture if any devstck or devstack
+# plugins are missing the required setting to listen on IPv6 address. This is run as part of
+# run phase of zuul job and before test run. Child job of 'devstack-tempest-ipv6'
+# can expand the IPv6 verification specific to project by defining the new post-run script which
+# will run along with this base script.
+# If there are more common verification for IPv6 then we can always extent this script.
+
+# Keep track of the DevStack directory
+TOP_DIR=$(cd $(dirname "$0")/../../devstack && pwd)
+source $TOP_DIR/stackrc
+source $TOP_DIR/openrc admin admin
+
+function verify_devstack_ipv6_setting {
+    local _service_host=$(echo $SERVICE_HOST | tr -d [])
+    local _host_ipv6=$(echo $HOST_IPV6 | tr -d [])
+    local _service_listen_address=$(echo $SERVICE_LISTEN_ADDRESS | tr -d [])
+    local _service_local_host=$(echo $SERVICE_LOCAL_HOST | tr -d [])
+    if [[ "$SERVICE_IP_VERSION" != 6 ]]; then
+        echo $SERVICE_IP_VERSION "SERVICE_IP_VERSION is not set to 6 which is must for devstack to deploy services with IPv6 address."
+        exit 1
+    fi
+    is_service_host_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_host'"))')
+    if [[ "$is_service_host_ipv6" != "True" ]]; then
+        echo $SERVICE_HOST "SERVICE_HOST is not ipv6 which means devstack cannot deploy services on IPv6 address."
+        exit 1
+    fi
+    is_host_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_host_ipv6'"))')
+    if [[ "$is_host_ipv6" != "True" ]]; then
+        echo $HOST_IPV6 "HOST_IPV6 is not ipv6 which means devstack cannot deploy services on IPv6 address."
+        exit 1
+    fi
+    is_service_listen_address=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_listen_address'"))')
+    if [[ "$is_service_listen_address" != "True" ]]; then
+        echo $SERVICE_LISTEN_ADDRESS "SERVICE_LISTEN_ADDRESS is not ipv6 which means devstack cannot deploy services on IPv6 address."
+        exit 1
+    fi
+    is_service_local_host=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_local_host'"))')
+    if [[ "$is_service_local_host" != "True" ]]; then
+        echo $SERVICE_LOCAL_HOST "SERVICE_LOCAL_HOST is not ipv6 which means devstack cannot deploy services on IPv6 address."
+        exit 1
+    fi
+    echo "Devstack is properly configured with IPv6"
+    echo "SERVICE_IP_VERSION: " $SERVICE_IP_VERSION "HOST_IPV6: " $HOST_IPV6 "SERVICE_HOST: " $SERVICE_HOST "SERVICE_LISTEN_ADDRESS: " $SERVICE_LISTEN_ADDRESS "SERVICE_LOCAL_HOST: " $SERVICE_LOCAL_HOST
+}
+
+function sanity_check_system_ipv6_enabled {
+    system_ipv6_enabled=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_ipv6_enabled())')
+    if [[ $system_ipv6_enabled != "True" ]]; then
+        echo "IPv6 is disabled in system"
+        exit 1
+    fi
+    echo "IPv6 is enabled in system"
+}
+
+function verify_service_listen_address_is_ipv6 {
+    local endpoints_verified=False
+    local all_ipv6=True
+    endpoints=$(openstack endpoint list -f value -c URL)
+    for endpoint in ${endpoints}; do
+        local endpoint_address=$(echo "$endpoint" | awk -F/ '{print $3}' | awk -F] '{print $1}')
+        endpoint_address=$(echo $endpoint_address | tr -d [])
+        local is_endpoint_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$endpoint_address'"))')
+        if [[ "$is_endpoint_ipv6" != "True" ]]; then
+            all_ipv6=False
+            echo $endpoint ": This is not ipv6 endpoint which means corresponding service is not listening on IPv6 address."
+            continue
+        fi
+        endpoints_verified=True
+    done
+    if [[ "$all_ipv6" == "False"  ]] || [[ "$endpoints_verified" == "False" ]]; then
+        exit 1
+    fi
+    echo "All services deployed by devstack is on IPv6 endpoints"
+    echo $endpoints
+}
+
+#First thing to verify if system has IPv6 enabled or not
+sanity_check_system_ipv6_enabled
+#Verify whether devstack is configured properly with IPv6 setting
+verify_devstack_ipv6_setting
+#Get all registrfed endpoints by devstack in keystone and verify that each endpoints address is IPv6.
+verify_service_listen_address_is_ipv6
diff --git a/tox.ini b/tox.ini
index 8a7a509..b6ea143 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = pep8,py36,py37,py27,pip-check-reqs
+envlist = pep8,py36,py37,py27,bashate,pip-check-reqs
 minversion = 2.3.1
 skipsdist = True
 
@@ -231,6 +231,18 @@
     find . -type f -name "*.pyc" -delete
     tempest run --serial --regex '\[.*\bslow\b.*\]' {posargs}
 
+[testenv:ipv6-only]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# Run only smoke and ipv6 tests. This env is used to tests
+# the ipv6 deployments and basic tests run fine so that we can
+# verify that services listen on IPv6 address.
+commands =
+    find . -type f -name "*.pyc" -delete
+    tempest run --regex '\[.*\bsmoke|ipv6|test_network_v6\b.*\]' {posargs}
+
 [testenv:venv]
 deps =
   -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
@@ -303,6 +315,20 @@
          -b html releasenotes/source releasenotes/build/html
 whitelist_externals = rm
 
+[testenv:bashate]
+basepython = python3
+# if you want to test out some changes you have made to bashate
+# against tempest, just set BASHATE_INSTALL_PATH=/path/... to your
+# modified bashate tree
+deps =
+   {env:BASHATE_INSTALL_PATH:bashate}
+whitelist_externals = bash
+commands = bash -c "find {toxinidir}/tools    \
+         -not \( -type d -name .?\* -prune \) \
+         -type f                              \
+         -name \*.sh                          \
+         -print0 | xargs -0 bashate -v"
+
 [testenv:pip-check-reqs]
 # Do not install test-requirements as that will pollute the virtualenv for
 # determining missing packages.