diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
new file mode 100644
index 0000000000..fd482da9e6
--- /dev/null
+++ b/openstackclient/common/quota.py
@@ -0,0 +1,192 @@
+#   Copyright 2012 OpenStack Foundation
+#
+#   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.
+#
+
+"""Quota action implementations"""
+
+import itertools
+import logging
+import six
+import sys
+
+from cliff import command
+from cliff import show
+
+
+# List the quota items, map the internal argument name to the option
+# name that the user sees.
+
+COMPUTE_QUOTAS = {
+    'cores': 'cores',
+    'fixed_ips': 'fixed-ips',
+    'floating_ips': 'floating-ips',
+    'injected_file_content_bytes': 'injected-file-size',
+    'injected_file_path_bytes': 'injected-path-size',
+    'injected_files': 'injected-files',
+    'instances': 'instances',
+    'key_pairs': 'key-pairs',
+    'metadata_items': 'properties',
+    'ram': 'ram',
+    'security_group_rules': 'secgroup-rules',
+    'security_groups': 'secgroups',
+}
+
+VOLUME_QUOTAS = {
+    'gigabytes': 'gigabytes',
+    'snapshots': 'snapshots',
+    'volumes': 'volumes',
+}
+
+
+class SetQuota(command.Command):
+    """Set quotas for project or class"""
+
+    log = logging.getLogger(__name__ + '.SetQuota')
+
+    def get_parser(self, prog_name):
+        parser = super(SetQuota, self).get_parser(prog_name)
+        parser.add_argument(
+            'project',
+            metavar='<project/class>',
+            help='Set quotas for this project or class (name/ID)',
+        )
+        parser.add_argument(
+            '--class',
+            dest='quota_class',
+            action='store_true',
+            default=False,
+            help='Set quotas for <class>',
+        )
+        for k, v in itertools.chain(
+                COMPUTE_QUOTAS.items(), VOLUME_QUOTAS.items()):
+            parser.add_argument(
+                '--%s' % v,
+                metavar='<new-%s>' % v,
+                type=int,
+                help='New value for the %s quota' % v,
+            )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+
+        compute_client = self.app.client_manager.compute
+        volume_client = self.app.client_manager.volume
+
+        compute_kwargs = {}
+        for k, v in COMPUTE_QUOTAS.items():
+            if v in parsed_args:
+                compute_kwargs[k] = getattr(parsed_args, v, None)
+
+        volume_kwargs = {}
+        for k, v in VOLUME_QUOTAS.items():
+            if v in parsed_args:
+                volume_kwargs[k] = getattr(parsed_args, v, None)
+
+        if compute_kwargs == {} and volume_kwargs == {}:
+            sys.stderr.write("No quotas updated")
+            return
+
+        if parsed_args.quota_class:
+            if compute_kwargs:
+                compute_client.quota_classes.update(
+                    parsed_args.project,
+                    **compute_kwargs)
+            if volume_kwargs:
+                volume_client.quota_classes.update(
+                    parsed_args.project,
+                    **volume_kwargs)
+        else:
+            if compute_kwargs:
+                compute_client.quotas.update(
+                    parsed_args.project,
+                    **compute_kwargs)
+            if volume_kwargs:
+                volume_client.quotas.update(
+                    parsed_args.project,
+                    **volume_kwargs)
+
+
+class ShowQuota(show.ShowOne):
+    """Show quotas for project or class"""
+
+    log = logging.getLogger(__name__ + '.ShowQuota')
+
+    def get_parser(self, prog_name):
+        parser = super(ShowQuota, self).get_parser(prog_name)
+        parser.add_argument(
+            'project',
+            metavar='<project/class>',
+            help='Show this project or class (name/ID)',
+        )
+        type_group = parser.add_mutually_exclusive_group()
+        type_group.add_argument(
+            '--class',
+            dest='quota_class',
+            action='store_true',
+            default=False,
+            help='Show quotas for <class>',
+        )
+        type_group.add_argument(
+            '--default',
+            dest='default',
+            action='store_true',
+            default=False,
+            help='Show default quotas for <project>'
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+
+        compute_client = self.app.client_manager.compute
+        volume_client = self.app.client_manager.volume
+
+        # NOTE(dtroyer): These quota API calls do not validate the project
+        #                or class arguments and return what appears to be
+        #                the default quota values if the project or class
+        #                does not exist. If this is determined to be the
+        #                intended behaviour of the API we will validate
+        #                the argument with Identity ourselves later.
+        if parsed_args.quota_class:
+            compute_quota = compute_client.quota_classes.get(
+                parsed_args.project)
+            volume_quota = volume_client.quota_classes.get(
+                parsed_args.project)
+        elif parsed_args.default:
+            compute_quota = compute_client.quotas.defaults(
+                parsed_args.project)
+            volume_quota = volume_client.quotas.defaults(
+                parsed_args.project)
+        else:
+            compute_quota = compute_client.quotas.get(parsed_args.project)
+            volume_quota = volume_client.quotas.get(parsed_args.project)
+
+        info = {}
+        info.update(compute_quota._info)
+        info.update(volume_quota._info)
+
+        # Map the internal quota names to the external ones
+        for k, v in itertools.chain(
+                COMPUTE_QUOTAS.items(), VOLUME_QUOTAS.items()):
+            if not k == v and info[k]:
+                info[v] = info[k]
+                info.pop(k)
+
+        # Handle project ID special as it only appears in output
+        if info['id']:
+            info['project'] = info['id']
+            info.pop('id')
+
+        return zip(*sorted(six.iteritems(info)))
diff --git a/openstackclient/volume/v1/quota.py b/openstackclient/volume/v1/quota.py
deleted file mode 100644
index 4f4e97e8f5..0000000000
--- a/openstackclient/volume/v1/quota.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#   Copyright 2012-2013 OpenStack, LLC.
-#
-#   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.
-#
-
-"""Volume v1 Quota action implementations"""
-
-import logging
-import sys
-
-from cliff import command
-from cliff import show
-
-from openstackclient.common import utils
-
-
-class ListQuota(show.ShowOne):
-    """List quota command"""
-
-    api = 'volume'
-    log = logging.getLogger(__name__ + '.ListQuota')
-
-    def get_parser(self, prog_name):
-        parser = super(ListQuota, self).get_parser(prog_name)
-        parser.add_argument(
-            'tenant',
-            metavar='<tenant>',
-            help='ID of tenant to list the default quotas for')
-        return parser
-
-    def take_action(self, parsed_args):
-        self.log.debug('take_action(%s)' % parsed_args)
-        volume_client = self.app.client_manager.volume
-        defaults = volume_client.quotas.defaults(parsed_args.tenant)
-
-        return zip(*sorted(defaults._info.iteritems()))
-
-
-class SetQuota(command.Command):
-    """Set quota command"""
-
-    api = 'volume'
-    log = logging.getLogger(__name__ + '.SetQuota')
-
-    def get_parser(self, prog_name):
-        parser = super(SetQuota, self).get_parser(prog_name)
-        parser.add_argument(
-            'tenant',
-            metavar='<tenant>',
-            help='ID of tenant to set the quotas for')
-        parser.add_argument(
-            '--volumes',
-            metavar='<new-volumes>',
-            type=int,
-            help='New value for the volumes quota')
-        parser.add_argument(
-            '--gigabytes',
-            metavar='<new-gigabytes>',
-            type=int,
-            help='New value for the gigabytes quota')
-        return parser
-
-    def take_action(self, parsed_args):
-        self.log.debug('take_action(%s)' % parsed_args)
-
-        kwargs = {}
-        if parsed_args.volumes:
-            kwargs['volumes'] = parsed_args.volumes
-        if parsed_args.gigabytes:
-            kwargs['gigabytes'] = parsed_args.gigabytes
-
-        if kwargs == {}:
-            sys.stdout.write("Quota not updated, no arguments present")
-            return
-
-        volume_client = self.app.client_manager.volume
-        volume_client.quotas.update(parsed_args.tenant,
-                                    parsed_args.volumes,
-                                    parsed_args.gigabytes)
-
-        return
-
-
-class ShowQuota(show.ShowOne):
-    """Show quota command"""
-
-    api = 'volume'
-    log = logging.getLogger(__name__ + '.ShowQuota')
-
-    def get_parser(self, prog_name):
-        parser = super(ShowQuota, self).get_parser(prog_name)
-        parser.add_argument(
-            'tenant',
-            metavar='<tenant>',
-            help='ID of tenant to list the quotas for')
-        return parser
-
-    def take_action(self, parsed_args):
-        self.log.debug('take_action(%s)' % parsed_args)
-        volume_client = self.app.client_manager.volume
-        quota = utils.find_resource(volume_client.quotas,
-                                    parsed_args.tenant)
-
-        return zip(*sorted(quota._info.iteritems()))
diff --git a/setup.cfg b/setup.cfg
index bbda913db1..475e2077bb 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,6 +33,8 @@ openstack.cli =
 
 openstack.common =
     limits_show = openstackclient.common.limits:ShowLimits
+    quota_set = openstackclient.common.quota:SetQuota
+    quota_show = openstackclient.common.quota:ShowQuota
 
 openstack.identity.v2_0 =
     ec2_credentials_create = openstackclient.identity.v2_0.ec2creds:CreateEC2Creds
@@ -203,10 +205,6 @@ openstack.compute.v2 =
     server_unpause = openstackclient.compute.v2.server:UnpauseServer
 
 openstack.volume.v1 =
-    quota_list = openstackclient.volume.v1.quota:ListQuota
-    quota_set = openstackclient.volume.v1.quota:SetQuota
-    quota_show = openstackclient.volume.v1.quota:ShowQuota
-
     snapshot_create = openstackclient.volume.v1.snapshot:CreateSnapshot
     snapshot_delete = openstackclient.volume.v1.snapshot:DeleteSnapshot
     snapshot_list = openstackclient.volume.v1.snapshot:ListSnapshot