Add the sqlalchemy implementation of the alarms collection.
blueprint alarm-api Change-Id: Id8f00b1cb7519ca59f277170fcb03e0976a4fb1a
This commit is contained in:
parent
0eefaf3c88
commit
2c84007b34
@ -19,9 +19,10 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import copy
|
||||
import os
|
||||
import uuid
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from ceilometer.openstack.common import log
|
||||
from ceilometer.openstack.common import timeutils
|
||||
@ -29,7 +30,7 @@ from ceilometer.storage import base
|
||||
from ceilometer.storage import models as api_models
|
||||
from ceilometer.storage.sqlalchemy import migration
|
||||
from ceilometer.storage.sqlalchemy.models import Meter, Project, Resource
|
||||
from ceilometer.storage.sqlalchemy.models import Source, User, Base
|
||||
from ceilometer.storage.sqlalchemy.models import Source, User, Base, Alarm
|
||||
import ceilometer.storage.sqlalchemy.session as sqlalchemy_session
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
@ -412,18 +413,78 @@ class Connection(base.Connection):
|
||||
period_end=period_end,
|
||||
)
|
||||
|
||||
def _row_to_alarm_model(self, row):
|
||||
return api_models.Alarm(alarm_id=row.id,
|
||||
enabled=row.enabled,
|
||||
name=row.name,
|
||||
description=row.description,
|
||||
timestamp=row.timestamp,
|
||||
counter_name=row.counter_name,
|
||||
user_id=row.user_id,
|
||||
project_id=row.project_id,
|
||||
comparison_operator=row.comparison_operator,
|
||||
threshold=row.threshold,
|
||||
statistic=row.statistic,
|
||||
evaluation_periods=row.evaluation_periods,
|
||||
period=row.period,
|
||||
state=row.state,
|
||||
state_timestamp=row.state_timestamp,
|
||||
ok_actions=row.ok_actions,
|
||||
alarm_actions=row.alarm_actions,
|
||||
insufficient_data_actions=
|
||||
row.insufficient_data_actions,
|
||||
matching_metadata=row.matching_metadata)
|
||||
|
||||
def _alarm_model_to_row(self, alarm, row=None):
|
||||
if row is None:
|
||||
row = Alarm(id=str(uuid.uuid1()))
|
||||
row.update(alarm.as_dict())
|
||||
return row
|
||||
|
||||
def get_alarms(self, name=None, user=None,
|
||||
project=None, enabled=True, alarm_id=None):
|
||||
"""Yields a lists of alarms that match filters
|
||||
:param user: Optional ID for user that owns the resource.
|
||||
:param project: Optional ID for project that owns the resource.
|
||||
:param enabled: Optional boolean to list disable alarm.
|
||||
:param alarm_id: Optional alarm_id to return one alarm.
|
||||
"""
|
||||
raise NotImplementedError('Alarms not implemented')
|
||||
query = self.session.query(Alarm)
|
||||
if name is not None:
|
||||
query = query.filter(Alarm.name == name)
|
||||
if enabled is not None:
|
||||
query = query.filter(Alarm.enabled == enabled)
|
||||
if user is not None:
|
||||
query = query.filter(Alarm.user_id == user)
|
||||
if project is not None:
|
||||
query = query.filter(Alarm.project_id == project)
|
||||
if alarm_id is not None:
|
||||
query = query.filter(Alarm.id == alarm_id)
|
||||
|
||||
return (self._row_to_alarm_model(x) for x in query.all())
|
||||
|
||||
def update_alarm(self, alarm):
|
||||
"""update alarm
|
||||
|
||||
:param alarm: the new Alarm to update
|
||||
"""
|
||||
raise NotImplementedError('Alarms not implemented')
|
||||
if alarm.alarm_id:
|
||||
alarm_row = self.session.merge(Alarm(id=alarm.alarm_id))
|
||||
self._alarm_model_to_row(alarm, alarm_row)
|
||||
else:
|
||||
self.session.merge(User(id=alarm.user_id))
|
||||
self.session.merge(Project(id=alarm.project_id))
|
||||
|
||||
alarm_row = self._alarm_model_to_row(alarm)
|
||||
self.session.add(alarm_row)
|
||||
|
||||
self.session.flush()
|
||||
return self._row_to_alarm_model(alarm_row)
|
||||
|
||||
def delete_alarm(self, alarm_id):
|
||||
"""Delete a alarm
|
||||
|
||||
:param alarm_id: ID of the alarm to delete
|
||||
"""
|
||||
raise NotImplementedError('Alarms not implemented')
|
||||
self.session.query(Alarm).filter(Alarm.id == alarm_id).delete()
|
||||
self.session.flush()
|
||||
|
@ -0,0 +1,56 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2013 eNovance <licensing@enovance.com>
|
||||
# Copyright © 2013 Red Hat, Inc.
|
||||
#
|
||||
# Author: Mehdi Abaakouk <mehdi.abaakouk@enovance.com>
|
||||
# Angus Salkeld <asalkeld@redhat.com>
|
||||
#
|
||||
# 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 sqlalchemy import MetaData, Table, Column, Text
|
||||
from sqlalchemy import Boolean, Integer, String, DateTime, Float
|
||||
|
||||
meta = MetaData()
|
||||
|
||||
alarm = Table(
|
||||
'alarm', meta,
|
||||
Column('id', String(255), primary_key=True, index=True),
|
||||
Column('enabled', Boolean),
|
||||
Column('name', Text()),
|
||||
Column('description', Text()),
|
||||
Column('timestamp', DateTime(timezone=False)),
|
||||
Column('counter_name', String(255), index=True),
|
||||
Column('user_id', String(255), index=True),
|
||||
Column('project_id', String(255), index=True),
|
||||
Column('comparison_operator', String(2)),
|
||||
Column('threshold', Float),
|
||||
Column('statistic', String(255)),
|
||||
Column('evaluation_periods', Integer),
|
||||
Column('period', Integer),
|
||||
Column('state', String(255)),
|
||||
Column('state_timestamp', DateTime(timezone=False)),
|
||||
Column('ok_actions', Text()),
|
||||
Column('alarm_actions', Text()),
|
||||
Column('insufficient_data_actions', Text()),
|
||||
Column('matching_metadata', Text()))
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta.bind = migrate_engine
|
||||
alarm.create()
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta.bind = migrate_engine
|
||||
alarm.drop()
|
@ -22,8 +22,8 @@ import json
|
||||
import urlparse
|
||||
|
||||
from oslo.config import cfg
|
||||
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime, \
|
||||
Float
|
||||
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime
|
||||
from sqlalchemy import Float, Boolean, Text
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.types import TypeDecorator, VARCHAR
|
||||
@ -74,6 +74,12 @@ class CeilometerBase(object):
|
||||
def __getitem__(self, key):
|
||||
return getattr(self, key)
|
||||
|
||||
def update(self, values):
|
||||
""" Make the model object behave like a dict
|
||||
"""
|
||||
for k, v in values.iteritems():
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
Base = declarative_base(cls=CeilometerBase)
|
||||
|
||||
@ -139,3 +145,32 @@ class Resource(Base):
|
||||
user_id = Column(String(255), ForeignKey('user.id'))
|
||||
project_id = Column(String(255), ForeignKey('project.id'))
|
||||
meters = relationship("Meter", backref='resource')
|
||||
|
||||
|
||||
class Alarm(Base):
|
||||
"""Alarm data"""
|
||||
__tablename__ = 'alarm'
|
||||
id = Column(String(255), primary_key=True)
|
||||
enabled = Column(Boolean)
|
||||
name = Column(Text)
|
||||
description = Column(Text)
|
||||
timestamp = Column(DateTime, default=timeutils.utcnow)
|
||||
counter_name = Column(Text)
|
||||
|
||||
user_id = Column(String(255), ForeignKey('user.id'))
|
||||
project_id = Column(String(255), ForeignKey('project.id'))
|
||||
|
||||
comparison_operator = Column(String(2))
|
||||
threshold = Column(Float)
|
||||
statistic = Column(String(255))
|
||||
evaluation_periods = Column(Integer)
|
||||
period = Column(Integer)
|
||||
|
||||
state = Column(String(255))
|
||||
state_timestamp = Column(DateTime, default=timeutils.utcnow)
|
||||
|
||||
ok_actions = Column(JSONEncodedDict)
|
||||
alarm_actions = Column(JSONEncodedDict)
|
||||
insufficient_data_actions = Column(JSONEncodedDict)
|
||||
|
||||
matching_metadata = Column(JSONEncodedDict)
|
||||
|
@ -61,6 +61,10 @@ class CounterDataTypeTest(base.CounterDataTypeTest, SQLAlchemyEngineTestBase):
|
||||
pass
|
||||
|
||||
|
||||
class AlarmTest(base.AlarmTest, SQLAlchemyEngineTestBase):
|
||||
pass
|
||||
|
||||
|
||||
def test_model_table_args():
|
||||
cfg.CONF.database_connection = 'mysql://localhost'
|
||||
assert table_args()
|
||||
|
Loading…
Reference in New Issue
Block a user