rename neutron/db to tacker/db

Change-Id: Iade9d9ef557c29d1f13cf631c8df16bd5d9be4cd
This commit is contained in:
Isaku Yamahata 2014-06-26 17:04:20 +09:00
parent 6125f5fcab
commit b307e8a7c6
19 changed files with 289 additions and 1944 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
2db5203cb7a9

View File

@ -1,5 +0,0 @@
This directory contains the migration scripts for the Neutron project. Please
see the README in neutron/db/migration on how to use and generate new
migrations.

View File

@ -1,204 +0,0 @@
# Copyright (c) 2012 OpenStack Foundation.
# All Rights Reserved.
#
# 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 sqlalchemy as sa
from sqlalchemy import orm
from neutron.common import constants
from neutron.db import model_base
from neutron.openstack.common import uuidutils
class HasTenant(object):
"""Tenant mixin, add to subclasses that have a tenant."""
# NOTE(jkoelker) tenant_id is just a free form string ;(
tenant_id = sa.Column(sa.String(255))
class HasId(object):
"""id mixin, add to subclasses that have an id."""
id = sa.Column(sa.String(36),
primary_key=True,
default=uuidutils.generate_uuid)
class HasStatusDescription(object):
"""Status with description mixin."""
status = sa.Column(sa.String(16), nullable=False)
status_description = sa.Column(sa.String(255))
class IPAvailabilityRange(model_base.BASEV2):
"""Internal representation of available IPs for Neutron subnets.
Allocation - first entry from the range will be allocated.
If the first entry is equal to the last entry then this row
will be deleted.
Recycling ips involves reading the IPAllocationPool and IPAllocation tables
and inserting ranges representing available ips. This happens after the
final allocation is pulled from this table and a new ip allocation is
requested. Any contiguous ranges of available ips will be inserted as a
single range.
"""
allocation_pool_id = sa.Column(sa.String(36),
sa.ForeignKey('ipallocationpools.id',
ondelete="CASCADE"),
nullable=False,
primary_key=True)
first_ip = sa.Column(sa.String(64), nullable=False, primary_key=True)
last_ip = sa.Column(sa.String(64), nullable=False, primary_key=True)
def __repr__(self):
return "%s - %s" % (self.first_ip, self.last_ip)
class IPAllocationPool(model_base.BASEV2, HasId):
"""Representation of an allocation pool in a Neutron subnet."""
subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id',
ondelete="CASCADE"),
nullable=True)
first_ip = sa.Column(sa.String(64), nullable=False)
last_ip = sa.Column(sa.String(64), nullable=False)
available_ranges = orm.relationship(IPAvailabilityRange,
backref='ipallocationpool',
lazy="joined",
cascade='all, delete-orphan')
def __repr__(self):
return "%s - %s" % (self.first_ip, self.last_ip)
class IPAllocation(model_base.BASEV2):
"""Internal representation of allocated IP addresses in a Neutron subnet.
"""
port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id',
ondelete="CASCADE"),
nullable=True)
ip_address = sa.Column(sa.String(64), nullable=False, primary_key=True)
subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id',
ondelete="CASCADE"),
nullable=False, primary_key=True)
network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id",
ondelete="CASCADE"),
nullable=False, primary_key=True)
class Route(object):
"""mixin of a route."""
destination = sa.Column(sa.String(64), nullable=False, primary_key=True)
nexthop = sa.Column(sa.String(64), nullable=False, primary_key=True)
class SubnetRoute(model_base.BASEV2, Route):
subnet_id = sa.Column(sa.String(36),
sa.ForeignKey('subnets.id',
ondelete="CASCADE"),
primary_key=True)
class Port(model_base.BASEV2, HasId, HasTenant):
"""Represents a port on a Neutron v2 network."""
name = sa.Column(sa.String(255))
network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"),
nullable=False)
fixed_ips = orm.relationship(IPAllocation, backref='ports', lazy='joined')
mac_address = sa.Column(sa.String(32), nullable=False)
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
status = sa.Column(sa.String(16), nullable=False)
device_id = sa.Column(sa.String(255), nullable=False)
device_owner = sa.Column(sa.String(255), nullable=False)
def __init__(self, id=None, tenant_id=None, name=None, network_id=None,
mac_address=None, admin_state_up=None, status=None,
device_id=None, device_owner=None, fixed_ips=None):
self.id = id
self.tenant_id = tenant_id
self.name = name
self.network_id = network_id
self.mac_address = mac_address
self.admin_state_up = admin_state_up
self.device_owner = device_owner
self.device_id = device_id
# Since this is a relationship only set it if one is passed in.
if fixed_ips:
self.fixed_ips = fixed_ips
# NOTE(arosen): status must be set last as an event is triggered on!
self.status = status
class DNSNameServer(model_base.BASEV2):
"""Internal representation of a DNS nameserver."""
address = sa.Column(sa.String(128), nullable=False, primary_key=True)
subnet_id = sa.Column(sa.String(36),
sa.ForeignKey('subnets.id',
ondelete="CASCADE"),
primary_key=True)
class Subnet(model_base.BASEV2, HasId, HasTenant):
"""Represents a neutron subnet.
When a subnet is created the first and last entries will be created. These
are used for the IP allocation.
"""
name = sa.Column(sa.String(255))
network_id = sa.Column(sa.String(36), sa.ForeignKey('networks.id'))
ip_version = sa.Column(sa.Integer, nullable=False)
cidr = sa.Column(sa.String(64), nullable=False)
gateway_ip = sa.Column(sa.String(64))
allocation_pools = orm.relationship(IPAllocationPool,
backref='subnet',
lazy="joined",
cascade='delete')
enable_dhcp = sa.Column(sa.Boolean())
dns_nameservers = orm.relationship(DNSNameServer,
backref='subnet',
cascade='all, delete, delete-orphan')
routes = orm.relationship(SubnetRoute,
backref='subnet',
cascade='all, delete, delete-orphan')
shared = sa.Column(sa.Boolean)
ipv6_ra_mode = sa.Column(sa.Enum(constants.IPV6_SLAAC,
constants.DHCPV6_STATEFUL,
constants.DHCPV6_STATELESS,
name='ipv6_ra_modes'), nullable=True)
ipv6_address_mode = sa.Column(sa.Enum(constants.IPV6_SLAAC,
constants.DHCPV6_STATEFUL,
constants.DHCPV6_STATELESS,
name='ipv6_address_modes'), nullable=True)
class Network(model_base.BASEV2, HasId, HasTenant):
"""Represents a v2 neutron network."""
name = sa.Column(sa.String(255))
ports = orm.relationship(Port, backref='networks')
subnets = orm.relationship(Subnet, backref='networks',
lazy="joined")
status = sa.Column(sa.String(16))
admin_state_up = sa.Column(sa.Boolean)
shared = sa.Column(sa.Boolean)

View File

@ -16,16 +16,14 @@
from oslo.config import cfg
import sqlalchemy as sql
from neutron.db import model_base
from neutron.openstack.common.db.sqlalchemy import session
from neutron.openstack.common import log as logging
from tacker.db import model_base
from tacker.openstack.common.db.sqlalchemy import session
from tacker.openstack.common import log as logging
LOG = logging.getLogger(__name__)
BASE = model_base.BASEV2
cfg.CONF.import_opt('connection',
'neutron.openstack.common.db.options',
'tacker.openstack.common.db.options',
group='database')
_FACADE = None
@ -50,7 +48,7 @@ def configure_db():
register_models()
def clear_db(base=BASE):
def clear_db(base=model_base.BASE):
unregister_models(base)
@ -67,7 +65,7 @@ def get_session(autocommit=True, expire_on_commit=False):
expire_on_commit=expire_on_commit)
def register_models(base=BASE):
def register_models(base=model_base.BASE):
"""Register Models and create properties."""
try:
facade = _create_facade_lazily()
@ -79,7 +77,7 @@ def register_models(base=BASE):
return True
def unregister_models(base=BASE):
def unregister_models(base=model_base.BASE):
"""Unregister Models, useful clearing out data before testing."""
try:
facade = _create_facade_lazily()

199
tacker/db/db_base.py Normal file
View File

@ -0,0 +1,199 @@
# Copyright (c) 2012 OpenStack Foundation.
# All Rights Reserved.
#
# 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 weakref
from sqlalchemy import sql
from tacker.common import exceptions as n_exc
from tacker.db import sqlalchemyutils
from tacker.openstack.common import log as logging
LOG = logging.getLogger(__name__)
class CommonDbMixin(object):
"""Common methods used in core and service plugins."""
# Plugins, mixin classes implementing extension will register
# hooks into the dict below for "augmenting" the "core way" of
# building a query for retrieving objects from a model class.
# To this aim, the register_model_query_hook and unregister_query_hook
# from this class should be invoked
_model_query_hooks = {}
# This dictionary will store methods for extending attributes of
# api resources. Mixins can use this dict for adding their own methods
# TODO(salvatore-orlando): Avoid using class-level variables
_dict_extend_functions = {}
@classmethod
def register_model_query_hook(cls, model, name, query_hook, filter_hook,
result_filters=None):
"""Register a hook to be invoked when a query is executed.
Add the hooks to the _model_query_hooks dict. Models are the keys
of this dict, whereas the value is another dict mapping hook names to
callables performing the hook.
Each hook has a "query" component, used to build the query expression
and a "filter" component, which is used to build the filter expression.
Query hooks take as input the query being built and return a
transformed query expression.
Filter hooks take as input the filter expression being built and return
a transformed filter expression
"""
model_hooks = cls._model_query_hooks.get(model)
if not model_hooks:
# add key to dict
model_hooks = {}
cls._model_query_hooks[model] = model_hooks
model_hooks[name] = {'query': query_hook, 'filter': filter_hook,
'result_filters': result_filters}
@property
def safe_reference(self):
"""Return a weakref to the instance.
Minimize the potential for the instance persisting
unnecessarily in memory by returning a weakref proxy that
won't prevent deallocation.
"""
return weakref.proxy(self)
def _model_query(self, context, model):
query = context.session.query(model)
# define basic filter condition for model query
# NOTE(jkoelker) non-admin queries are scoped to their tenant_id
# NOTE(salvatore-orlando): unless the model allows for shared objects
query_filter = None
if not context.is_admin and hasattr(model, 'tenant_id'):
if hasattr(model, 'shared'):
query_filter = ((model.tenant_id == context.tenant_id) |
(model.shared == sql.true()))
else:
query_filter = (model.tenant_id == context.tenant_id)
# Execute query hooks registered from mixins and plugins
for _name, hooks in self._model_query_hooks.get(model,
{}).iteritems():
query_hook = hooks.get('query')
if isinstance(query_hook, basestring):
query_hook = getattr(self, query_hook, None)
if query_hook:
query = query_hook(context, model, query)
filter_hook = hooks.get('filter')
if isinstance(filter_hook, basestring):
filter_hook = getattr(self, filter_hook, None)
if filter_hook:
query_filter = filter_hook(context, model, query_filter)
# NOTE(salvatore-orlando): 'if query_filter' will try to evaluate the
# condition, raising an exception
if query_filter is not None:
query = query.filter(query_filter)
return query
def _fields(self, resource, fields):
if fields:
return dict(((key, item) for key, item in resource.items()
if key in fields))
return resource
def _get_tenant_id_for_create(self, context, resource):
if context.is_admin and 'tenant_id' in resource:
tenant_id = resource['tenant_id']
elif ('tenant_id' in resource and
resource['tenant_id'] != context.tenant_id):
reason = _('Cannot create resource for another tenant')
raise n_exc.AdminRequired(reason=reason)
else:
tenant_id = context.tenant_id
return tenant_id
def _get_by_id(self, context, model, id):
query = self._model_query(context, model)
return query.filter(model.id == id).one()
def _apply_filters_to_query(self, query, model, filters):
if filters:
for key, value in filters.iteritems():
column = getattr(model, key, None)
if column:
query = query.filter(column.in_(value))
for _name, hooks in self._model_query_hooks.get(model,
{}).iteritems():
result_filter = hooks.get('result_filters', None)
if isinstance(result_filter, basestring):
result_filter = getattr(self, result_filter, None)
if result_filter:
query = result_filter(query, filters)
return query
def _apply_dict_extend_functions(self, resource_type,
response, db_object):
for func in self._dict_extend_functions.get(
resource_type, []):
args = (response, db_object)
if isinstance(func, basestring):
func = getattr(self, func, None)
else:
# must call unbound method - use self as 1st argument
args = (self,) + args
if func:
func(*args)
def _get_collection_query(self, context, model, filters=None,
sorts=None, limit=None, marker_obj=None,
page_reverse=False):
collection = self._model_query(context, model)
collection = self._apply_filters_to_query(collection, model, filters)
if limit and page_reverse and sorts:
sorts = [(s[0], not s[1]) for s in sorts]
collection = sqlalchemyutils.paginate_query(collection, model, limit,
sorts,
marker_obj=marker_obj)
return collection
def _get_collection(self, context, model, dict_func, filters=None,
fields=None, sorts=None, limit=None, marker_obj=None,
page_reverse=False):
query = self._get_collection_query(context, model, filters=filters,
sorts=sorts,
limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
items = [dict_func(c, fields) for c in query]
if limit and page_reverse:
items.reverse()
return items
def _get_collection_count(self, context, model, filters=None):
return self._get_collection_query(context, model, filters).count()
def _get_marker_obj(self, context, resource, limit, marker):
if limit and marker:
return getattr(self, '_get_%s' % resource)(context, marker)
return None
def _filter_non_model_columns(self, data, model):
"""Remove all the attributes from data which are not columns of
the model passed as second parameter.
"""
columns = [c.name for c in model.__table__.columns]
return dict((k, v) for (k, v) in
data.iteritems() if k in columns)

View File

@ -15,56 +15,56 @@
# @author Mark McClain (DreamHost)
The migrations in the alembic/versions contain the changes needed to migrate
from older Neutron releases to newer versions. A migration occurs by executing
from older Tacker releases to newer versions. A migration occurs by executing
a script that details the changes needed to upgrade/downgrade the database. The
migration scripts are ordered so that multiple scripts can run sequentially to
update the database. The scripts are executed by Neutron's migration wrapper
which uses the Alembic library to manage the migration. Neutron supports
update the database. The scripts are executed by Tacker's migration wrapper
which uses the Alembic library to manage the migration. Tacker supports
migration from Folsom or later.
If you are a deployer or developer and want to migrate from Folsom to Grizzly
or later you must first add version tracking to the database:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini stamp folsom
You can then upgrade to the latest database version via:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini upgrade head
To check the current database version:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini current
To create a script to run the migration offline:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini upgrade head --sql
To run the offline migration between specific migration versions:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini upgrade \
<start version>:<end version> --sql
Upgrade the database incrementally:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini upgrade --delta <# of revs>
Downgrade the database by a certain number of revisions:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini downgrade --delta <# of revs>
DEVELOPERS:
A database migration script is required when you submit a change to Neutron
A database migration script is required when you submit a change to Tacker
that alters the database model definition. The migration script is a special
python file that includes code to update/downgrade the database to match the
changes in the model definition. Alembic will execute these scripts in order to
provide a linear migration path between revision. The neutron-db-manage command
provide a linear migration path between revision. The tacker-db-manage command
can be used to generate migration template for you to complete. The operations
in the template are those supported by the Alembic migration library.
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini revision \
-m "description of revision" \
--autogenerate
@ -77,16 +77,16 @@ In rare circumstances, you may want to start with an empty migration template
and manually author the changes necessary for an upgrade/downgrade. You can
create a blank file via:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini revision \
-m "description of revision"
The migration timeline should remain linear so that there is a clear path when
upgrading/downgrading. To verify that the timeline does branch, you can run
this command:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini check_migration
If the migration path does branch, you can find the branch point via:
$ neutron-db-manage --config-file /path/to/neutron.conf \
$ tacker-db-manage --config-file /path/to/tacker.conf \
--config-file /path/to/plugin/config.ini history

View File

@ -17,20 +17,6 @@
from alembic import op
import sqlalchemy as sa
OVS_PLUGIN = ('neutron.plugins.openvswitch.ovs_neutron_plugin'
'.OVSNeutronPluginV2')
CISCO_PLUGIN = 'neutron.plugins.cisco.network_plugin.PluginV2'
def should_run(active_plugins, migrate_plugins):
if '*' in migrate_plugins:
return True
else:
if (CISCO_PLUGIN not in migrate_plugins and
OVS_PLUGIN in migrate_plugins):
migrate_plugins.append(CISCO_PLUGIN)
return set(active_plugins) & set(migrate_plugins)
def alter_enum(table, column, enum_type, nullable):
bind = op.get_bind()

View File

@ -11,7 +11,7 @@ script_location = %(here)s/alembic
# the 'revision' command, regardless of autogenerate
# revision_environment = false
# default to an empty string because the Neutron migration cli will
# default to an empty string because the Tacker migration cli will
# extract the correct value and set it programatically before alemic is fully
# invoked.
sqlalchemy.url =

View File

@ -19,30 +19,20 @@ from logging import config as logging_config
from alembic import context
from sqlalchemy import create_engine, pool
from neutron.db import model_base
from neutron.openstack.common import importutils
from tacker.db import model_base
DATABASE_QUOTA_DRIVER = 'neutron.extensions._quotav2_driver.DbQuotaDriver'
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
neutron_config = config.neutron_config
tacker_config = config.tacker_config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
logging_config.fileConfig(config.config_file_name)
plugin_class_path = neutron_config.core_plugin
active_plugins = [plugin_class_path]
active_plugins += neutron_config.service_plugins
for class_path in active_plugins:
importutils.import_class(class_path)
# set the target for 'autogenerate' support
target_metadata = model_base.BASEV2.metadata
target_metadata = model_base.BASE.metadata
def run_migrations_offline():
@ -56,15 +46,14 @@ def run_migrations_offline():
"""
kwargs = dict()
if neutron_config.database.connection:
kwargs['url'] = neutron_config.database.connection
if tacker_config.database.connection:
kwargs['url'] = tacker_config.database.connection
else:
kwargs['dialect_name'] = neutron_config.database.engine
kwargs['dialect_name'] = tacker_config.database.engine
context.configure(**kwargs)
with context.begin_transaction():
context.run_migrations(active_plugins=active_plugins,
options=build_options())
context.run_migrations()
def run_migrations_online():
@ -75,7 +64,7 @@ def run_migrations_online():
"""
engine = create_engine(
neutron_config.database.connection,
tacker_config.database.connection,
poolclass=pool.NullPool)
connection = engine.connect()
@ -86,20 +75,11 @@ def run_migrations_online():
try:
with context.begin_transaction():
context.run_migrations(active_plugins=active_plugins,
options=build_options())
context.run_migrations()
finally:
connection.close()
def build_options():
return {'folsom_quota_db_enabled': is_db_quota_enabled()}
def is_db_quota_enabled():
return neutron_config.QUOTAS.quota_driver == DATABASE_QUOTA_DRIVER
if context.is_offline_mode():
run_migrations_offline()
else:

View File

@ -25,28 +25,16 @@ Create Date: ${create_date}
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
# Change to ['*'] if this migration applies to all plugins
migration_for_plugins = [
'${config.neutron_config.core_plugin}'
]
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
from neutron.db import migration
from tacker.db import migration
def upgrade(active_plugins=None, options=None):
if not migration.should_run(active_plugins, migration_for_plugins):
return
${upgrades if upgrades else "pass"}
def downgrade(active_plugins=None, options=None):
if not migration.should_run(active_plugins, migration_for_plugins):
return
${downgrades if downgrades else "pass"}

View File

@ -0,0 +1 @@
81ffa86020d

View File

@ -0,0 +1,5 @@
This directory contains the migration scripts for the Tacker project. Please
see the README in tacker/db/migration on how to use and generate new
migrations.

View File

@ -26,21 +26,6 @@ from oslo.config import cfg
HEAD_FILENAME = 'HEAD'
_core_opts = [
cfg.StrOpt('core_plugin',
default='',
help=_('Neutron plugin provider module')),
cfg.ListOpt('service_plugins',
default=[],
help=_("The service plugins Neutron will use")),
]
_quota_opts = [
cfg.StrOpt('quota_driver',
default='',
help=_('Neutron quota driver class')),
]
_db_opts = [
cfg.StrOpt('connection',
deprecated_name='sql_connection',
@ -53,9 +38,7 @@ _db_opts = [
]
CONF = cfg.ConfigOpts()
CONF.register_cli_opts(_core_opts)
CONF.register_cli_opts(_db_opts, 'database')
CONF.register_opts(_quota_opts, 'QUOTAS')
def do_alembic_command(config, cmd, *args, **kwargs):
@ -162,9 +145,9 @@ def main():
os.path.join(os.path.dirname(__file__), 'alembic.ini')
)
config.set_main_option('script_location',
'neutron.db.migration:alembic_migrations')
# attach the Neutron conf to the Alembic conf
config.neutron_config = CONF
'tacker.db.migration:alembic_migrations')
# attach the Tacker conf to the Alembic conf
config.tacker_config = CONF
CONF()
#TODO(gongysh) enable logging

View File

@ -16,11 +16,11 @@
from sqlalchemy.ext import declarative
from sqlalchemy import orm
from neutron.openstack.common.db.sqlalchemy import models
from tacker.openstack.common.db.sqlalchemy import models
class NeutronBase(models.ModelBase):
"""Base class for Neutron Models."""
class TackerBase(models.ModelBase):
"""Base class for Tacker Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
@ -41,7 +41,7 @@ class NeutronBase(models.ModelBase):
id(self), ', '.join(items))
class NeutronBaseV2(NeutronBase):
class TackerBaseV1(TackerBase):
@declarative.declared_attr
def __tablename__(cls):
@ -49,4 +49,4 @@ class NeutronBaseV2(NeutronBase):
return cls.__name__.lower() + 's'
BASEV2 = declarative.declarative_base(cls=NeutronBaseV2)
BASE = declarative.declarative_base(cls=TackerBaseV1)

40
tacker/db/models_v2.py Normal file
View File

@ -0,0 +1,40 @@
# Copyright (c) 2012 OpenStack Foundation.
# All Rights Reserved.
#
# 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 sqlalchemy as sa
from tacker.openstack.common import uuidutils
class HasTenant(object):
"""Tenant mixin, add to subclasses that have a tenant."""
# NOTE(jkoelker) tenant_id is just a free form string ;(
tenant_id = sa.Column(sa.String(255))
class HasId(object):
"""id mixin, add to subclasses that have an id."""
id = sa.Column(sa.String(36),
primary_key=True,
default=uuidutils.generate_uuid)
class HasStatusDescription(object):
"""Status with description mixin."""
status = sa.Column(sa.String(16), nullable=False)
status_description = sa.Column(sa.String(255))

View File

@ -17,8 +17,8 @@ from six import moves
import sqlalchemy
from sqlalchemy.orm.properties import RelationshipProperty
from neutron.common import exceptions as n_exc
from neutron.openstack.common import log as logging
from tacker.common import exceptions as n_exc
from tacker.openstack.common import log as logging
LOG = logging.getLogger(__name__)