summaryrefslogtreecommitdiff
path: root/nova/db
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-06-01 21:08:41 +0000
committerGerrit Code Review <review@openstack.org>2016-06-01 21:08:42 +0000
commit628fedc6fd75a121db010c664ea37aaf2a37ca24 (patch)
treeb387fe08402742803fa3a87aedce2a95038c2592 /nova/db
parentbfc5285b4684f6e459e6232ede58365fd9d50e34 (diff)
parent35748e7a9b3445a60522e088e38bf25e6bfef25e (diff)
downloadnova-628fedc6fd75a121db010c664ea37aaf2a37ca24.tar.gz
Merge "Add aggregates tables to the API db."
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/sqlalchemy/api_migrations/migrate_repo/versions/017_aggregates.py73
-rw-r--r--nova/db/sqlalchemy/api_models.py62
2 files changed, 135 insertions, 0 deletions
diff --git a/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/017_aggregates.py b/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/017_aggregates.py
new file mode 100644
index 0000000000..482a6aa9d0
--- /dev/null
+++ b/nova/db/sqlalchemy/api_migrations/migrate_repo/versions/017_aggregates.py
@@ -0,0 +1,73 @@
+# 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.
+"""API Database migrations for aggregates"""
+
+from migrate import UniqueConstraint
+from sqlalchemy import Column
+from sqlalchemy import DateTime
+from sqlalchemy import ForeignKey
+from sqlalchemy import Index
+from sqlalchemy import Integer
+from sqlalchemy import MetaData
+from sqlalchemy import String
+from sqlalchemy import Table
+
+
+def upgrade(migrate_engine):
+ meta = MetaData()
+ meta.bind = migrate_engine
+
+ aggregates = Table('aggregates', meta,
+ Column('created_at', DateTime),
+ Column('updated_at', DateTime),
+ Column('id', Integer, primary_key=True, nullable=False),
+ Column('uuid', String(length=36)),
+ Column('name', String(length=255)),
+ Index('aggregate_uuid_idx', 'uuid'),
+ UniqueConstraint('name', name='uniq_aggregate0name'),
+ mysql_engine='InnoDB',
+ mysql_charset='utf8'
+ )
+
+ aggregates.create(checkfirst=True)
+
+ aggregate_hosts = Table('aggregate_hosts', meta,
+ Column('created_at', DateTime),
+ Column('updated_at', DateTime),
+ Column('id', Integer, primary_key=True, nullable=False),
+ Column('host', String(length=255)),
+ Column('aggregate_id', Integer, ForeignKey('aggregates.id'),
+ nullable=False),
+ UniqueConstraint('host', 'aggregate_id',
+ name='uniq_aggregate_hosts0host0aggregate_id'),
+ mysql_engine='InnoDB',
+ mysql_charset='utf8'
+ )
+
+ aggregate_hosts.create(checkfirst=True)
+
+ aggregate_metadata = Table('aggregate_metadata', meta,
+ Column('created_at', DateTime),
+ Column('updated_at', DateTime),
+ Column('id', Integer, primary_key=True, nullable=False),
+ Column('aggregate_id', Integer, ForeignKey('aggregates.id'),
+ nullable=False),
+ Column('key', String(length=255), nullable=False),
+ Column('value', String(length=255), nullable=False),
+ UniqueConstraint('aggregate_id', 'key',
+ name='uniq_aggregate_metadata0aggregate_id0key'),
+ Index('aggregate_metadata_key_idx', 'key'),
+ mysql_engine='InnoDB',
+ mysql_charset='utf8'
+ )
+
+ aggregate_metadata.create(checkfirst=True)
diff --git a/nova/db/sqlalchemy/api_models.py b/nova/db/sqlalchemy/api_models.py
index b880b63075..e8bee347d7 100644
--- a/nova/db/sqlalchemy/api_models.py
+++ b/nova/db/sqlalchemy/api_models.py
@@ -35,6 +35,68 @@ class _NovaAPIBase(models.ModelBase, models.TimestampMixin):
API_BASE = declarative_base(cls=_NovaAPIBase)
+class AggregateHost(API_BASE):
+ """Represents a host that is member of an aggregate."""
+ __tablename__ = 'aggregate_hosts'
+ __table_args__ = (schema.UniqueConstraint(
+ "host", "aggregate_id",
+ name="uniq_aggregate_hosts0host0aggregate_id"
+ ),
+ )
+ id = Column(Integer, primary_key=True, autoincrement=True)
+ host = Column(String(255))
+ aggregate_id = Column(Integer, ForeignKey('aggregates.id'), nullable=False)
+
+
+class AggregateMetadata(API_BASE):
+ """Represents a metadata key/value pair for an aggregate."""
+ __tablename__ = 'aggregate_metadata'
+ __table_args__ = (
+ schema.UniqueConstraint("aggregate_id", "key",
+ name="uniq_aggregate_metadata0aggregate_id0key"
+ ),
+ Index('aggregate_metadata_key_idx', 'key'),
+ )
+ id = Column(Integer, primary_key=True)
+ key = Column(String(255), nullable=False)
+ value = Column(String(255), nullable=False)
+ aggregate_id = Column(Integer, ForeignKey('aggregates.id'), nullable=False)
+
+
+class Aggregate(API_BASE):
+ """Represents a cluster of hosts that exists in this zone."""
+ __tablename__ = 'aggregates'
+ __table_args__ = (Index('aggregate_uuid_idx', 'uuid'),
+ schema.UniqueConstraint(
+ "name", name="uniq_aggregate0name")
+ )
+ id = Column(Integer, primary_key=True, autoincrement=True)
+ uuid = Column(String(36))
+ name = Column(String(255))
+ _hosts = orm.relationship(AggregateHost,
+ primaryjoin='Aggregate.id == AggregateHost.aggregate_id')
+ _metadata = orm.relationship(AggregateMetadata,
+ primaryjoin='Aggregate.id == AggregateMetadata.aggregate_id')
+
+ @property
+ def _extra_keys(self):
+ return ['hosts', 'metadetails', 'availability_zone']
+
+ @property
+ def hosts(self):
+ return [h.host for h in self._hosts]
+
+ @property
+ def metadetails(self):
+ return {m.key: m.value for m in self._metadata}
+
+ @property
+ def availability_zone(self):
+ if 'availability_zone' not in self.metadetails:
+ return None
+ return self.metadetails['availability_zone']
+
+
class CellMapping(API_BASE):
"""Contains information on communicating with a cell"""
__tablename__ = 'cell_mappings'