designate/designate/storage/impl_sqlalchemy/models.py

198 lines
7.0 KiB
Python

# Copyright 2012 Hewlett-Packard Development Company, L.P.
# Copyright 2012 Managed I.T.
#
# Author: Kiall Mac Innes <kiall@managedit.ie>
# Modified: Patrick Galbraith <patg@hp.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.
import hashlib
from oslo.config import cfg
from oslo.db.sqlalchemy import models as oslo_models
from sqlalchemy import (Column, String, Text, Integer, ForeignKey,
Enum, Boolean, Unicode, UniqueConstraint, event)
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
from designate.openstack.common import timeutils
from designate.sqlalchemy.types import UUID
from designate.sqlalchemy import models
from designate import utils
CONF = cfg.CONF
RESOURCE_STATUSES = ['ACTIVE', 'PENDING', 'DELETED']
RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF', 'NS', 'PTR',
'SSHFP']
TSIG_ALGORITHMS = ['hmac-md5', 'hmac-sha1', 'hmac-sha224', 'hmac-sha256',
'hmac-sha384', 'hmac-sha512']
class Base(models.Base, oslo_models.TimestampMixin):
id = Column(UUID, default=utils.generate_uuid, primary_key=True)
version = Column(Integer, default=1, nullable=False)
__mapper_args__ = {
'version_id_col': version
}
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
Base = declarative_base(cls=Base)
class Quota(Base):
__tablename__ = 'quotas'
__table_args__ = (
UniqueConstraint('tenant_id', 'resource', name='unique_quota'),
{'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
)
tenant_id = Column(String(36), default=None, nullable=True)
resource = Column(String(32), nullable=False)
hard_limit = Column(Integer(), nullable=False)
class Server(Base):
__tablename__ = 'servers'
name = Column(String(255), nullable=False, unique=True)
class Tld(Base):
__tablename__ = 'tlds'
name = Column(String(255), nullable=False, unique=True)
description = Column(Unicode(160), nullable=True)
class Domain(models.SoftDeleteMixin, Base):
__tablename__ = 'domains'
__table_args__ = (
UniqueConstraint('name', 'deleted', name='unique_domain_name'),
{'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
)
tenant_id = Column(String(36), default=None, nullable=True)
name = Column(String(255), nullable=False)
email = Column(String(255), nullable=False)
description = Column(Unicode(160), nullable=True)
ttl = Column(Integer, default=CONF.default_ttl, nullable=False)
serial = Column(Integer, default=timeutils.utcnow_ts, nullable=False)
refresh = Column(Integer, default=CONF.default_soa_refresh, nullable=False)
retry = Column(Integer, default=CONF.default_soa_retry, nullable=False)
expire = Column(Integer, default=CONF.default_soa_expire, nullable=False)
minimum = Column(Integer, default=CONF.default_soa_minimum, nullable=False)
status = Column(Enum(name='resource_statuses', *RESOURCE_STATUSES),
nullable=False, server_default='ACTIVE',
default='ACTIVE')
recordsets = relationship('RecordSet',
backref=backref('domain', uselist=False),
cascade="all, delete-orphan",
passive_deletes=True)
parent_domain_id = Column(UUID, ForeignKey('domains.id'), default=None,
nullable=True)
class RecordSet(Base):
__tablename__ = 'recordsets'
__table_args__ = (
UniqueConstraint('domain_id', 'name', 'type', name='unique_recordset'),
{'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
)
tenant_id = Column(String(36), default=None, nullable=True)
domain_id = Column(UUID, ForeignKey('domains.id', ondelete='CASCADE'),
nullable=False)
name = Column(String(255), nullable=False)
type = Column(Enum(name='record_types', *RECORD_TYPES), nullable=False)
ttl = Column(Integer, default=None, nullable=True)
description = Column(Unicode(160), nullable=True)
records = relationship('Record',
backref=backref('recordset', uselist=False),
cascade="all, delete-orphan",
passive_deletes=True)
class Record(Base):
__tablename__ = 'records'
tenant_id = Column(String(36), default=None, nullable=True)
domain_id = Column(UUID, ForeignKey('domains.id', ondelete='CASCADE'),
nullable=False)
recordset_id = Column(UUID,
ForeignKey('recordsets.id', ondelete='CASCADE'),
nullable=False)
data = Column(Text, nullable=False)
priority = Column(Integer, default=None, nullable=True)
description = Column(Unicode(160), nullable=True)
hash = Column(String(32), nullable=False, unique=True)
managed = Column(Boolean, default=False)
managed_extra = Column(Unicode(100), default=None, nullable=True)
managed_plugin_type = Column(Unicode(50), default=None, nullable=True)
managed_plugin_name = Column(Unicode(50), default=None, nullable=True)
managed_resource_type = Column(Unicode(50), default=None, nullable=True)
managed_resource_region = Column(Unicode(100), default=None, nullable=True)
managed_resource_id = Column(UUID, default=None, nullable=True)
managed_tenant_id = Column(Unicode(36), default=None, nullable=True)
status = Column(Enum(name='resource_statuses', *RESOURCE_STATUSES),
nullable=False, server_default='ACTIVE',
default='ACTIVE')
def recalculate_hash(self):
"""
Calculates the hash of the record, used to ensure record uniqueness.
"""
md5 = hashlib.md5()
md5.update("%s:%s:%s" % (self.recordset_id, self.data, self.priority))
self.hash = md5.hexdigest()
@event.listens_for(Record, "before_insert")
def recalculate_record_hash_before_insert(mapper, connection, instance):
instance.recalculate_hash()
@event.listens_for(Record, "before_update")
def recalculate_record_hash_before_update(mapper, connection, instance):
instance.recalculate_hash()
class TsigKey(Base):
__tablename__ = 'tsigkeys'
name = Column(String(255), nullable=False, unique=True)
algorithm = Column(Enum(name='tsig_algorithms', *TSIG_ALGORITHMS),
nullable=False)
secret = Column(String(255), nullable=False)
class Blacklists(Base):
__tablename__ = 'blacklists'
pattern = Column(String(255), nullable=False, unique=True)
description = Column(Unicode(160), nullable=True)