Handle case where sample-api is disabled

This change forbids the creation of threshold alarm if ceilometer
sample-api is disabled.

And logs warning if alarm created before try to use it.

Change-Id: I59861e0d78b120f194c34cc21c4b5e806f22b970
This commit is contained in:
Mehdi Abaakouk 2016-10-06 17:13:43 +02:00
parent 1806c1e74e
commit 0112415f66
2 changed files with 55 additions and 4 deletions

View File

@ -11,14 +11,21 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from ceilometerclient import client as ceiloclient
from ceilometerclient import exc as ceiloexc
from oslo_log import log
import pecan
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
from aodh.api.controllers.v2 import base from aodh.api.controllers.v2 import base
from aodh.api.controllers.v2 import utils as v2_utils from aodh.api.controllers.v2 import utils as v2_utils
from aodh.i18n import _ from aodh.i18n import _
from aodh import keystone_client
from aodh import storage from aodh import storage
LOG = log.getLogger(__name__)
class AlarmThresholdRule(base.AlarmRule): class AlarmThresholdRule(base.AlarmRule):
"""Alarm Threshold Rule """Alarm Threshold Rule
@ -57,10 +64,47 @@ class AlarmThresholdRule(base.AlarmRule):
exclude_outliers = wsme.wsattr(bool, default=False) exclude_outliers = wsme.wsattr(bool, default=False)
"Whether datapoints with anomalously low sample counts are excluded" "Whether datapoints with anomalously low sample counts are excluded"
ceilometer_sample_api_is_supported = None
def __init__(self, query=None, **kwargs): def __init__(self, query=None, **kwargs):
query = [base.Query(**q) for q in query] if query else [] query = [base.Query(**q) for q in query] if query else []
super(AlarmThresholdRule, self).__init__(query=query, **kwargs) super(AlarmThresholdRule, self).__init__(query=query, **kwargs)
@classmethod
def _check_ceilometer_sample_api(cls):
# Check it only once
if cls.ceilometer_sample_api_is_supported is None:
auth_config = pecan.request.cfg.service_credentials
client = ceiloclient.get_client(
version=2,
session=keystone_client.get_session(pecan.request.cfg),
# ceiloclient adapter options
region_name=auth_config.region_name,
interface=auth_config.interface,
)
try:
client.statistics.list(
meter_name="idontthinkthatexistsbutwhatever")
except Exception as e:
if isinstance(e, ceiloexc.HTTPException):
if e.code == 410:
cls.ceilometer_sample_api_is_supported = False
elif e.code < 500:
cls.ceilometer_sample_api_is_supported = True
else:
raise
else:
raise
else:
# I don't think this meter can exists but how known
cls.ceilometer_sample_api_is_supported = True
if cls.ceilometer_sample_api_is_supported is False:
raise base.ClientSideError(
"This telemetry installation is not configured to support"
"alarm of type 'threshold")
@staticmethod @staticmethod
def validate(threshold_rule): def validate(threshold_rule):
# note(sileht): wsme default doesn't work in some case # note(sileht): wsme default doesn't work in some case
@ -77,8 +121,9 @@ class AlarmThresholdRule(base.AlarmRule):
allow_timestamps=False) allow_timestamps=False)
return threshold_rule return threshold_rule
@staticmethod @classmethod
def validate_alarm(alarm): def validate_alarm(cls, alarm):
cls._check_ceilometer_sample_api()
# ensure an implicit constraint on project_id is added to # ensure an implicit constraint on project_id is added to
# the query if not already present # the query if not already present
alarm.threshold_rule.query = v2_utils.sanitize_query( alarm.threshold_rule.query = v2_utils.sanitize_query(

View File

@ -19,6 +19,7 @@ import operator
import six import six
from ceilometerclient import client as ceiloclient from ceilometerclient import client as ceiloclient
from ceilometerclient import exc as ceiloexc
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
from oslo_utils import timeutils from oslo_utils import timeutils
@ -126,7 +127,12 @@ class ThresholdEvaluator(evaluator.Evaluator):
return self.cm_client.statistics.list( return self.cm_client.statistics.list(
meter_name=rule['meter_name'], q=query, meter_name=rule['meter_name'], q=query,
period=rule['period']) period=rule['period'])
except Exception: except Exception as e:
if isinstance(e, ceiloexc.HTTPException) and e.code == 410:
LOG.warning("This telemetry installation is not configured to "
"support alarm of type 'threshold', they should "
"be disabled or removed.")
else:
LOG.exception(_('alarm stats retrieval failed')) LOG.exception(_('alarm stats retrieval failed'))
return [] return []