Set lock_path correctly.
[openstack-build/neutron-build.git] / neutron / pecan_wsgi / controllers / quota.py
1 # Copyright (c) 2015 Taturiello Consulting, Meh.
2 # All Rights Reserved.
3 #
4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
5 #    not use this file except in compliance with the License. You may obtain
6 #    a copy of the License at
7 #
8 #         http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #    Unless required by applicable law or agreed to in writing, software
11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 #    License for the specific language governing permissions and limitations
14 #    under the License.
15
16 from oslo_config import cfg
17 from oslo_log import log
18 from oslo_utils import importutils
19 from pecan import request
20 from pecan import response
21
22 from neutron.api.v2 import attributes
23 from neutron.common import constants
24 from neutron.common import exceptions as n_exc
25 from neutron.pecan_wsgi.controllers import utils
26 from neutron.quota import resource_registry
27
28 LOG = log.getLogger(__name__)
29 RESOURCE_NAME = "quota"
30
31
32 class QuotasController(utils.NeutronPecanController):
33
34     def __init__(self):
35         self._driver = importutils.import_class(
36             cfg.CONF.QUOTAS.quota_driver
37         )
38         super(QuotasController, self).__init__(
39             "%ss" % RESOURCE_NAME, RESOURCE_NAME)
40
41     def _check_admin(self, context,
42                      reason=_("Only admin can view or configure quota")):
43         if not context.is_admin:
44             raise n_exc.AdminRequired(reason=reason)
45
46     @utils.expose()
47     def _lookup(self, tenant_id, *remainder):
48         return QuotaController(self._driver, tenant_id), remainder
49
50     @utils.expose()
51     def index(self):
52         neutron_context = request.context.get('neutron_context')
53         # FIXME(salv-orlando): There shouldn't be any need to to this eplicit
54         # check. However some behaviours from the "old" extension have
55         # been temporarily carried over here
56         self._check_admin(neutron_context)
57         # TODO(salv-orlando): proper plurals management
58         return {self.collection:
59                 self._driver.get_all_quotas(
60                     neutron_context,
61                     resource_registry.get_all_resources())}
62
63
64 class QuotaController(utils.NeutronPecanController):
65
66     def __init__(self, _driver, tenant_id):
67         self._driver = _driver
68         self._tenant_id = tenant_id
69
70         super(QuotaController, self).__init__(
71             "%ss" % RESOURCE_NAME, RESOURCE_NAME)
72
73         # Ensure limits for all registered resources are returned
74         attr_dict = attributes.RESOURCE_ATTRIBUTE_MAP[self.collection]
75         for quota_resource in resource_registry.get_all_resources().keys():
76             attr_dict[quota_resource] = {
77                 'allow_post': False,
78                 'allow_put': True,
79                 'convert_to': attributes.convert_to_int,
80                 'validate': {
81                     'type:range': [-1, constants.DB_INTEGER_MAX_VALUE]},
82                 'is_visible': True}
83
84     @utils.expose(generic=True)
85     def index(self):
86         return get_tenant_quotas(self._tenant_id, self._driver)
87
88     @utils.when(index, method='PUT')
89     def put(self, *args, **kwargs):
90         neutron_context = request.context.get('neutron_context')
91         # For put requests there's always going to be a single element
92         quota_data = request.context['resources'][0]
93         for key, value in quota_data.items():
94             self._driver.update_quota_limit(
95                 neutron_context, self._tenant_id, key, value)
96         return get_tenant_quotas(self._tenant_id, self._driver)
97
98     @utils.when(index, method='DELETE')
99     def delete(self):
100         neutron_context = request.context.get('neutron_context')
101         self._driver.delete_tenant_quota(neutron_context,
102                                          self._tenant_id)
103         response.status = 204
104
105
106 def get_tenant_quotas(tenant_id, driver=None):
107     if not driver:
108         driver = importutils.import_class(cfg.CONF.QUOTAS.quota_driver)
109
110     neutron_context = request.context.get('neutron_context')
111     if tenant_id == 'tenant':
112         # NOTE(salv-orlando): Read the following before the code in order
113         # to avoid puking.
114         # There is a weird undocumented behaviour of the Neutron quota API
115         # as 'tenant' is used as an API action to return the identifier
116         # of the tenant in the request context. This is used exclusively
117         # for interaction with python-neutronclient and is a possibly
118         # unnecessary 'whoami' API endpoint. Pending resolution of this
119         # API issue, this controller will just treat the magic string
120         # 'tenant' (and only that string) and return the response expected
121         # by python-neutronclient
122         return {'tenant': {'tenant_id': neutron_context.tenant_id}}
123     tenant_quotas = driver.get_tenant_quotas(
124         neutron_context,
125         resource_registry.get_all_resources(),
126         tenant_id)
127     tenant_quotas['tenant_id'] = tenant_id
128     return {RESOURCE_NAME: tenant_quotas}