Files
python-neutronclient/neutronclient/neutron/v2_0/quota.py
Abhishek Raut d45442b3d4 Add support to expose default quotas for tenants
Neutron client should be able to show the default quotas
set for tenants. This patch adds support for the same and
introduces a new CLI to retrieve default quotas.

Sample usage:

neutron quota-default-show
+-----------------------+-------+
| Field                 | Value |
+-----------------------+-------+
| floatingip            | 50    |
| l2-gateway-connection | -1    |
| network               | 10    |
| port                  | 50    |
| rbac_policy           | 10    |
| router                | 10    |
| security_group        | 10    |
| security_group_rule   | 100   |
| subnet                | 10    |
| subnetpool            | -1    |
+-----------------------+-------+

Change-Id: Ie92c22862d2b8ace32a2cf4cb642a6d0bac7932d
Closes-Bug: #1204956
2016-07-15 20:47:51 +00:00

245 lines
8.6 KiB
Python

# Copyright 2012 OpenStack Foundation.
# All Rights Reserved
#
# 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.
#
from __future__ import print_function
import abc
import argparse
from cliff import lister
from cliff import show
from oslo_serialization import jsonutils
import six
from neutronclient._i18n import _
from neutronclient.common import exceptions
from neutronclient.common import utils
from neutronclient.neutron import v2_0 as neutronV20
def get_tenant_id(args, client):
return (args.pos_tenant_id or args.tenant_id or
client.get_quotas_tenant()['tenant']['tenant_id'])
class DeleteQuota(neutronV20.NeutronCommand):
"""Delete defined quotas of a given tenant."""
resource = 'quota'
def get_parser(self, prog_name):
parser = super(DeleteQuota, self).get_parser(prog_name)
parser.add_argument(
'--tenant-id', metavar='tenant-id',
help=_('The owner tenant ID.'))
parser.add_argument(
'--tenant_id',
help=argparse.SUPPRESS)
parser.add_argument(
'pos_tenant_id',
help=argparse.SUPPRESS, nargs='?')
return parser
def take_action(self, parsed_args):
neutron_client = self.get_client()
tenant_id = get_tenant_id(parsed_args, neutron_client)
obj_deleter = getattr(neutron_client,
"delete_%s" % self.resource)
obj_deleter(tenant_id)
print((_('Deleted %(resource)s: %(tenant_id)s')
% {'tenant_id': tenant_id,
'resource': self.resource}),
file=self.app.stdout)
return
class ListQuota(neutronV20.NeutronCommand, lister.Lister):
"""List quotas of all tenants who have non-default quota values."""
resource = 'quota'
def get_parser(self, prog_name):
parser = super(ListQuota, self).get_parser(prog_name)
return parser
def take_action(self, parsed_args):
neutron_client = self.get_client()
search_opts = {}
self.log.debug('search options: %s', search_opts)
obj_lister = getattr(neutron_client,
"list_%ss" % self.resource)
data = obj_lister(**search_opts)
info = []
collection = self.resource + "s"
if collection in data:
info = data[collection]
_columns = len(info) > 0 and sorted(info[0].keys()) or []
return (_columns, (utils.get_item_properties(s, _columns)
for s in info))
class ShowQuotaBase(neutronV20.NeutronCommand, show.ShowOne):
"""Base class to show quotas of a given tenant."""
resource = "quota"
@abc.abstractmethod
def retrieve_data(self, tenant_id, neutron_client):
"""Retrieve data using neutron client for the given tenant."""
def get_parser(self, prog_name):
parser = super(ShowQuotaBase, self).get_parser(prog_name)
parser.add_argument(
'--tenant-id', metavar='tenant-id',
help=_('The owner tenant ID.'))
parser.add_argument(
'--tenant_id',
help=argparse.SUPPRESS)
# allow people to do neutron quota-show <tenant-id>.
# we use a different name for this because the default will
# override whatever is in the named arg otherwise.
parser.add_argument(
'pos_tenant_id',
help=argparse.SUPPRESS, nargs='?')
return parser
def take_action(self, parsed_args):
neutron_client = self.get_client()
tenant_id = get_tenant_id(parsed_args, neutron_client)
data = self.retrieve_data(tenant_id, neutron_client)
if self.resource in data:
return zip(*sorted(six.iteritems(data[self.resource])))
return
class ShowQuota(ShowQuotaBase):
"""Show quotas for a given tenant."""
def retrieve_data(self, tenant_id, neutron_client):
return neutron_client.show_quota(tenant_id)
class ShowQuotaDefault(ShowQuotaBase):
"""Show default quotas for a given tenant."""
def retrieve_data(self, tenant_id, neutron_client):
return neutron_client.show_quota_default(tenant_id)
class UpdateQuota(neutronV20.NeutronCommand, show.ShowOne):
"""Define tenant's quotas not to use defaults."""
resource = 'quota'
def get_parser(self, prog_name):
parser = super(UpdateQuota, self).get_parser(prog_name)
parser.add_argument(
'--tenant-id', metavar='tenant-id',
help=_('The owner tenant ID.'))
parser.add_argument(
'--tenant_id',
help=argparse.SUPPRESS)
parser.add_argument(
'--network', metavar='networks',
help=_('The limit of networks.'))
parser.add_argument(
'--subnet', metavar='subnets',
help=_('The limit of subnets.'))
parser.add_argument(
'--port', metavar='ports',
help=_('The limit of ports.'))
parser.add_argument(
'--router', metavar='routers',
help=_('The limit of routers.'))
parser.add_argument(
'--floatingip', metavar='floatingips',
help=_('The limit of floating IPs.'))
parser.add_argument(
'--security-group', metavar='security_groups',
help=_('The limit of security groups.'))
parser.add_argument(
'--security-group-rule', metavar='security_group_rules',
help=_('The limit of security groups rules.'))
parser.add_argument(
'--vip', metavar='vips',
help=_('The limit of vips.'))
parser.add_argument(
'--pool', metavar='pools',
help=_('The limit of pools.'))
parser.add_argument(
'--member', metavar='members',
help=_('The limit of pool members.'))
parser.add_argument(
'--health-monitor', metavar='health_monitors',
help=_('The limit of health monitors.'))
parser.add_argument(
'pos_tenant_id',
help=argparse.SUPPRESS, nargs='?')
return parser
def _validate_int(self, name, value):
try:
return_value = int(value)
except Exception:
message = (_('Quota limit for %(name)s must be an integer') %
{'name': name})
raise exceptions.NeutronClientException(message=message)
return return_value
def args2body(self, parsed_args):
quota = {}
for resource in ('network', 'subnet', 'port', 'router', 'floatingip',
'security_group', 'security_group_rule',
'vip', 'pool', 'member', 'health_monitor'):
if getattr(parsed_args, resource):
quota[resource] = self._validate_int(
resource,
getattr(parsed_args, resource))
return {self.resource: quota}
def take_action(self, parsed_args):
neutron_client = self.get_client()
_extra_values = neutronV20.parse_args_to_dict(self.values_specs)
neutronV20._merge_args(self, parsed_args, _extra_values,
self.values_specs)
body = self.args2body(parsed_args)
if self.resource in body:
body[self.resource].update(_extra_values)
else:
body[self.resource] = _extra_values
obj_updator = getattr(neutron_client,
"update_%s" % self.resource)
tenant_id = get_tenant_id(parsed_args, neutron_client)
data = obj_updator(tenant_id, body)
if self.resource in data:
for k, v in six.iteritems(data[self.resource]):
if isinstance(v, list):
value = ""
for _item in v:
if value:
value += "\n"
if isinstance(_item, dict):
value += jsonutils.dumps(_item)
else:
value += str(_item)
data[self.resource][k] = value
elif v is None:
data[self.resource][k] = ''
return zip(*sorted(six.iteritems(data[self.resource])))
else:
return