26
26
from sqlalchemy.ext.declarative import declarative_base
27
27
from sqlalchemy import ForeignKey, DateTime, Boolean, Text, Float
28
28
from sqlalchemy.orm import relationship, backref, object_mapper
29
from sqlalchemy.schema import ForeignKeyConstraint
31
30
from nova.db.sqlalchemy.session import get_session
32
31
from nova import exception
77
76
return getattr(self, key, default)
79
78
def __iter__(self):
80
self._i = iter(object_mapper(self).columns)
79
columns = dict(object_mapper(self).columns).keys()
80
# NOTE(russellb): Allow models to specify other keys that can be looked
81
# up, beyond the actual db columns. An example would be the 'name'
82
# property for an Instance.
83
if hasattr(self, '_extra_keys'):
84
columns.extend(self._extra_keys())
85
self._i = iter(columns)
84
n = self._i.next().name
85
90
return n, getattr(self, n)
87
92
def update(self, values):
184
189
except TypeError:
185
190
# Support templates like "uuid-%(uuid)s", etc.
187
for key, value in self.iteritems():
192
# NOTE(russellb): Don't use self.iteritems() here, as it will
193
# result in infinite recursion on the name property.
194
for column in iter(object_mapper(self).columns):
188
196
# prevent recursion if someone specifies %(name)s
189
197
# %(name)s will not be valid.
190
198
if key == 'name':
200
info[key] = self[key]
194
202
base_name = FLAGS.instance_name_template % info
196
204
base_name = self.uuid
197
if getattr(self, '_rescue', False):
198
base_name += "-rescue"
207
def _extra_keys(self):
201
210
user_id = Column(String(255))
202
211
project_id = Column(String(255))
211
220
# ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True)
212
221
# ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id))
213
222
# kernel = relationship(Kernel, backref=backref('instances', order_by=id))
214
# project = relationship(Project, backref=backref('instances', order_by=id))
216
224
launch_index = Column(Integer)
217
225
key_name = Column(String(255))
464
472
uuid = Column(String(36), nullable=False)
466
474
usage_id = Column(Integer, ForeignKey('quota_usages.id'), nullable=False)
467
# NOTE(dprince): Force innerjoin below for lockmode update on PostgreSQL
468
usage = relationship(QuotaUsage,
469
backref=backref('reservations'),
470
foreign_keys=usage_id,
473
'Reservation.usage_id == QuotaUsage.id,'
474
'Reservation.deleted == False)')
476
476
project_id = Column(String(255), index=True)
477
477
resource = Column(String(255))
703
703
id = Column(Integer, primary_key=True)
704
704
address = Column(String(255), unique=True)
705
705
network_id = Column(Integer, nullable=False)
706
instance_id = Column(Integer, nullable=False)
706
instance_uuid = Column(String(36), nullable=False)
707
707
uuid = Column(String(36))
715
715
address = Column(String(255))
716
716
network_id = Column(Integer, nullable=True)
717
717
virtual_interface_id = Column(Integer, nullable=True)
718
instance_id = Column(Integer, nullable=True)
718
instance_uuid = Column(String(36), nullable=True)
719
719
# associated means that a fixed_ip has its instance_id column set
720
720
# allocated means that a fixed_ip has its virtual_interface_id column set
721
721
allocated = Column(Boolean, default=False)
738
738
interface = Column(String(255))
741
class AuthToken(BASE, NovaBase):
742
"""Represents an authorization token for all API transactions.
744
Fields are a string representing the actual token and a user id for
745
mapping to the actual user
748
__tablename__ = 'auth_tokens'
749
token_hash = Column(String(255), primary_key=True)
750
user_id = Column(String(255))
751
server_management_url = Column(String(255))
752
storage_url = Column(String(255))
753
cdn_management_url = Column(String(255))
756
class User(BASE, NovaBase):
757
"""Represents a user."""
758
__tablename__ = 'users'
759
id = Column(String(255), primary_key=True)
761
name = Column(String(255))
762
access_key = Column(String(255))
763
secret_key = Column(String(255))
765
is_admin = Column(Boolean)
768
class Project(BASE, NovaBase):
769
"""Represents a project."""
770
__tablename__ = 'projects'
771
id = Column(String(255), primary_key=True)
772
name = Column(String(255))
773
description = Column(String(255))
775
project_manager = Column(String(255), ForeignKey(User.id))
777
members = relationship(User,
778
secondary='user_project_association',
782
741
class DNSDomain(BASE, NovaBase):
783
742
"""Represents a DNS domain with availability zone or project info."""
784
743
__tablename__ = 'dns_domains'
786
745
scope = Column(String(255))
787
746
availability_zone = Column(String(255))
788
747
project_id = Column(String(255))
789
project = relationship(Project,
790
primaryjoin=project_id == Project.id,
791
foreign_keys=[Project.id],
795
class UserProjectRoleAssociation(BASE, NovaBase):
796
__tablename__ = 'user_project_role_association'
797
user_id = Column(String(255), primary_key=True)
798
user = relationship(User,
799
primaryjoin=user_id == User.id,
800
foreign_keys=[User.id],
803
project_id = Column(String(255), primary_key=True)
804
project = relationship(Project,
805
primaryjoin=project_id == Project.id,
806
foreign_keys=[Project.id],
809
role = Column(String(255), primary_key=True)
810
ForeignKeyConstraint(['user_id',
812
['user_project_association.user_id',
813
'user_project_association.project_id'])
816
class UserRoleAssociation(BASE, NovaBase):
817
__tablename__ = 'user_role_association'
818
user_id = Column(String(255), ForeignKey('users.id'), primary_key=True)
819
user = relationship(User, backref='roles')
820
role = Column(String(255), primary_key=True)
823
class UserProjectAssociation(BASE, NovaBase):
824
__tablename__ = 'user_project_association'
825
user_id = Column(String(255), ForeignKey(User.id), primary_key=True)
826
project_id = Column(String(255), ForeignKey(Project.id), primary_key=True)
829
750
class ConsolePool(BASE, NovaBase):
903
824
"""Represents a host that is member of an aggregate."""
904
825
__tablename__ = 'aggregate_hosts'
905
826
id = Column(Integer, primary_key=True, autoincrement=True)
906
host = Column(String(255), unique=True)
827
host = Column(String(255), unique=False)
907
828
aggregate_id = Column(Integer, ForeignKey('aggregates.id'), nullable=False)
921
842
__tablename__ = 'aggregates'
922
843
id = Column(Integer, primary_key=True, autoincrement=True)
923
844
name = Column(String(255), unique=True)
924
operational_state = Column(String(255), nullable=False)
925
845
availability_zone = Column(String(255), nullable=False)
926
846
_hosts = relationship(AggregateHost,
927
848
secondary="aggregate_hosts",
928
849
primaryjoin='and_('
929
850
'Aggregate.id == AggregateHost.aggregate_id,'
990
911
class VolumeIdMapping(BASE, NovaBase):
991
"""Compatability layer for the EC2 volume service"""
912
"""Compatibility layer for the EC2 volume service"""
992
913
__tablename__ = 'volume_id_mappings'
993
914
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
994
915
uuid = Column(String(36), nullable=False)
997
918
class SnapshotIdMapping(BASE, NovaBase):
998
"""Compatability layer for the EC2 snapshot service"""
919
"""Compatibility layer for the EC2 snapshot service"""
999
920
__tablename__ = 'snapshot_id_mappings'
1000
921
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
1001
922
uuid = Column(String(36), nullable=False)
1043
964
__tablename__ = 'instance_id_mappings'
1044
965
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
1045
966
uuid = Column(String(36), nullable=False)
969
class TaskLog(BASE, NovaBase):
970
"""Audit log for background periodic tasks"""
971
__tablename__ = 'task_log'
972
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
973
task_name = Column(String(255), nullable=False)
974
state = Column(String(255), nullable=False)
975
host = Column(String(255))
976
period_beginning = Column(String(255), default=timeutils.utcnow)
977
period_ending = Column(String(255), default=timeutils.utcnow)
978
message = Column(String(255), nullable=False)
979
task_items = Column(Integer(), default=0)
980
errors = Column(Integer(), default=0)