bilean/bilean/db/sqlalchemy/models.py

239 lines
8.2 KiB
Python

#
# 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.
"""
SQLAlchemy models for Bilean data.
"""
import six
from bilean.db.sqlalchemy import types
from oslo_db.sqlalchemy import models
from oslo_utils import timeutils
from oslo_utils import uuidutils
import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref
from sqlalchemy.orm import relationship
from sqlalchemy.orm.session import Session
BASE = declarative_base()
UUID4 = uuidutils.generate_uuid
def get_session():
from bilean.db.sqlalchemy import api as db_api
return db_api.get_session()
class BileanBase(models.ModelBase):
"""Base class for Heat Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
def expire(self, session=None, attrs=None):
"""Expire this object ()."""
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.expire(self, attrs)
def refresh(self, session=None, attrs=None):
"""Refresh this object."""
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.refresh(self, attrs)
def delete(self, session=None):
"""Delete this object."""
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.delete(self)
session.flush()
def update_and_save(self, values, session=None):
if not session:
session = Session.object_session(self)
if not session:
session = get_session()
session.begin()
for k, v in six.iteritems(values):
setattr(self, k, v)
session.commit()
class SoftDelete(object):
deleted_at = sqlalchemy.Column(sqlalchemy.DateTime)
def soft_delete(self, session=None):
"""Mark this object as deleted."""
self.update_and_save({'deleted_at': timeutils.utcnow()},
session=session)
class StateAware(object):
status = sqlalchemy.Column('status', sqlalchemy.String(255))
status_reason = sqlalchemy.Column('status_reason', sqlalchemy.Text)
class User(BASE, BileanBase, SoftDelete, StateAware, models.TimestampMixin):
"""Represents a user to record account"""
__tablename__ = 'user'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True)
name = sqlalchemy.Column(sqlalchemy.String(255))
policy_id = sqlalchemy.Column(
sqlalchemy.String(36),
sqlalchemy.ForeignKey('policy.id'),
nullable=True)
balance = sqlalchemy.Column(sqlalchemy.Float, default=0.0)
rate = sqlalchemy.Column(sqlalchemy.Float, default=0.0)
credit = sqlalchemy.Column(sqlalchemy.Integer, default=0)
last_bill = sqlalchemy.Column(
sqlalchemy.DateTime, default=timeutils.utcnow())
class Policy(BASE, BileanBase, SoftDelete, models.TimestampMixin):
"""Represents a policy to collect rules."""
__tablename__ = 'policy'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
name = sqlalchemy.Column(sqlalchemy.String(255))
rules = sqlalchemy.Column(types.List)
is_default = sqlalchemy.Column(sqlalchemy.Boolean, default=False)
meta_data = sqlalchemy.Column(types.Dict)
class Rule(BASE, BileanBase, SoftDelete, models.TimestampMixin):
"""Represents a rule created to bill someone resource"""
__tablename__ = 'rule'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
name = sqlalchemy.Column(sqlalchemy.String(255))
type = sqlalchemy.Column(sqlalchemy.String(255))
spec = sqlalchemy.Column(types.Dict)
meta_data = sqlalchemy.Column(types.Dict)
class Resource(BASE, BileanBase, SoftDelete, models.TimestampMixin):
"""Represents a meta resource with rate"""
__tablename__ = 'resource'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True)
user_id = sqlalchemy.Column(
sqlalchemy.String(36),
sqlalchemy.ForeignKey('user.id'),
nullable=False)
rule_id = sqlalchemy.Column(
sqlalchemy.String(36),
sqlalchemy.ForeignKey('rule.id'),
nullable=True)
user = relationship(User, backref=backref('resources'))
resource_type = sqlalchemy.Column(sqlalchemy.String(36), nullable=False)
properties = sqlalchemy.Column(types.Dict)
rate = sqlalchemy.Column(sqlalchemy.Float, nullable=False)
class Action(BASE, BileanBase, StateAware, models.TimestampMixin):
"""Action objects."""
__tablename__ = 'action'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
name = sqlalchemy.Column(sqlalchemy.String(63))
context = sqlalchemy.Column(types.Dict)
target = sqlalchemy.Column(sqlalchemy.String(36))
action = sqlalchemy.Column(sqlalchemy.String(255))
cause = sqlalchemy.Column(sqlalchemy.String(255))
owner = sqlalchemy.Column(sqlalchemy.String(36))
start_time = sqlalchemy.Column(sqlalchemy.Float(precision='24,8'))
end_time = sqlalchemy.Column(sqlalchemy.Float(precision='24,8'))
timeout = sqlalchemy.Column(sqlalchemy.Integer)
inputs = sqlalchemy.Column(types.Dict)
outputs = sqlalchemy.Column(types.Dict)
data = sqlalchemy.Column(types.Dict)
class ActionDependency(BASE, BileanBase):
"""Action dependencies."""
__tablename__ = 'dependency'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
depended = sqlalchemy.Column(sqlalchemy.String(36),
sqlalchemy.ForeignKey('action.id'),
nullable=False)
dependent = sqlalchemy.Column(sqlalchemy.String(36),
sqlalchemy.ForeignKey('action.id'),
nullable=False)
class Event(BASE, BileanBase, SoftDelete):
"""Represents an event generated by the bilean engine."""
__tablename__ = 'event'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
user_id = sqlalchemy.Column(sqlalchemy.String(36),
sqlalchemy.ForeignKey('user.id'),
nullable=False)
user = relationship(User, backref=backref('events'))
action = sqlalchemy.Column(sqlalchemy.String(36))
timestamp = sqlalchemy.Column(sqlalchemy.DateTime)
resource_type = sqlalchemy.Column(sqlalchemy.String(36))
value = sqlalchemy.Column(sqlalchemy.Float)
class Job(BASE, BileanBase):
"""Represents a job for per user"""
__tablename__ = 'job'
id = sqlalchemy.Column(sqlalchemy.String(50), primary_key=True)
scheduler_id = sqlalchemy.Column(sqlalchemy.String(36))
job_type = sqlalchemy.Column(sqlalchemy.String(10))
parameters = sqlalchemy.Column(types.Dict)
class UserLock(BASE, BileanBase):
"""User locks for engines."""
__tablename__ = 'user_lock'
user_id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True)
action_id = sqlalchemy.Column(sqlalchemy.String(36))
class Service(BASE, BileanBase, models.TimestampMixin):
"""Service registry."""
__tablename__ = 'service'
id = sqlalchemy.Column(sqlalchemy.String(36), primary_key=True,
default=lambda: UUID4())
host = sqlalchemy.Column(sqlalchemy.String(255))
binary = sqlalchemy.Column(sqlalchemy.String(255))
topic = sqlalchemy.Column(sqlalchemy.String(255))
disabled = sqlalchemy.Column(sqlalchemy.Boolean, default=False)
disabled_reason = sqlalchemy.Column(sqlalchemy.String(255))