diff --git a/doc/source/cli/command-objects/versions.rst b/doc/source/cli/command-objects/versions.rst
new file mode 100644
index 0000000000..6742565265
--- /dev/null
+++ b/doc/source/cli/command-objects/versions.rst
@@ -0,0 +1,41 @@
+========
+versions
+========
+
+Get a list of every version of every service in a given cloud.
+
+versions show
+-------------
+
+Show service versions:
+
+.. program:: versions show
+.. code:: bash
+
+    openstack versions show
+        [--all-interfaces]
+        [--interface <interface>]
+        [--region-name <region-name>]
+        [--service <service>]
+
+.. option:: --all-interfaces
+
+    Return results for every interface of every service.
+    [Mutually exclusive with --interface]
+
+.. option:: --interface <interface>
+
+    Limit results to only those on given interface.
+    [Default 'public'. Mutually exclusive with --all-interfaces]
+
+.. option:: --region-name <region-name>
+
+    Limit results to only those from region-name
+
+.. option:: --service <service>
+
+    Limit results to only those for service. The argument should be either
+    an exact match to what is in the catalog or a known official value or
+    alias from `service-types-authority`_.
+
+.. _service-types-authority: https://service-types.openstack.org/
diff --git a/openstackclient/common/versions.py b/openstackclient/common/versions.py
new file mode 100644
index 0000000000..6a93d3002b
--- /dev/null
+++ b/openstackclient/common/versions.py
@@ -0,0 +1,114 @@
+# Copyright 2018 Red Hat, 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.
+
+"""Versions Action Implementation"""
+
+import os_service_types
+from osc_lib.command import command
+
+from openstackclient.i18n import _
+
+
+class ShowVersions(command.Lister):
+    _description = _("Show available versions of services")
+
+    def get_parser(self, prog_name):
+        parser = super(ShowVersions, self).get_parser(prog_name)
+        interface_group = parser.add_mutually_exclusive_group()
+        interface_group.add_argument(
+            "--all-interfaces",
+            dest="is_all_interfaces",
+            action="store_true",
+            default=False,
+            help=_("Show values for all interfaces"),
+        )
+        interface_group.add_argument(
+            '--interface',
+            default='public',
+            metavar='<interface>',
+            help=_('Show versions for a specific interface.'),
+        )
+        parser.add_argument(
+            '--region-name',
+            metavar='<region_name>',
+            help=_('Show versions for a specific region.'),
+        )
+        parser.add_argument(
+            '--service',
+            metavar='<region_name>',
+            help=_('Show versions for a specific service.'),
+        )
+        parser.add_argument(
+            '--status',
+            metavar='<region_name>',
+            help=_('Show versions for a specific status.'
+                   ' [Valid values are SUPPORTED, CURRENT,'
+                   ' DEPRECATED, EXPERIMENTAL]'),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+
+        interface = parsed_args.interface
+        if parsed_args.is_all_interfaces:
+            interface = None
+
+        session = self.app.client_manager.session
+        version_data = session.get_all_version_data(
+            interface=interface,
+            region_name=parsed_args.region_name)
+
+        columns = [
+            "Region Name",
+            "Service Type",
+            "Version",
+            "Status",
+            "Endpoint",
+            "Min Microversion",
+            "Max Microversion",
+        ]
+
+        status = parsed_args.status
+        if status:
+            status = status.upper()
+
+        service = parsed_args.service
+        if service:
+            # Normalize service type argument to official type
+            service_type_manager = os_service_types.ServiceTypes()
+            service = service_type_manager.get_service_type(service)
+
+        versions = []
+        for region_name, interfaces in version_data.items():
+            for interface, services in interfaces.items():
+                for service_type, service_versions in services.items():
+                    if service and service != service_type:
+                        # TODO(mordred) Once there is a version of
+                        # keystoneauth that can do this filtering
+                        # before making all the discovery calls, switch
+                        # to that.
+                        continue
+                    for data in service_versions:
+                        if status and status != data['status']:
+                            continue
+                        versions.append((
+                            region_name,
+                            service_type,
+                            data['version'],
+                            data['status'],
+                            data['url'],
+                            data['min_microversion'],
+                            data['max_microversion'],
+                        ))
+        return (columns, versions)
diff --git a/openstackclient/tests/functional/common/test_versions.py b/openstackclient/tests/functional/common/test_versions.py
new file mode 100644
index 0000000000..adc74ebc6c
--- /dev/null
+++ b/openstackclient/tests/functional/common/test_versions.py
@@ -0,0 +1,31 @@
+#    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.
+
+import json
+
+from openstackclient.tests.functional import base
+
+
+class VersionsTests(base.TestCase):
+    """Functional tests for versions."""
+
+    def test_versions_show(self):
+        # TODO(mordred) Make this better. The trick is knowing what in the
+        # payload to test for.
+        cmd_output = json.loads(self.openstack(
+            'versions show -f json'
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertIn(
+            "Region Name",
+            cmd_output[0],
+        )
diff --git a/releasenotes/notes/versions-show-12a2443624c83048.yaml b/releasenotes/notes/versions-show-12a2443624c83048.yaml
new file mode 100644
index 0000000000..4f5652f76a
--- /dev/null
+++ b/releasenotes/notes/versions-show-12a2443624c83048.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    A new command, ``openstack versions show`` was added, which will
+    provide a list of all versions of all services in the cloud. It
+    includes relevant metadata, such as min/max microversion, endpoint,
+    status and region.
diff --git a/setup.cfg b/setup.cfg
index f9c0b3efcf..e2fd73bf9d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -51,6 +51,7 @@ openstack.common =
     quota_list = openstackclient.common.quota:ListQuota
     quota_set = openstackclient.common.quota:SetQuota
     quota_show = openstackclient.common.quota:ShowQuota
+    versions_show = openstackclient.common.versions:ShowVersions
 
 openstack.compute.v2 =
     compute_agent_create = openstackclient.compute.v2.agent:CreateAgent