forked from starlingx-staging/stx-ceilometer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
root.py
229 lines (206 loc) · 9.04 KB
/
root.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#
# Copyright 2012 New Dream Network, LLC (DreamHost)
# Copyright 2013 IBM Corp.
# Copyright 2013 eNovance <licensing@enovance.com>
# Copyright Ericsson AB 2013. All rights reserved
# Copyright 2014 Hewlett-Packard Company
# Copyright 2015 Huawei Technologies Co., Ltd.
#
# 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.
#
# Copyright (c) 2013-2015 Wind River Systems, Inc.
#
from keystoneauth1 import exceptions
from oslo_config import cfg
from oslo_log import log
from oslo_utils import strutils
import pecan
from ceilometer.api.controllers.v2 import capabilities
from ceilometer.api.controllers.v2 import extensions
from ceilometer.api.controllers.v2 import meters
from ceilometer.api.controllers.v2 import metertypes
from ceilometer.api.controllers.v2 import pipelines
from ceilometer.api.controllers.v2 import query
from ceilometer.api.controllers.v2 import resources
from ceilometer.api.controllers.v2 import samples
from ceilometer.api.controllers.v2 import statistics
from ceilometer.i18n import _
from ceilometer import keystone_client
API_OPTS = [
cfg.BoolOpt('gnocchi_is_enabled',
help=('Set True to disable resource/meter/sample URLs. '
'Default autodetection by querying keystone.')),
cfg.BoolOpt('aodh_is_enabled',
help=('Set True to redirect alarms URLs to aodh. '
'Default autodetection by querying keystone.')),
cfg.StrOpt('aodh_url',
help=('The endpoint of Aodh to redirect alarms URLs '
'to Aodh API. Default autodetection by querying '
'keystone.')),
cfg.BoolOpt('panko_is_enabled',
help=('Set True to redirect events URLs to Panko. '
'Default autodetection by querying keystone.')),
cfg.StrOpt('panko_url',
help=('The endpoint of Panko to redirect events URLs '
'to Panko API. Default autodetection by querying '
'keystone.')),
]
LOG = log.getLogger(__name__)
def gnocchi_abort():
pecan.abort(410, ("This telemetry installation is configured to use "
"Gnocchi. Please use the Gnocchi API available on "
"the metric endpoint to retrieve data."))
def aodh_abort():
pecan.abort(410, _("alarms URLs is unavailable when Aodh is "
"disabled or unavailable."))
def _redirect(url):
pecan.redirect(location=url + pecan.request.path_qs,
code=308)
class QueryController(object):
def __init__(self, gnocchi_is_enabled=False,
aodh_url=None):
self.gnocchi_is_enabled = gnocchi_is_enabled
self.aodh_url = aodh_url
@pecan.expose()
def _lookup(self, kind, *remainder):
if kind == 'alarms' and self.aodh_url:
_redirect(self.aodh_url)
elif kind == 'alarms':
aodh_abort()
elif kind == 'samples' and self.gnocchi_is_enabled:
gnocchi_abort()
elif kind == 'samples':
return query.QuerySamplesController(), remainder
else:
pecan.abort(404)
class V2Controller(object):
"""Version 2 API controller root."""
capabilities = capabilities.CapabilitiesController()
vars()['wrs-metertypes'] = metertypes.MeterTypesController()
vars()['wrs-pipelines'] = pipelines.PipelinesController()
vars()['wrs-statistics'] = statistics.StatisticsController()
extensions = extensions.ExtensionsController()
def __init__(self):
self._gnocchi_is_enabled = None
self._aodh_is_enabled = None
self._aodh_url = None
self._panko_is_enabled = None
self._panko_url = None
@property
def gnocchi_is_enabled(self):
if self._gnocchi_is_enabled is None:
if pecan.request.cfg.api.gnocchi_is_enabled is not None:
self._gnocchi_is_enabled = (
pecan.request.cfg.api.gnocchi_is_enabled)
else:
try:
catalog = keystone_client.get_service_catalog(
keystone_client.get_client(pecan.request.cfg))
catalog.url_for(service_type='metric')
except exceptions.EndpointNotFound:
self._gnocchi_is_enabled = False
except exceptions.ClientException:
LOG.warning("Can't connect to keystone, assuming "
"gnocchi is disabled and retry later")
else:
self._gnocchi_is_enabled = True
LOG.warning("ceilometer-api started with gnocchi "
"enabled. The resources/meters/samples "
"URLs are disabled.")
return self._gnocchi_is_enabled
@property
def aodh_url(self):
if self._aodh_url is None:
if pecan.request.cfg.api.aodh_is_enabled is False:
self._aodh_url = ""
elif pecan.request.cfg.api.aodh_url is not None:
self._aodh_url = self._normalize_url(
pecan.request.cfg.api.aodh_url)
else:
try:
catalog = keystone_client.get_service_catalog(
keystone_client.get_client(pecan.request.cfg))
self._aodh_url = self._normalize_url(
catalog.url_for(service_type='alarming'))
except exceptions.EndpointNotFound:
self._aodh_url = ""
except exceptions.ClientException:
LOG.warning("Can't connect to keystone, assuming aodh "
"is disabled and retry later.")
else:
LOG.debug("ceilometer-api started with aodh "
"enabled. Alarms URLs will be redirected "
"to aodh endpoint.")
return self._aodh_url
@property
def panko_url(self):
if self._panko_url is None:
if pecan.request.cfg.api.panko_is_enabled is False:
self._panko_url = ""
elif pecan.request.cfg.api.panko_url is not None:
self._panko_url = self._normalize_url(
pecan.request.cfg.api.panko_url)
else:
try:
catalog = keystone_client.get_service_catalog(
keystone_client.get_client(pecan.request.cfg))
self._panko_url = self._normalize_url(
catalog.url_for(service_type='event'))
except exceptions.EndpointNotFound:
self._panko_url = ""
except exceptions.ClientException:
LOG.warning(
"Can't connect to keystone, assuming Panko "
"is disabled and retry later.")
else:
LOG.debug("ceilometer-api started with Panko "
"enabled. Events URLs will be redirected "
"to Panko endpoint.")
return self._panko_url
@pecan.expose()
def _lookup(self, kind, *remainder):
if (kind in ['meters', 'resources', 'samples']
and self.gnocchi_is_enabled):
if kind == 'meters' and pecan.request.method == 'POST':
direct = pecan.request.params.get('direct', '')
if strutils.bool_from_string(direct):
pecan.abort(400, _('direct option cannot be true when '
'Gnocchi is enabled.'))
return meters.MetersController(), remainder
gnocchi_abort()
elif kind == 'meters':
return meters.MetersController(), remainder
elif kind == 'resources':
return resources.ResourcesController(), remainder
elif kind == 'samples':
return samples.SamplesController(), remainder
elif kind == 'query':
return QueryController(
gnocchi_is_enabled=self.gnocchi_is_enabled,
aodh_url=self.aodh_url,
), remainder
elif kind == 'alarms' and (not self.aodh_url):
aodh_abort()
elif kind == 'alarms' and self.aodh_url:
_redirect(self.aodh_url)
elif kind == 'events' and self.panko_url:
return _redirect(self.panko_url)
elif kind == 'event_types' and self.panko_url:
return _redirect(self.panko_url)
else:
pecan.abort(404)
@staticmethod
def _normalize_url(url):
if url.endswith("/"):
return url[:-1]
return url