Coverage for manila/db/sqlalchemy/models.py: 95%
771 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
2# Copyright 2010 United States Government as represented by the
3# Administrator of the National Aeronautics and Space Administration.
4# Copyright 2011 Piston Cloud Computing, Inc.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18"""
19SQLAlchemy models for Manila data.
20"""
22from oslo_config import cfg
23from oslo_db.sqlalchemy import models
24from sqlalchemy import Column, Integer, String, schema
25from sqlalchemy import orm
26from sqlalchemy import ForeignKey, DateTime, Boolean, Enum
27from sqlalchemy_utils import generic_repr
29from manila.common import constants
31CONF = cfg.CONF
32BASE = orm.declarative_base()
35@generic_repr
36class ManilaBase(models.ModelBase,
37 models.TimestampMixin,
38 models.SoftDeleteMixin):
39 """Base class for Manila Models."""
40 __table_args__ = {'mysql_engine': 'InnoDB'}
41 metadata = None
43 def to_dict(self):
44 model_dict = {}
45 for k, v in self.items():
46 if not issubclass(type(v), ManilaBase):
47 model_dict[k] = v
48 return model_dict
50 def soft_delete(self, session, update_status=False,
51 status_field_name='status'):
52 """Mark this object as deleted."""
53 if update_status:
54 setattr(self, status_field_name, constants.STATUS_DELETED)
56 return super(ManilaBase, self).soft_delete(session)
59class Service(BASE, ManilaBase):
60 """Represents a running service on a host."""
62 __tablename__ = 'services'
63 id = Column(Integer, primary_key=True)
64 host = Column(String(255)) # , ForeignKey('hosts.id'))
65 binary = Column(String(255))
66 topic = Column(String(255))
67 state = Column(String(36))
68 report_count = Column(Integer, nullable=False, default=0)
69 disabled = Column(Boolean, default=False)
70 disabled_reason = Column(String(255))
71 availability_zone_id = Column(String(36),
72 ForeignKey('availability_zones.id'),
73 nullable=True)
74 ensuring = Column(Boolean, default=False)
76 availability_zone = orm.relationship(
77 "AvailabilityZone",
78 lazy='immediate',
79 primaryjoin=(
80 'and_('
81 'Service.availability_zone_id == '
82 'AvailabilityZone.id, '
83 'AvailabilityZone.deleted == \'False\')'
84 )
85 )
88class Quota(BASE, ManilaBase):
89 """Represents a single quota override for a project.
91 If there is no row for a given project id and resource, then the
92 default for the quota class is used. If there is no row for a
93 given quota class and resource, then the default for the
94 deployment is used. If the row is present but the hard limit is
95 Null, then the resource is unlimited.
96 """
98 __tablename__ = 'quotas'
99 id = Column(Integer, primary_key=True)
101 project_id = Column(String(255), index=True)
103 resource = Column(String(255))
105 hard_limit = Column(Integer, nullable=True)
108class ProjectUserQuota(BASE, ManilaBase):
109 """Represents a single quota override for a user with in a project."""
111 __tablename__ = 'project_user_quotas'
112 id = Column(Integer, primary_key=True, nullable=False)
114 project_id = Column(String(255), nullable=False)
115 user_id = Column(String(255), nullable=False)
117 resource = Column(String(255), nullable=False)
119 hard_limit = Column(Integer)
122class ProjectShareTypeQuota(BASE, ManilaBase):
123 """Represents a single quota override for a share type within a project."""
125 __tablename__ = 'project_share_type_quotas'
126 id = Column(Integer, primary_key=True, nullable=False)
127 project_id = Column(String(255), nullable=False)
128 share_type_id = Column(
129 String(36), ForeignKey('share_types.id'), nullable=False)
130 resource = Column(String(255), nullable=False)
131 hard_limit = Column(Integer)
134class QuotaClass(BASE, ManilaBase):
135 """Represents a single quota override for a quota class.
137 If there is no row for a given quota class and resource, then the
138 default for the deployment is used. If the row is present but the
139 hard limit is Null, then the resource is unlimited.
140 """
142 __tablename__ = 'quota_classes'
143 id = Column(Integer, primary_key=True)
145 class_name = Column(String(255), index=True)
147 resource = Column(String(255))
148 hard_limit = Column(Integer, nullable=True)
151class QuotaUsage(BASE, ManilaBase):
152 """Represents the current usage for a given resource."""
154 __tablename__ = 'quota_usages'
155 id = Column(Integer, primary_key=True)
157 project_id = Column(String(255), index=True)
158 user_id = Column(String(255))
159 share_type_id = Column(String(36))
160 resource = Column(String(255))
162 in_use = Column(Integer)
163 reserved = Column(Integer)
165 @property
166 def total(self):
167 return self.in_use + self.reserved
169 until_refresh = Column(Integer, nullable=True)
172class Reservation(BASE, ManilaBase):
173 """Represents a resource reservation for quotas."""
175 __tablename__ = 'reservations'
176 id = Column(Integer, primary_key=True)
177 uuid = Column(String(36), nullable=False)
179 usage_id = Column(Integer, ForeignKey('quota_usages.id'), nullable=False)
181 project_id = Column(String(255), index=True)
182 user_id = Column(String(255))
183 share_type_id = Column(String(36))
184 resource = Column(String(255))
186 delta = Column(Integer)
187 expire = Column(DateTime, nullable=False)
190class Share(BASE, ManilaBase):
191 """Represents an NFS and CIFS shares."""
192 __tablename__ = 'shares'
193 _extra_keys = ['name', 'export_location', 'export_locations', 'status',
194 'host', 'share_server_id', 'share_network_id',
195 'availability_zone', 'access_rules_status', 'share_type_id']
197 @property
198 def name(self):
199 return CONF.share_name_template % self.id
201 @property
202 def export_location(self):
203 if len(self.instances) > 0: 203 ↛ exitline 203 didn't return from function 'export_location' because the condition on line 203 was always true
204 return self.instance.export_location
206 @property
207 def encryption_key_ref(self):
208 if len(self.instances) > 0:
209 return self.instance.encryption_key_ref
211 @property
212 def is_busy(self):
213 # Make sure share is not busy, i.e., not part of a migration
214 if self.task_state in constants.BUSY_TASK_STATES:
215 return True
216 return False
218 @property
219 def export_locations(self):
220 # TODO(gouthamr): Return AZ specific export locations for replicated
221 # shares.
222 # NOTE(gouthamr): For a replicated share, export locations of the
223 # 'active' instances are chosen, if 'available'.
224 all_export_locations = []
225 select_instances = list(filter(
226 lambda x: x['replica_state'] == constants.REPLICA_STATE_ACTIVE,
227 self.instances)) or self.instances
229 for instance in select_instances:
230 if instance['status'] == constants.STATUS_AVAILABLE:
231 for export_location in instance.export_locations:
232 all_export_locations.append(export_location['path'])
234 return all_export_locations
236 def __getattr__(self, item):
237 proxified_properties = ('status', 'host', 'share_server_id',
238 'share_network_id', 'availability_zone',
239 'share_type_id', 'share_type')
241 if item in proxified_properties:
242 return getattr(self.instance, item, None)
244 raise AttributeError(item)
246 @property
247 def share_server_id(self):
248 return self.__getattr__('share_server_id')
250 @property
251 def has_replicas(self):
252 if len(self.instances) > 1:
253 # NOTE(gouthamr): The 'primary' instance of a replicated share
254 # has a 'replica_state' set to 'active'. Only the secondary replica
255 # instances need to be regarded as true 'replicas' by users.
256 replicas = (list(filter(lambda x: x['replica_state'] is not None,
257 self.instances)))
258 return len(replicas) > 1
259 return False
261 @property
262 def progress(self):
263 if len(self.instances) > 0:
264 return self.instance.progress
266 @property
267 def instance(self):
268 # NOTE(gouthamr): The order of preference: status 'replication_change',
269 # followed by 'available' and 'error'. If replicated share and
270 # not undergoing a 'replication_change', only 'active' instances are
271 # preferred.
272 result = None
273 if len(self.instances) > 0:
274 order = (constants.STATUS_REVERTING,
275 constants.STATUS_REPLICATION_CHANGE,
276 constants.STATUS_MIGRATING,
277 constants.STATUS_SERVER_MIGRATING,
278 constants.STATUS_AVAILABLE,
279 constants.STATUS_ERROR, )
280 other_statuses = (
281 [x['status'] for x in self.instances if
282 x['status'] not in order and
283 x['status'] not in constants.TRANSITIONAL_STATUSES]
284 )
285 order = (order + tuple(other_statuses) +
286 constants.TRANSITIONAL_STATUSES)
287 sorted_instances = sorted(
288 self.instances, key=lambda x: order.index(x['status']))
290 select_instances = sorted_instances
291 if (select_instances[0]['status'] !=
292 constants.STATUS_REPLICATION_CHANGE):
293 select_instances = (
294 list(filter(lambda x: x['replica_state'] ==
295 constants.REPLICA_STATE_ACTIVE,
296 sorted_instances)) or sorted_instances
297 )
298 result = select_instances[0]
299 return result
301 @property
302 def access_rules_status(self):
303 return get_access_rules_status(self.instances)
305 id = Column(String(36), primary_key=True)
306 deleted = Column(String(36), default='False')
307 user_id = Column(String(255))
308 project_id = Column(String(255))
309 size = Column(Integer)
311 display_name = Column(String(255))
312 display_description = Column(String(255))
313 snapshot_id = Column(String(36))
314 source_backup_id = Column(String(36))
315 snapshot_support = Column(Boolean, default=True)
316 create_share_from_snapshot_support = Column(Boolean, default=True)
317 revert_to_snapshot_support = Column(Boolean, default=False)
318 replication_type = Column(String(255), nullable=True)
319 mount_snapshot_support = Column(Boolean, default=False)
320 share_proto = Column(String(255))
321 is_public = Column(Boolean, default=False)
322 share_group_id = Column(String(36),
323 ForeignKey('share_groups.id'),
324 nullable=True)
326 source_share_group_snapshot_member_id = Column(String(36), nullable=True)
327 task_state = Column(String(255))
328 is_soft_deleted = Column(Boolean, default=False)
329 scheduled_to_be_deleted_at = Column(DateTime)
330 instances = orm.relationship(
331 "ShareInstance",
332 lazy='subquery',
333 primaryjoin=(
334 'and_('
335 'Share.id == ShareInstance.share_id, '
336 'ShareInstance.deleted == "False")'
337 ),
338 viewonly=True,
339 join_depth=2,
340 )
343class ShareInstance(BASE, ManilaBase):
344 __tablename__ = 'share_instances'
346 _extra_keys = ['name', 'export_location', 'availability_zone',
347 'replica_state']
348 _proxified_properties = ('user_id', 'project_id', 'size',
349 'display_name', 'display_description',
350 'snapshot_id', 'share_proto', 'is_public',
351 'share_group_id', 'replication_type',
352 'source_share_group_snapshot_member_id',
353 'mount_snapshot_support')
355 def set_share_data(self, share):
356 for share_property in self._proxified_properties:
357 setattr(self, share_property, share[share_property])
359 @property
360 def name(self):
361 return CONF.share_name_template % self.id
363 @property
364 def export_location(self):
365 if len(self.export_locations) > 0:
366 return self.export_locations[0]['path']
368 @property
369 def availability_zone(self):
370 if self._availability_zone:
371 return self._availability_zone['name']
373 id = Column(String(36), primary_key=True)
374 share_id = Column(String(36), ForeignKey('shares.id'))
375 deleted = Column(String(36), default='False')
376 host = Column(String(255))
377 status = Column(String(255))
378 progress = Column(String(32))
379 mount_point_name = Column(String(255))
380 ACCESS_STATUS_PRIORITIES = {
381 constants.STATUS_ACTIVE: 0,
382 constants.SHARE_INSTANCE_RULES_SYNCING: 1,
383 constants.SHARE_INSTANCE_RULES_ERROR: 2,
384 }
386 access_rules_status = Column(Enum(constants.STATUS_ACTIVE,
387 constants.SHARE_INSTANCE_RULES_SYNCING,
388 constants.SHARE_INSTANCE_RULES_ERROR),
389 default=constants.STATUS_ACTIVE)
391 scheduled_at = Column(DateTime)
392 launched_at = Column(DateTime)
393 terminated_at = Column(DateTime)
394 encryption_key_ref = Column(String(36), nullable=True)
395 replica_state = Column(String(255), nullable=True)
396 cast_rules_to_readonly = Column(Boolean, default=False, nullable=False)
397 share_type_id = Column(String(36), ForeignKey('share_types.id'),
398 nullable=True)
399 availability_zone_id = Column(String(36),
400 ForeignKey('availability_zones.id'),
401 nullable=True)
402 _availability_zone = orm.relationship(
403 "AvailabilityZone",
404 lazy='subquery',
405 foreign_keys=availability_zone_id,
406 primaryjoin=(
407 'and_('
408 'ShareInstance.availability_zone_id == '
409 'AvailabilityZone.id, '
410 'AvailabilityZone.deleted == \'False\')'
411 )
412 )
414 export_locations = orm.relationship(
415 "ShareInstanceExportLocations",
416 lazy='joined',
417 backref=orm.backref('share_instance', lazy='joined'),
418 primaryjoin=(
419 'and_('
420 'ShareInstance.id == '
421 'ShareInstanceExportLocations.share_instance_id, '
422 'ShareInstanceExportLocations.deleted == 0)'
423 )
424 )
425 share_network_id = Column(String(36), ForeignKey('share_networks.id'),
426 nullable=True)
427 share_server_id = Column(String(36), ForeignKey('share_servers.id'),
428 nullable=True)
429 share_type = orm.relationship(
430 "ShareTypes",
431 lazy='subquery',
432 foreign_keys=share_type_id,
433 primaryjoin='and_('
434 'ShareInstance.share_type_id == ShareTypes.id, '
435 'ShareTypes.deleted == "False")')
436 share = orm.relationship(
437 'Share',
438 foreign_keys=share_id,
439 primaryjoin='ShareInstance.share_id == Share.id'
440 )
443class ShareInstanceExportLocations(BASE, ManilaBase):
444 """Represents export locations of share instances."""
445 __tablename__ = 'share_instance_export_locations'
447 _extra_keys = ['el_metadata', ]
449 @property
450 def el_metadata(self):
451 el_metadata = {}
452 for meta in self._el_metadata_bare: # pylint: disable=no-member
453 el_metadata[meta['key']] = meta['value']
454 return el_metadata
456 @property
457 def replica_state(self):
458 return self.share_instance['replica_state']
460 id = Column(Integer, primary_key=True)
461 uuid = Column(String(36), nullable=False, unique=True)
462 share_instance_id = Column(
463 String(36), ForeignKey('share_instances.id'), nullable=False)
464 path = Column(String(2000))
465 is_admin_only = Column(Boolean, default=False, nullable=False)
468class ShareInstanceExportLocationsMetadata(BASE, ManilaBase):
469 """Represents export location metadata of share instances."""
470 __tablename__ = "share_instance_export_locations_metadata"
472 _extra_keys = ['export_location_uuid', ]
474 id = Column(Integer, primary_key=True)
475 export_location_id = Column(
476 Integer,
477 ForeignKey("share_instance_export_locations.id"), nullable=False)
478 key = Column(String(255), nullable=False)
479 value = Column(String(1023), nullable=False)
480 export_location = orm.relationship(
481 ShareInstanceExportLocations,
482 backref="_el_metadata_bare",
483 foreign_keys=export_location_id,
484 lazy='immediate',
485 primaryjoin="and_("
486 "%(cls_name)s.export_location_id == "
487 "ShareInstanceExportLocations.id,"
488 "%(cls_name)s.deleted == 0)" % {
489 "cls_name": "ShareInstanceExportLocationsMetadata"})
491 @property
492 def export_location_uuid(self):
493 return self.export_location.uuid # pylint: disable=no-member
496class ShareTypes(BASE, ManilaBase):
497 """Represent possible share_types of volumes offered."""
498 __tablename__ = "share_types"
499 id = Column(String(36), primary_key=True)
500 deleted = Column(String(36), default='False')
501 name = Column(String(255))
502 description = Column(String(255))
503 is_public = Column(Boolean, default=True)
506class ShareTypeProjects(BASE, ManilaBase):
507 """Represent projects associated share_types."""
508 __tablename__ = "share_type_projects"
509 __table_args__ = (schema.UniqueConstraint(
510 "share_type_id", "project_id", "deleted",
511 name="uniq_share_type_projects0share_type_id0project_id0deleted"),
512 )
513 id = Column(Integer, primary_key=True)
514 share_type_id = Column(Integer, ForeignKey('share_types.id'),
515 nullable=False)
516 project_id = Column(String(255))
518 share_type = orm.relationship(
519 ShareTypes,
520 backref="projects",
521 foreign_keys=share_type_id,
522 primaryjoin='and_('
523 'ShareTypeProjects.share_type_id == ShareTypes.id,'
524 'ShareTypeProjects.deleted == 0)')
527class ShareTypeExtraSpecs(BASE, ManilaBase):
528 """Represents additional specs as key/value pairs for a share_type."""
529 __tablename__ = 'share_type_extra_specs'
530 id = Column(Integer, primary_key=True)
531 key = Column("spec_key", String(255))
532 value = Column("spec_value", String(255))
533 share_type_id = Column(String(36), ForeignKey('share_types.id'),
534 nullable=False)
535 share_type = orm.relationship(
536 ShareTypes,
537 backref="extra_specs",
538 foreign_keys=share_type_id,
539 primaryjoin='and_('
540 'ShareTypeExtraSpecs.share_type_id == ShareTypes.id,'
541 'ShareTypeExtraSpecs.deleted == 0)'
542 )
545class ShareMetadata(BASE, ManilaBase):
546 """Represents a metadata key/value pair for a share."""
547 __tablename__ = 'share_metadata'
548 id = Column(Integer, primary_key=True)
549 key = Column(String(255), nullable=False)
550 value = Column(String(1023), nullable=False)
551 share_id = Column(String(36), ForeignKey('shares.id'), nullable=False)
552 share = orm.relationship(Share, backref="share_metadata",
553 foreign_keys=share_id,
554 primaryjoin='and_('
555 'ShareMetadata.share_id == Share.id,'
556 'ShareMetadata.deleted == 0)')
559class ShareAccessMapping(BASE, ManilaBase):
560 """Represents access to share."""
561 __tablename__ = 'share_access_map'
563 id = Column(String(36), primary_key=True)
564 deleted = Column(String(36), default='False')
565 share_id = Column(String(36), ForeignKey('shares.id'))
566 access_type = Column(String(255))
567 access_to = Column(String(255))
568 access_key = Column(String(255), nullable=True)
570 access_level = Column(Enum(*constants.ACCESS_LEVELS),
571 default=constants.ACCESS_LEVEL_RW)
573 @property
574 def state(self):
575 """Get the aggregated 'state' from all the instance mapping states.
577 An access rule is supposed to be truly 'active' when it has been
578 applied across all of the share instances of the parent share object.
579 """
580 return get_aggregated_access_rules_state(self.instance_mappings)
582 instance_mappings = orm.relationship(
583 "ShareInstanceAccessMapping",
584 lazy='immediate',
585 primaryjoin=(
586 'and_('
587 'ShareAccessMapping.id == '
588 'ShareInstanceAccessMapping.access_id, '
589 'ShareInstanceAccessMapping.deleted == "False")'
590 )
591 )
592 share = orm.relationship(
593 "Share",
594 primaryjoin=(
595 'and_('
596 'ShareAccessMapping.share_id == '
597 'Share.id, '
598 'Share.deleted == "False")'
599 )
600 )
603class ShareAccessRulesMetadata(BASE, ManilaBase):
604 """Represents a metadata key/value pair for a share access rule."""
605 __tablename__ = 'share_access_rules_metadata'
606 id = Column(Integer, primary_key=True)
607 deleted = Column(String(36), default='False')
608 key = Column(String(255), nullable=False)
609 value = Column(String(1023), nullable=False)
610 access_id = Column(String(36), ForeignKey('share_access_map.id'),
611 nullable=False)
612 access = orm.relationship(
613 ShareAccessMapping, backref="share_access_rules_metadata",
614 foreign_keys=access_id,
615 lazy='immediate',
616 primaryjoin='and_('
617 'ShareAccessRulesMetadata.access_id == ShareAccessMapping.id,'
618 'ShareAccessRulesMetadata.deleted == "False")')
621class ShareInstanceAccessMapping(BASE, ManilaBase):
622 """Represents access to individual share instances."""
624 __tablename__ = 'share_instance_access_map'
625 _proxified_properties = ('share_id', 'access_type', 'access_key',
626 'access_to', 'access_level')
628 def set_share_access_data(self, share_access):
629 for share_access_attr in self._proxified_properties:
630 setattr(self, share_access_attr, share_access[share_access_attr])
632 id = Column(String(36), primary_key=True)
633 deleted = Column(String(36), default='False')
634 share_instance_id = Column(String(36), ForeignKey('share_instances.id'))
635 access_id = Column(String(36), ForeignKey('share_access_map.id'))
636 state = Column(String(255), default=constants.ACCESS_STATE_QUEUED_TO_APPLY)
638 instance = orm.relationship(
639 "ShareInstance",
640 lazy='immediate',
641 primaryjoin=(
642 'and_('
643 'ShareInstanceAccessMapping.share_instance_id == '
644 'ShareInstance.id, '
645 'ShareInstanceAccessMapping.deleted == "False")'
646 )
647 )
650class ShareSnapshot(BASE, ManilaBase):
651 """Represents a snapshot of a share."""
652 __tablename__ = 'share_snapshots'
653 _extra_keys = ['name', 'share_name', 'status', 'progress',
654 'provider_location', 'aggregate_status']
656 def __getattr__(self, item):
657 proxified_properties = ('status', 'progress', 'provider_location')
659 if item in proxified_properties:
660 return getattr(self.instance, item, None)
662 raise AttributeError(item)
664 @property
665 def export_locations(self):
666 # TODO(gouthamr): Return AZ specific export locations for replicated
667 # snapshots.
668 # NOTE(gouthamr): For a replicated snapshot, export locations of the
669 # 'active' instances are chosen, if 'available'.
670 all_export_locations = []
671 select_instances = list(filter(
672 lambda x: (x['share_instance']['replica_state'] ==
673 constants.REPLICA_STATE_ACTIVE),
674 self.instances)) or self.instances
676 for instance in select_instances:
677 if instance['status'] == constants.STATUS_AVAILABLE: 677 ↛ 676line 677 didn't jump to line 676 because the condition on line 677 was always true
678 for export_location in instance.export_locations:
679 all_export_locations.append(export_location)
681 return all_export_locations
683 @property
684 def name(self):
685 return CONF.share_snapshot_name_template % self.id
687 @property
688 def share_name(self):
689 return CONF.share_name_template % self.share_id
691 @property
692 def instance(self):
693 result = None
694 if len(self.instances) > 0: 694 ↛ 715line 694 didn't jump to line 715 because the condition on line 694 was always true
695 def qualified_replica(x):
696 if x is None: 696 ↛ 697line 696 didn't jump to line 697 because the condition on line 696 was never true
697 return False
698 else:
699 preferred_statuses = (constants.REPLICA_STATE_ACTIVE,)
700 return x['replica_state'] in preferred_statuses
702 replica_snapshots = list(filter(
703 lambda x: qualified_replica(x.share_instance), self.instances))
705 migrating_snapshots = list(filter(
706 lambda x: x.share_instance['status'] in (
707 constants.STATUS_MIGRATING,
708 constants.STATUS_SERVER_MIGRATING), self.instances))
710 snapshot_instances = (replica_snapshots or migrating_snapshots
711 or self.instances)
713 result = snapshot_instances[0]
715 return result
717 @property
718 def aggregate_status(self):
719 """Get the aggregated 'status' of all instances.
721 A snapshot is supposed to be truly 'available' when it is available
722 across all of the share instances of the parent share object. In
723 case of replication, we only consider replicas (share instances)
724 that are in 'in_sync' replica_state.
725 """
727 def qualified_replica(x):
728 if x is None: 728 ↛ 729line 728 didn't jump to line 729 because the condition on line 728 was never true
729 return False
730 else:
731 preferred_statuses = (constants.REPLICA_STATE_ACTIVE,
732 constants.REPLICA_STATE_IN_SYNC)
733 return x['replica_state'] in preferred_statuses
735 replica_snapshots = list(filter(
736 lambda x: qualified_replica(x['share_instance']), self.instances))
738 if not replica_snapshots:
739 return self.status
741 order = (constants.STATUS_DELETING, constants.STATUS_CREATING,
742 constants.STATUS_ERROR, constants.STATUS_MIGRATING,
743 constants.STATUS_SERVER_MIGRATING,
744 constants.STATUS_AVAILABLE)
745 other_statuses = [x['status'] for x in self.instances if
746 x['status'] not in order]
747 order = (order + tuple(other_statuses))
749 sorted_instances = sorted(
750 replica_snapshots, key=lambda x: order.index(x['status']))
751 return sorted_instances[0].status
753 id = Column(String(36), primary_key=True)
754 deleted = Column(String(36), default='False')
755 user_id = Column(String(255))
756 project_id = Column(String(255))
757 share_id = Column(String(36))
758 size = Column(Integer)
759 display_name = Column(String(255))
760 display_description = Column(String(255))
761 share_size = Column(Integer)
762 share_proto = Column(String(255))
763 share = orm.relationship(Share, backref="snapshots",
764 foreign_keys=share_id,
765 primaryjoin='and_('
766 'ShareSnapshot.share_id == Share.id,'
767 'ShareSnapshot.deleted == "False")')
770class ShareSnapshotMetadata(BASE, ManilaBase):
771 """Represents a metadata key/value pair for a snapshot."""
772 __tablename__ = 'share_snapshot_metadata'
773 id = Column(Integer, primary_key=True)
774 key = Column(String(255), nullable=False)
775 value = Column(String(1023), nullable=False)
776 deleted = Column(String(36), default='False')
777 share_snapshot_id = Column(String(36), ForeignKey(
778 'share_snapshots.id'), nullable=False)
780 share_snapshot = orm.relationship(
781 ShareSnapshot, backref="share_snapshot_metadata",
782 foreign_keys=share_snapshot_id,
783 primaryjoin='and_('
784 'ShareSnapshotMetadata.share_snapshot_id == ShareSnapshot.id,'
785 'ShareSnapshotMetadata.deleted == "False")')
788class ShareSnapshotInstance(BASE, ManilaBase):
789 """Represents a snapshot of a share."""
790 __tablename__ = 'share_snapshot_instances'
791 _extra_keys = ['name', 'share_id', 'share_name']
793 @property
794 def name(self):
795 return CONF.share_snapshot_name_template % self.id
797 @property
798 def share_name(self):
799 return CONF.share_name_template % self.share_instance_id
801 @property
802 def share_id(self):
803 # NOTE(u_glide): This property required for compatibility
804 # with share drivers
805 return self.share_instance_id
807 @property
808 def size(self):
809 # NOTE(silvacarlose) for backwards compatibility
810 if self.instance_size is None: 810 ↛ 813line 810 didn't jump to line 813 because the condition on line 810 was always true
811 return self.snapshot.size
812 else:
813 return self.instance_size
815 id = Column(String(36), primary_key=True)
816 deleted = Column(String(36), default='False')
817 snapshot_id = Column(String(36), nullable=True)
818 share_instance_id = Column(
819 String(36), ForeignKey('share_instances.id'), nullable=False)
820 status = Column(String(255))
821 progress = Column(String(255))
822 provider_location = Column(String(255))
823 share_proto = Column(String(255))
824 instance_size = Column('size', Integer)
825 share_group_snapshot_id = Column(String(36), nullable=True)
826 user_id = Column(String(255))
827 project_id = Column(String(255))
829 export_locations = orm.relationship(
830 "ShareSnapshotInstanceExportLocation",
831 lazy='immediate',
832 primaryjoin=(
833 'and_('
834 'ShareSnapshotInstance.id == '
835 'ShareSnapshotInstanceExportLocation.share_snapshot_instance_id, '
836 'ShareSnapshotInstanceExportLocation.deleted == "False")'
837 )
838 )
839 share_instance = orm.relationship(
840 ShareInstance, backref="snapshot_instances",
841 lazy='immediate',
842 primaryjoin=(
843 'and_('
844 'ShareSnapshotInstance.share_instance_id == ShareInstance.id,'
845 'ShareSnapshotInstance.deleted == "False")')
846 )
847 snapshot = orm.relationship(
848 "ShareSnapshot",
849 lazy="immediate",
850 foreign_keys=snapshot_id,
851 backref="instances",
852 primaryjoin=(
853 'and_('
854 'ShareSnapshot.id == ShareSnapshotInstance.snapshot_id, '
855 'ShareSnapshotInstance.deleted == "False")'
856 ),
857 viewonly=True,
858 join_depth=2,
859 sync_backref=False,
860 )
861 share_group_snapshot = orm.relationship(
862 "ShareGroupSnapshot",
863 lazy="immediate",
864 foreign_keys=share_group_snapshot_id,
865 backref="share_group_snapshot_members",
866 primaryjoin=('ShareGroupSnapshot.id == '
867 'ShareSnapshotInstance.share_group_snapshot_id'),
868 viewonly=True,
869 join_depth=2,
870 sync_backref=False,
871 )
874class ShareSnapshotAccessMapping(BASE, ManilaBase):
875 """Represents access to share snapshot."""
876 __tablename__ = 'share_snapshot_access_map'
878 @property
879 def state(self):
880 """Get the aggregated 'state' from all the instance mapping states.
882 An access rule is supposed to be truly 'active' when it has been
883 applied across all of the share snapshot instances of the parent
884 share snapshot object.
885 """
886 return get_aggregated_access_rules_state(self.instance_mappings)
888 id = Column(String(36), primary_key=True)
889 deleted = Column(String(36), default='False')
890 share_snapshot_id = Column(String(36), ForeignKey('share_snapshots.id'))
891 access_type = Column(String(255))
892 access_to = Column(String(255))
894 instance_mappings = orm.relationship(
895 "ShareSnapshotInstanceAccessMapping",
896 lazy='immediate',
897 primaryjoin=(
898 'and_('
899 'ShareSnapshotAccessMapping.id == '
900 'ShareSnapshotInstanceAccessMapping.access_id, '
901 'ShareSnapshotInstanceAccessMapping.deleted == "False")'
902 )
903 )
906class ShareSnapshotInstanceAccessMapping(BASE, ManilaBase):
907 """Represents access to individual share snapshot instances."""
909 __tablename__ = 'share_snapshot_instance_access_map'
910 _proxified_properties = ('share_snapshot_id', 'access_type', 'access_to')
912 def set_snapshot_access_data(self, snapshot_access):
913 for snapshot_access_attr in self._proxified_properties:
914 setattr(self, snapshot_access_attr,
915 snapshot_access[snapshot_access_attr])
917 id = Column(String(36), primary_key=True)
918 deleted = Column(String(36), default='False')
919 share_snapshot_instance_id = Column(String(36), ForeignKey(
920 'share_snapshot_instances.id'))
921 access_id = Column(String(36), ForeignKey('share_snapshot_access_map.id'))
922 state = Column(Enum(*constants.ACCESS_RULES_STATES),
923 default=constants.ACCESS_STATE_QUEUED_TO_APPLY)
925 instance = orm.relationship(
926 "ShareSnapshotInstance",
927 lazy='immediate',
928 primaryjoin=(
929 'and_('
930 'ShareSnapshotInstanceAccessMapping.share_snapshot_instance_id == '
931 'ShareSnapshotInstance.id, '
932 'ShareSnapshotInstanceAccessMapping.deleted == "False")'
933 )
934 )
937class ShareSnapshotInstanceExportLocation(BASE, ManilaBase):
938 """Represents export locations of share snapshot instances."""
939 __tablename__ = 'share_snapshot_instance_export_locations'
941 id = Column(String(36), primary_key=True)
942 share_snapshot_instance_id = Column(
943 String(36), ForeignKey('share_snapshot_instances.id'), nullable=False)
944 path = Column(String(2000))
945 is_admin_only = Column(Boolean, default=False, nullable=False)
946 deleted = Column(String(36), default='False')
949class SecurityService(BASE, ManilaBase):
950 """Security service information for manila shares."""
952 __tablename__ = 'security_services'
953 id = Column(String(36), primary_key=True)
954 deleted = Column(String(36), default='False')
955 project_id = Column(String(255), nullable=False)
956 type = Column(String(32), nullable=False)
957 dns_ip = Column(String(64), nullable=True)
958 server = Column(String(255), nullable=True)
959 domain = Column(String(255), nullable=True)
960 user = Column(String(255), nullable=True)
961 password = Column(String(255), nullable=True)
962 name = Column(String(255), nullable=True)
963 description = Column(String(255), nullable=True)
964 ou = Column(String(255), nullable=True)
965 default_ad_site = Column(String(255), nullable=True)
968class ShareNetwork(BASE, ManilaBase):
969 """Represents network data used by share."""
970 __tablename__ = 'share_networks'
971 id = Column(String(36), primary_key=True, nullable=False)
972 deleted = Column(String(36), default='False')
973 project_id = Column(String(255), nullable=False)
974 user_id = Column(String(255), nullable=False)
975 name = Column(String(255), nullable=True)
976 description = Column(String(255), nullable=True)
977 status = Column(Enum(
978 constants.STATUS_NETWORK_ACTIVE, constants.STATUS_NETWORK_ERROR,
979 constants.STATUS_NETWORK_CHANGE),
980 default=constants.STATUS_NETWORK_ACTIVE)
981 security_services = orm.relationship(
982 "SecurityService",
983 secondary="share_network_security_service_association",
984 backref="share_networks",
985 primaryjoin='and_('
986 'ShareNetwork.id == '
987 'ShareNetworkSecurityServiceAssociation.share_network_id,'
988 'ShareNetworkSecurityServiceAssociation.deleted == 0,'
989 'ShareNetwork.deleted == "False")',
990 secondaryjoin='and_('
991 'SecurityService.id == '
992 'ShareNetworkSecurityServiceAssociation.security_service_id,'
993 'SecurityService.deleted == "False")')
994 share_instances = orm.relationship(
995 "ShareInstance",
996 backref=orm.backref('share_network'),
997 primaryjoin='and_('
998 'ShareNetwork.id == ShareInstance.share_network_id,'
999 'ShareInstance.deleted == "False")')
1000 share_network_subnets = orm.relationship(
1001 "ShareNetworkSubnet",
1002 lazy='joined',
1003 backref=orm.backref('share_network', lazy='joined'),
1004 primaryjoin='and_'
1005 '(ShareNetwork.id == ShareNetworkSubnet.share_network_id,'
1006 'ShareNetworkSubnet.deleted == "False")')
1008 @property
1009 def security_service_update_support(self):
1010 share_servers_support_updating = []
1011 for network_subnet in self.share_network_subnets:
1012 for server in network_subnet['share_servers']:
1013 share_servers_support_updating.append(
1014 server['security_service_update_support'])
1015 # NOTE(carloss): all share servers within this share network must
1016 # support updating security services in order to have this property
1017 # set to True.
1018 return all(share_servers_support_updating)
1020 @property
1021 def network_allocation_update_support(self):
1022 share_servers_support_updating = []
1023 for network_subnet in self.share_network_subnets: 1023 ↛ 1024line 1023 didn't jump to line 1024 because the loop on line 1023 never started
1024 for server in network_subnet['share_servers']:
1025 share_servers_support_updating.append(
1026 server['network_allocation_update_support'])
1027 # NOTE(felipe_rodrigues): all share servers within this share network
1028 # must support updating in order to have this property set to True.
1029 return all(share_servers_support_updating)
1032class ShareNetworkSubnet(BASE, ManilaBase):
1033 """Represents a share network subnet used by some resources."""
1035 _extra_keys = ['availability_zone', 'subnet_metadata']
1037 __tablename__ = 'share_network_subnets'
1038 id = Column(String(36), primary_key=True, nullable=False)
1039 neutron_net_id = Column(String(36), nullable=True)
1040 neutron_subnet_id = Column(String(36), nullable=True)
1041 network_type = Column(String(32), nullable=True)
1042 cidr = Column(String(64), nullable=True)
1043 segmentation_id = Column(Integer, nullable=True)
1044 gateway = Column(String(64), nullable=True)
1045 mtu = Column(Integer, nullable=True)
1046 deleted = Column(String(36), default='False')
1047 share_network_id = Column(String(36), ForeignKey('share_networks.id'),
1048 nullable=False)
1049 ip_version = Column(Integer, nullable=True)
1050 availability_zone_id = Column(
1051 String(36), ForeignKey('availability_zones.id'), nullable=True)
1053 share_servers = orm.relationship(
1054 "ShareServer",
1055 secondary="share_server_share_network_subnet_mappings",
1056 backref="share_network_subnets",
1057 lazy='immediate',
1058 primaryjoin="and_(ShareNetworkSubnet.id == "
1059 "%(cls_name)s.share_network_subnet_id, "
1060 "%(cls_name)s.deleted == 0)" % {
1061 "cls_name": "ShareServerShareNetworkSubnetMapping"},
1062 secondaryjoin='and_('
1063 'ShareServer.id == '
1064 'ShareServerShareNetworkSubnetMapping.share_server_id,'
1065 'ShareServerShareNetworkSubnetMapping.deleted == 0)'
1066 )
1068 _availability_zone = orm.relationship(
1069 "AvailabilityZone",
1070 lazy='immediate',
1071 foreign_keys=availability_zone_id,
1072 primaryjoin=(
1073 "and_("
1074 "ShareNetworkSubnet.availability_zone_id == AvailabilityZone.id, "
1075 "AvailabilityZone.deleted == 'False')"))
1077 @property
1078 def availability_zone(self):
1079 if self._availability_zone: 1079 ↛ 1080line 1079 didn't jump to line 1080 because the condition on line 1079 was never true
1080 return self._availability_zone['name']
1082 @property
1083 def is_default(self):
1084 return self.availability_zone_id is None
1086 @property
1087 def share_network_name(self):
1088 return self.share_network['name']
1090 @property
1091 def subnet_metadata(self):
1092 metadata_dict = {}
1093 metadata_list = (
1094 self.share_network_subnet_metadata) # pylint: disable=no-member
1095 for meta in metadata_list:
1096 metadata_dict[meta['key']] = meta['value']
1097 return metadata_dict
1099 @property
1100 def project_id(self):
1101 return self.share_network['project_id']
1104class ShareNetworkSubnetMetadata(BASE, ManilaBase):
1105 """Represents a metadata key/value pair for a subnet."""
1106 __tablename__ = 'share_network_subnet_metadata'
1107 id = Column(Integer, primary_key=True)
1108 key = Column(String(255), nullable=False)
1109 value = Column(String(1023), nullable=False)
1110 deleted = Column(String(36), default='False')
1111 share_network_subnet_id = Column(String(36), ForeignKey(
1112 'share_network_subnets.id'), nullable=False)
1114 share_network_subnet = orm.relationship(
1115 ShareNetworkSubnet,
1116 backref=orm.backref('share_network_subnet_metadata', lazy='immediate'),
1117 foreign_keys=share_network_subnet_id,
1118 primaryjoin='and_('
1119 'ShareNetworkSubnetMetadata.share_network_subnet_id == '
1120 'ShareNetworkSubnet.id,'
1121 'ShareNetworkSubnetMetadata.deleted == "False")')
1124class ShareServer(BASE, ManilaBase):
1125 """Represents share server used by share."""
1126 __tablename__ = 'share_servers'
1127 id = Column(String(36), primary_key=True, nullable=False)
1128 deleted = Column(String(36), default='False')
1129 host = Column(String(255), nullable=False)
1130 is_auto_deletable = Column(Boolean, default=True)
1131 identifier = Column(String(255), nullable=True)
1132 task_state = Column(String(255), nullable=True)
1133 source_share_server_id = Column(String(36), ForeignKey('share_servers.id'),
1134 nullable=True)
1135 security_service_update_support = Column(
1136 Boolean, nullable=False, default=False)
1137 network_allocation_update_support = Column(
1138 Boolean, nullable=False, default=False)
1139 share_replicas_migration_support = Column(
1140 Boolean, nullable=False, default=False)
1141 encryption_key_ref = Column(String(36), nullable=True)
1142 application_credential_id = Column(String(36), nullable=True)
1143 status = Column(Enum(
1144 constants.STATUS_INACTIVE, constants.STATUS_ACTIVE,
1145 constants.STATUS_ERROR, constants.STATUS_DELETING,
1146 constants.STATUS_CREATING, constants.STATUS_DELETED,
1147 constants.STATUS_MANAGING, constants.STATUS_UNMANAGING,
1148 constants.STATUS_UNMANAGE_ERROR, constants.STATUS_MANAGE_ERROR,
1149 constants.STATUS_SERVER_MIGRATING,
1150 constants.STATUS_SERVER_MIGRATING_TO,
1151 constants.STATUS_SERVER_NETWORK_CHANGE),
1152 default=constants.STATUS_INACTIVE)
1153 network_allocations = orm.relationship(
1154 "NetworkAllocation",
1155 primaryjoin='and_('
1156 'ShareServer.id == NetworkAllocation.share_server_id,'
1157 'NetworkAllocation.deleted == "False")')
1158 share_instances = orm.relationship(
1159 "ShareInstance",
1160 backref='share_server',
1161 primaryjoin='and_('
1162 'ShareServer.id == ShareInstance.share_server_id,'
1163 'ShareInstance.deleted == "False")')
1165 share_groups = orm.relationship(
1166 "ShareGroup",
1167 backref='share_server',
1168 primaryjoin='and_('
1169 'ShareServer.id == ShareGroup.share_server_id,'
1170 'ShareGroup.deleted == "False")')
1172 _backend_details = orm.relationship(
1173 "ShareServerBackendDetails",
1174 lazy='immediate',
1175 viewonly=True,
1176 primaryjoin='and_('
1177 'ShareServer.id == '
1178 'ShareServerBackendDetails.share_server_id, '
1179 'ShareServerBackendDetails.deleted == "False")')
1181 _share_network_subnet_ids = orm.relationship(
1182 "ShareServerShareNetworkSubnetMapping",
1183 lazy='immediate',
1184 viewonly=True,
1185 primaryjoin='and_('
1186 'ShareServer.id == '
1187 'ShareServerShareNetworkSubnetMapping.share_server_id,'
1188 'ShareServerShareNetworkSubnetMapping.deleted == 0)')
1190 @property
1191 def backend_details(self):
1192 return {model['key']: model['value']
1193 for model in self._backend_details}
1195 @property
1196 def share_network_subnet_ids(self):
1197 return [model['share_network_subnet_id']
1198 for model in self._share_network_subnet_ids]
1200 @property
1201 def share_network_id(self):
1202 return (self.share_network_subnets[0]['share_network_id']
1203 if self.share_network_subnets else None)
1205 _extra_keys = ['backend_details', 'share_network_subnet_ids']
1208class EncryptionRef(BASE, ManilaBase):
1209 """Represents a share server with encryption keys."""
1210 __tablename__ = 'encryption_refs'
1211 id = Column(String(36), primary_key=True, nullable=False)
1212 share_server_id = Column(
1213 String(36), ForeignKey('share_servers.id'), unique=True)
1214 share_instance_id = Column(
1215 String(36), ForeignKey('share_instances.id'), unique=True)
1216 encryption_key_ref = Column(String(36), nullable=True)
1217 project_id = Column(String(255), nullable=True)
1218 deleted = Column(String(36), default='False')
1220 share_server = orm.relationship(
1221 ShareServer,
1222 backref=orm.backref(
1223 'server_encryption_ref_entry', lazy='joined', uselist=False),
1224 foreign_keys=share_server_id,
1225 primaryjoin='and_('
1226 'EncryptionRef.share_server_id == ShareServer.id,'
1227 'EncryptionRef.deleted == "False")'
1228 )
1230 share_instance = orm.relationship(
1231 ShareInstance,
1232 backref=orm.backref(
1233 'instance_encryption_ref_entry', lazy='joined', uselist=False),
1234 foreign_keys=share_instance_id,
1235 primaryjoin='and_('
1236 'EncryptionRef.share_instance_id == ShareInstance.id,'
1237 'EncryptionRef.deleted == "False")'
1238 )
1241class ShareServerBackendDetails(BASE, ManilaBase):
1242 """Represents a metadata key/value pair for a share server."""
1243 __tablename__ = 'share_server_backend_details'
1244 deleted = Column(String(36), default='False')
1245 id = Column(Integer, primary_key=True)
1246 key = Column(String(255), nullable=False)
1247 value = Column(String(1023), nullable=False)
1248 share_server_id = Column(String(36), ForeignKey('share_servers.id'),
1249 nullable=False)
1252class ShareServerShareNetworkSubnetMapping(BASE, ManilaBase):
1253 """Represents the Share Server and Share Network Subnet mapping."""
1254 __tablename__ = 'share_server_share_network_subnet_mappings'
1255 id = Column(Integer, primary_key=True)
1256 share_server_id = Column(
1257 String(36), ForeignKey('share_servers.id'), nullable=False)
1258 share_network_subnet_id = Column(
1259 String(36), ForeignKey('share_network_subnets.id'), nullable=False)
1262class ShareNetworkSecurityServiceAssociation(BASE, ManilaBase):
1263 """Association table between compute_zones and compute_nodes tables."""
1265 __tablename__ = 'share_network_security_service_association'
1267 id = Column(Integer, primary_key=True)
1268 share_network_id = Column(String(36),
1269 ForeignKey('share_networks.id'),
1270 nullable=False)
1271 security_service_id = Column(String(36),
1272 ForeignKey('security_services.id'),
1273 nullable=False)
1276class Transfer(BASE, ManilaBase):
1277 """Represents a share transfer request."""
1279 __tablename__ = 'transfers'
1281 id = Column(String(36), primary_key=True, nullable=False)
1282 deleted = Column(String(36), default='False')
1283 # resource type can be "share" or "share_network"
1284 resource_type = Column(String(36), nullable=False)
1285 # The uuid of the related resource.
1286 resource_id = Column(String(36), nullable=False)
1287 display_name = Column(String(255))
1288 salt = Column(String(255))
1289 crypt_hash = Column(String(255))
1290 expires_at = Column(DateTime)
1291 source_project_id = Column(String(255), nullable=True)
1292 destination_project_id = Column(String(255), nullable=True)
1293 accepted = Column(Boolean, default=False)
1296class NetworkAllocation(BASE, ManilaBase):
1297 """Represents network allocation data."""
1298 __tablename__ = 'network_allocations'
1299 id = Column(String(36), primary_key=True, nullable=False)
1300 deleted = Column(String(36), default='False')
1301 label = Column(String(255), nullable=True)
1302 ip_address = Column(String(64), nullable=True)
1303 ip_version = Column(Integer, nullable=True)
1304 cidr = Column(String(64), nullable=True)
1305 gateway = Column(String(64), nullable=True)
1306 mtu = Column(Integer, nullable=True)
1307 network_type = Column(String(32), nullable=True)
1308 segmentation_id = Column(Integer, nullable=True)
1309 mac_address = Column(String(32), nullable=True)
1310 share_server_id = Column(String(36), ForeignKey('share_servers.id'),
1311 nullable=False)
1313 # NOTE(felipe_rodrigues): admin allocation does not have subnet.
1314 share_network_subnet_id = Column(
1315 String(36), ForeignKey('share_network_subnets.id'), nullable=True)
1318class DriverPrivateData(BASE, ManilaBase):
1319 """Represents a private data as key-value pairs for a driver."""
1320 __tablename__ = 'drivers_private_data'
1321 entity_uuid = Column(String(36), nullable=False, primary_key=True)
1322 key = Column(String(255), nullable=False, primary_key=True)
1323 value = Column(String(1023), nullable=False)
1326class AvailabilityZone(BASE, ManilaBase):
1327 """Represents a private data as key-value pairs for a driver."""
1328 __tablename__ = 'availability_zones'
1329 __table_args__ = (
1330 schema.UniqueConstraint('name', 'deleted', name='az_name_uc'),
1331 )
1332 id = Column(String(36), primary_key=True, nullable=False)
1333 deleted = Column(String(36), default='False')
1334 name = Column(String(255), nullable=False)
1337class ShareGroupTypes(BASE, ManilaBase):
1338 """Represent possible share group types of shares offered."""
1339 __tablename__ = "share_group_types"
1340 __table_args__ = (
1341 schema.UniqueConstraint(
1342 "name", "deleted", name="uniq_share_group_type_name"),
1343 )
1344 id = Column(String(36), primary_key=True)
1345 deleted = Column(String(36), default='False')
1346 name = Column(String(255))
1347 is_public = Column(Boolean, default=True)
1350class ShareGroup(BASE, ManilaBase):
1351 """Represents a share group."""
1352 __tablename__ = 'share_groups'
1353 _extra_keys = [
1354 'availability_zone',
1355 ]
1356 id = Column(String(36), primary_key=True)
1357 user_id = Column(String(255), nullable=False)
1358 project_id = Column(String(255), nullable=False)
1359 deleted = Column(String(36), default='False')
1360 host = Column(String(255))
1361 name = Column(String(255))
1362 description = Column(String(255))
1363 status = Column(String(255))
1364 source_share_group_snapshot_id = Column(String(36))
1365 share_network_id = Column(
1366 String(36), ForeignKey('share_networks.id'), nullable=True)
1367 share_server_id = Column(
1368 String(36), ForeignKey('share_servers.id'), nullable=True)
1369 share_group_type_id = Column(
1370 String(36), ForeignKey('share_group_types.id'), nullable=True)
1371 availability_zone_id = Column(
1372 String(36), ForeignKey('availability_zones.id'), nullable=True)
1373 consistent_snapshot_support = Column(Enum('pool', 'host'), default=None)
1375 share_group_type = orm.relationship(
1376 ShareGroupTypes,
1377 backref="share_groups",
1378 foreign_keys=share_group_type_id,
1379 primaryjoin="and_("
1380 "ShareGroup.share_group_type_id =="
1381 "ShareGroupTypes.id,"
1382 "ShareGroup.deleted == 'False')")
1383 _availability_zone = orm.relationship(
1384 "AvailabilityZone",
1385 lazy='immediate',
1386 foreign_keys=availability_zone_id,
1387 primaryjoin=(
1388 "and_("
1389 "ShareGroup.availability_zone_id == AvailabilityZone.id, "
1390 "AvailabilityZone.deleted == 'False')"))
1392 @property
1393 def availability_zone(self):
1394 if self._availability_zone: 1394 ↛ 1395line 1394 didn't jump to line 1395 because the condition on line 1394 was never true
1395 return self._availability_zone['name']
1398class ShareGroupTypeProjects(BASE, ManilaBase):
1399 """Represent projects associated share group types."""
1400 __tablename__ = "share_group_type_projects"
1401 __table_args__ = (schema.UniqueConstraint(
1402 "share_group_type_id", "project_id", "deleted",
1403 name=("uniq_share_group_type_projects0share_group_type_id"
1404 "0project_id0deleted")),
1405 )
1406 id = Column(Integer, primary_key=True)
1407 share_group_type_id = Column(
1408 String, ForeignKey('share_group_types.id'), nullable=False)
1409 project_id = Column(String(255))
1410 share_group_type = orm.relationship(
1411 ShareGroupTypes,
1412 backref="projects",
1413 foreign_keys=share_group_type_id,
1414 primaryjoin='and_('
1415 'ShareGroupTypeProjects.share_group_type_id == '
1416 'ShareGroupTypes.id,'
1417 'ShareGroupTypeProjects.deleted == 0)')
1420class ShareGroupTypeSpecs(BASE, ManilaBase):
1421 """Represents additional specs for a share group type."""
1422 __tablename__ = 'share_group_type_specs'
1423 id = Column(Integer, primary_key=True)
1424 key = Column("spec_key", String(255))
1425 value = Column("spec_value", String(255))
1426 share_group_type_id = Column(
1427 String(36), ForeignKey('share_group_types.id'), nullable=False)
1428 share_group_type = orm.relationship(
1429 ShareGroupTypes,
1430 backref="group_specs",
1431 foreign_keys=share_group_type_id,
1432 primaryjoin='and_('
1433 'ShareGroupTypeSpecs.share_group_type_id == ShareGroupTypes.id,'
1434 'ShareGroupTypeSpecs.deleted == 0)'
1435 )
1438class ShareGroupSnapshot(BASE, ManilaBase):
1439 """Represents a share group snapshot."""
1440 __tablename__ = 'share_group_snapshots'
1441 id = Column(String(36), primary_key=True)
1442 share_group_id = Column(String(36), ForeignKey('share_groups.id'))
1443 user_id = Column(String(255), nullable=False)
1444 project_id = Column(String(255), nullable=False)
1445 deleted = Column(String(36), default='False')
1446 name = Column(String(255))
1447 description = Column(String(255))
1448 status = Column(String(255))
1449 share_group = orm.relationship(
1450 ShareGroup,
1451 backref=orm.backref("snapshots", lazy='joined'),
1452 foreign_keys=share_group_id,
1453 primaryjoin=('and_('
1454 'ShareGroupSnapshot.share_group_id == ShareGroup.id,'
1455 'ShareGroupSnapshot.deleted == "False")')
1456 )
1459class ShareGroupTypeShareTypeMapping(BASE, ManilaBase):
1460 """Represents the share types supported by a share group type."""
1461 __tablename__ = 'share_group_type_share_type_mappings'
1462 id = Column(String(36), primary_key=True)
1463 deleted = Column(String(36), default='False')
1464 share_group_type_id = Column(
1465 String(36), ForeignKey('share_group_types.id'), nullable=False)
1466 share_type_id = Column(
1467 String(36), ForeignKey('share_types.id'), nullable=False)
1468 share_group_type = orm.relationship(
1469 ShareGroupTypes,
1470 backref="share_types",
1471 foreign_keys=share_group_type_id,
1472 primaryjoin=('and_('
1473 'ShareGroupTypeShareTypeMapping.share_group_type_id '
1474 '== ShareGroupTypes.id,'
1475 'ShareGroupTypeShareTypeMapping.deleted == "False")')
1476 )
1479class ShareGroupShareTypeMapping(BASE, ManilaBase):
1480 """Represents the share types in a share group."""
1481 __tablename__ = 'share_group_share_type_mappings'
1482 id = Column(String(36), primary_key=True)
1483 deleted = Column(String(36), default='False')
1484 share_group_id = Column(
1485 String(36), ForeignKey('share_groups.id'), nullable=False)
1486 share_type_id = Column(
1487 String(36), ForeignKey('share_types.id'), nullable=False)
1488 share_group = orm.relationship(
1489 ShareGroup,
1490 backref="share_types",
1491 foreign_keys=share_group_id,
1492 primaryjoin=('and_('
1493 'ShareGroupShareTypeMapping.share_group_id '
1494 '== ShareGroup.id,'
1495 'ShareGroupShareTypeMapping.deleted == "False")')
1496 )
1499class Message(BASE, ManilaBase):
1500 """Represents a user message.
1502 User messages show information about API operations to the API end-user.
1503 """
1504 __tablename__ = 'messages'
1505 id = Column(String(36), primary_key=True, nullable=False)
1506 project_id = Column(String(255), nullable=False)
1507 # Info/Error/Warning.
1508 message_level = Column(String(255), nullable=False)
1509 request_id = Column(String(255), nullable=True)
1510 resource_type = Column(String(255))
1511 # The uuid of the related resource.
1512 resource_id = Column(String(36), nullable=True)
1513 # Operation specific action ID, this ID is mapped
1514 # to a message in manila/message/message_field.py
1515 action_id = Column(String(10), nullable=False)
1516 # After this time the message may no longer exist.
1517 expires_at = Column(DateTime, nullable=True)
1518 # Message detail ID, this ID is mapped
1519 # to a message in manila/message/message_field.py
1520 detail_id = Column(String(10), nullable=True)
1521 deleted = Column(String(36), default='False')
1524class ResourceLock(BASE, ManilaBase):
1525 """Represents a resource lock.
1527 Resource locks are held by users (or on behalf of users) and prevent
1528 actions to be performed on resources while the lock is present.
1529 """
1530 __tablename__ = 'resource_locks'
1531 id = Column(String(36), primary_key=True, nullable=False)
1532 user_id = Column(String(255), nullable=False)
1533 project_id = Column(String(255), nullable=False)
1534 # If the lock is held on behalf of the user, but created by 'service' or
1535 # 'admin' users, as opposed to the user themselves ('project')
1536 lock_context = Column(String(10), nullable=False)
1537 # The uuid of the resource being locked.
1538 resource_id = Column(String(36), nullable=False)
1539 # The resource type, a constant dict will hold possible values
1540 resource_type = Column(Enum(*constants.RESOURCE_LOCK_RESOURCE_TYPES),
1541 default=constants.SHARE_RESOURCE_TYPE)
1542 # Action that lock prevents, a constant dict will hold possible values
1543 resource_action = Column(Enum(*constants.RESOURCE_LOCK_RESOURCE_ACTIONS),
1544 default=constants.RESOURCE_ACTION_DELETE)
1545 lock_reason = Column(String(1023), nullable=True)
1546 deleted = Column(String(36), default='False')
1549class BackendInfo(BASE, ManilaBase):
1550 """Represent Backend Info."""
1551 __tablename__ = "backend_info"
1552 host = Column(String(255), primary_key=True)
1553 info_hash = Column(String(255))
1556class AsynchronousOperationData(BASE, ManilaBase):
1557 """Represents data as key-value pairs for asynchronous operations."""
1558 __tablename__ = 'async_operation_data'
1559 entity_uuid = Column(String(36), nullable=False, primary_key=True)
1560 key = Column(String(255), nullable=False, primary_key=True)
1561 value = Column(String(1023), nullable=False)
1564class ShareBackup(BASE, ManilaBase):
1565 """Represents a backup of a share."""
1566 __tablename__ = 'share_backups'
1567 id = Column(String(36), primary_key=True)
1569 @property
1570 def name(self):
1571 return CONF.share_backup_name_template % self.id
1573 @property
1574 def availability_zone(self):
1575 if self._availability_zone:
1576 return self._availability_zone['name']
1578 deleted = Column(String(36), default='False')
1579 user_id = Column(String(255), nullable=False)
1580 project_id = Column(String(255), nullable=False)
1582 share_id = Column(String(36), ForeignKey('shares.id'))
1583 size = Column(Integer)
1584 host = Column(String(255))
1585 topic = Column(String(255))
1586 display_name = Column(String(255))
1587 display_description = Column(String(255))
1588 progress = Column(String(32))
1589 restore_progress = Column(String(32))
1590 status = Column(String(255))
1591 fail_reason = Column(String(1023))
1592 backup_type = Column(String(32))
1593 availability_zone_id = Column(String(36),
1594 ForeignKey('availability_zones.id'),
1595 nullable=True)
1597 _availability_zone = orm.relationship(
1598 "AvailabilityZone",
1599 lazy='immediate',
1600 primaryjoin=(
1601 'and_('
1602 'ShareBackup.availability_zone_id == '
1603 'AvailabilityZone.id, '
1604 'AvailabilityZone.deleted == \'False\')'
1605 )
1606 )
1609def register_models():
1610 """Register Models and create metadata.
1612 Called from manila.db.sqlalchemy.__init__ as part of loading the driver,
1613 it will never need to be called explicitly elsewhere unless the
1614 connection is lost and needs to be reestablished.
1615 """
1616 from sqlalchemy import create_engine
1617 models = (Service,
1618 Share,
1619 ShareAccessMapping,
1620 ShareSnapshot
1621 )
1622 engine = create_engine(CONF.database.connection, echo=False)
1623 for model in models:
1624 model.metadata.create_all(engine)
1627def get_access_rules_status(instances):
1628 share_access_status = constants.STATUS_ACTIVE
1630 if len(instances) == 0:
1631 return share_access_status
1633 priorities = ShareInstance.ACCESS_STATUS_PRIORITIES
1635 for instance in instances:
1636 if instance['status'] != constants.STATUS_AVAILABLE:
1637 continue
1639 instance_access_status = instance['access_rules_status']
1641 if priorities.get(instance_access_status) > priorities.get(
1642 share_access_status):
1643 share_access_status = instance_access_status
1645 if share_access_status == constants.SHARE_INSTANCE_RULES_ERROR:
1646 break
1648 return share_access_status
1651def get_aggregated_access_rules_state(instance_mappings):
1652 state = None
1653 if len(instance_mappings) > 0: 1653 ↛ 1667line 1653 didn't jump to line 1667 because the condition on line 1653 was always true
1654 order = (constants.ACCESS_STATE_ERROR,
1655 constants.ACCESS_STATE_DENYING,
1656 constants.ACCESS_STATE_QUEUED_TO_DENY,
1657 constants.ACCESS_STATE_QUEUED_TO_UPDATE,
1658 constants.ACCESS_STATE_QUEUED_TO_APPLY,
1659 constants.ACCESS_STATE_UPDATING,
1660 constants.ACCESS_STATE_APPLYING,
1661 constants.ACCESS_STATE_ACTIVE)
1663 sorted_instance_mappings = sorted(
1664 instance_mappings, key=lambda x: order.index(x['state']))
1666 state = sorted_instance_mappings[0].state
1667 return state