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
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import copy
|
|
||||||
import os
|
import os
|
||||||
|
import uuid
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
from ceilometer.openstack.common import timeutils
|
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 import models as api_models
|
||||||
from ceilometer.storage.sqlalchemy import migration
|
from ceilometer.storage.sqlalchemy import migration
|
||||||
from ceilometer.storage.sqlalchemy.models import Meter, Project, Resource
|
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
|
import ceilometer.storage.sqlalchemy.session as sqlalchemy_session
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
@ -412,18 +413,78 @@ class Connection(base.Connection):
|
|||||||
period_end=period_end,
|
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,
|
def get_alarms(self, name=None, user=None,
|
||||||
project=None, enabled=True, alarm_id=None):
|
project=None, enabled=True, alarm_id=None):
|
||||||
"""Yields a lists of alarms that match filters
|
"""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):
|
def update_alarm(self, alarm):
|
||||||
"""update 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):
|
def delete_alarm(self, alarm_id):
|
||||||
"""Delete a alarm
|
"""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
|
import urlparse
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime, \
|
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime
|
||||||
Float
|
from sqlalchemy import Float, Boolean, Text
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.types import TypeDecorator, VARCHAR
|
from sqlalchemy.types import TypeDecorator, VARCHAR
|
||||||
@ -74,6 +74,12 @@ class CeilometerBase(object):
|
|||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return getattr(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)
|
Base = declarative_base(cls=CeilometerBase)
|
||||||
|
|
||||||
@ -139,3 +145,32 @@ class Resource(Base):
|
|||||||
user_id = Column(String(255), ForeignKey('user.id'))
|
user_id = Column(String(255), ForeignKey('user.id'))
|
||||||
project_id = Column(String(255), ForeignKey('project.id'))
|
project_id = Column(String(255), ForeignKey('project.id'))
|
||||||
meters = relationship("Meter", backref='resource')
|
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
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AlarmTest(base.AlarmTest, SQLAlchemyEngineTestBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_model_table_args():
|
def test_model_table_args():
|
||||||
cfg.CONF.database_connection = 'mysql://localhost'
|
cfg.CONF.database_connection = 'mysql://localhost'
|
||||||
assert table_args()
|
assert table_args()
|
||||||
|
Loading…
Reference in New Issue
Block a user