class NotificationApiPayloadBase(base.NotificationPayloadBase): SCHEMA = { 'id': ('notification', 'id'), 'notification_uuid': ('notification', 'notification_uuid'), 'generated_time': ('notification', 'generated_time'), 'source_host_uuid': ('notification', 'source_host_uuid'), 'type': ('notification', 'type'), 'payload': ('notification', 'payload'), 'status': ('notification', 'status'), } # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'notification_uuid': fields.UUIDField(), 'generated_time': fields.DateTimeField(), 'source_host_uuid': fields.UUIDField(), 'type': fields.NotificationTypeField(), 'payload': fields.DictOfStringsField(), 'status': fields.NotificationStatusField(), } def __init__(self, notification, **kwargs): super(NotificationApiPayloadBase, self).__init__(**kwargs) self.populate_schema(notification=notification)
class HostApiPayloadBase(base.NotificationPayloadBase): SCHEMA = { 'id': ('host', 'id'), 'uuid': ('host', 'uuid'), 'name': ('host', 'name'), 'failover_segment_id': ('host', 'failover_segment_id'), 'failover_segment': ('host', 'failover_segment'), 'type': ('host', 'type'), 'reserved': ('host', 'reserved'), 'control_attributes': ('host', 'control_attributes'), 'on_maintenance': ('host', 'on_maintenance'), } # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'uuid': fields.UUIDField(), 'name': fields.StringField(), 'failover_segment_id': fields.UUIDField(), 'failover_segment': fields.ObjectField('FailoverSegment'), 'type': fields.StringField(), 'reserved': fields.BooleanField(), 'control_attributes': fields.StringField(), 'on_maintenance': fields.BooleanField(), } def __init__(self, host, **kwargs): super(HostApiPayloadBase, self).__init__(**kwargs) self.populate_schema(host=host)
class SegmentApiPayloadBase(base.NotificationPayloadBase): SCHEMA = { 'id': ('segment', 'id'), 'uuid': ('segment', 'uuid'), 'name': ('segment', 'name'), 'service_type': ('segment', 'service_type'), 'description': ('segment', 'description'), 'recovery_method': ('segment', 'recovery_method'), 'enabled': ('segment', 'enabled'), } # Version 1.0: Initial version # Version 1.1: Add 'enabled' field VERSION = '1.1' fields = { 'id': fields.IntegerField(), 'uuid': fields.UUIDField(), 'name': fields.StringField(), 'service_type': fields.StringField(), 'description': fields.StringField(nullable=True), 'recovery_method': fields.FailoverSegmentRecoveryMethodField(), 'enabled': fields.BooleanField(), } def __init__(self, segment, **kwargs): super(SegmentApiPayloadBase, self).__init__(**kwargs) self.populate_schema(segment=segment)
class Host(base.MasakariPersistentObject, base.MasakariObject, base.MasakariObjectDictCompat): # Version 1.0: Initial version # Version 1.1: Added 'segment_uuid' parameter to 'get_by_uuid' method VERSION = '1.1' fields = { 'id': fields.IntegerField(), 'uuid': fields.UUIDField(), 'name': fields.StringField(), 'failover_segment_id': fields.UUIDField(), 'failover_segment': fields.ObjectField('FailoverSegment'), 'type': fields.StringField(), 'reserved': fields.BooleanField(), 'control_attributes': fields.StringField(), 'on_maintenance': fields.BooleanField(), } @staticmethod def _from_db_object(context, host, db_host): for key in host.fields: db_value = db_host.get(key) if key == "failover_segment": db_value = objects.FailoverSegment._from_db_object( host._context, objects.FailoverSegment(), db_value) setattr(host, key, db_value) host.obj_reset_changes() host._context = context return host @base.remotable_classmethod def get_by_id(cls, context, id): db_inst = db.host_get_by_id(context, id) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_uuid(cls, context, uuid, segment_uuid=None): db_inst = db.host_get_by_uuid(context, uuid, segment_uuid=segment_uuid) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_name(cls, context, name): db_inst = db.host_get_by_name(context, name) return cls._from_db_object(context, cls(), db_inst) @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') updates = self.masakari_obj_get_changes() if 'uuid' not in updates: updates['uuid'] = uuidutils.generate_uuid() LOG.debug('Generated uuid %(uuid)s for host', dict(uuid=updates['uuid'])) if 'failover_segment' in updates: raise exception.ObjectActionError(action='create', reason='failover segment ' 'assigned') api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_CREATE, phase=fields.EventNotificationPhase.START) db_host = db.host_create(self._context, updates) api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_CREATE, phase=fields.EventNotificationPhase.END) self._from_db_object(self._context, self, db_host) @base.remotable def save(self): updates = self.masakari_obj_get_changes() if 'failover_segment' in updates: raise exception.ObjectActionError(action='save', reason='failover segment ' 'changed') updates.pop('id', None) api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_UPDATE, phase=fields.EventNotificationPhase.START) db_host = db.host_update(self._context, self.uuid, updates) api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_UPDATE, phase=fields.EventNotificationPhase.END) self._from_db_object(self._context, self, db_host) @base.remotable def destroy(self): if not self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='destroy', reason='already destroyed') if not self.obj_attr_is_set('uuid'): raise exception.ObjectActionError(action='destroy', reason='no uuid') api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_DELETE, phase=fields.EventNotificationPhase.START) db.host_delete(self._context, self.uuid) api_utils.notify_about_host_api( self._context, self, action=fields.EventNotificationAction.HOST_DELETE, phase=fields.EventNotificationPhase.END) delattr(self, base.get_attrname('id'))
class Notification(base.MasakariPersistentObject, base.MasakariObject, base.MasakariObjectDictCompat): # Version 1.0: Initial version # Version 1.1: Added recovery_workflow_details field. # Note: This field shouldn't be persisted. VERSION = '1.1' fields = { 'id': fields.IntegerField(), 'notification_uuid': fields.UUIDField(), 'generated_time': fields.DateTimeField(), 'source_host_uuid': fields.UUIDField(), 'type': fields.NotificationTypeField(), 'payload': fields.DictOfStringsField(), 'status': fields.NotificationStatusField(), # NOTE(ShilpaSD): This field shouldn't be stored in db. # The recovery workflow details read from the 'notification_driver' # will be set to this field. 'recovery_workflow_details': fields.ListOfObjectsField('NotificationProgressDetails', default=[]) } @staticmethod def _from_db_object(context, notification, db_notification): for key in notification.fields: if key in NOTIFICATION_OPTIONAL_FIELDS: continue if key != 'payload': setattr(notification, key, db_notification.get(key)) else: payload = db_notification.get("payload") notification.payload = jsonutils.loads(payload) notification.obj_reset_changes() notification._context = context return notification @base.remotable_classmethod def get_by_id(cls, context, id): db_notification = db.notification_get_by_id(context, id) return cls._from_db_object(context, cls(), db_notification) @base.remotable_classmethod def get_by_uuid(cls, context, uuid): db_notification = db.notification_get_by_uuid(context, uuid) return cls._from_db_object(context, cls(), db_notification) @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') updates = self.masakari_obj_get_changes() # NOTE(ShilpaSD): This field doesn't exist in the Notification # db model so don't save it. updates.pop('recovery_workflow_details', None) if 'notification_uuid' not in updates: updates['notification_uuid'] = uuidutils.generate_uuid() LOG.debug('Generated uuid %(uuid)s for notifications', dict(uuid=updates['notification_uuid'])) if 'payload' in updates: updates['payload'] = jsonutils.dumps(updates['payload']) api_utils.notify_about_notification_api( self._context, self, action=fields.EventNotificationAction.NOTIFICATION_CREATE, phase=fields.EventNotificationPhase.START) db_notification = db.notification_create(self._context, updates) api_utils.notify_about_notification_api( self._context, self, action=fields.EventNotificationAction.NOTIFICATION_CREATE, phase=fields.EventNotificationPhase.END) self._from_db_object(self._context, self, db_notification) @base.remotable def save(self): updates = self.masakari_obj_get_changes() updates.pop('id', None) # NOTE(ShilpaSD): This field doesn't exist in the Notification # db model so don't save it. updates.pop('recovery_workflow_details', None) db_notification = db.notification_update(self._context, self.notification_uuid, updates) self._from_db_object(self._context, self, db_notification) @base.remotable def destroy(self): if not self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='destroy', reason='already destroyed') if not self.obj_attr_is_set('notification_uuid'): raise exception.ObjectActionError(action='destroy', reason='no uuid') db.notification_delete(self._context, self.notification_uuid) delattr(self, base.get_attrname('id'))
class FailoverSegment(base.MasakariPersistentObject, base.MasakariObject, base.MasakariObjectDictCompat): # 1.0, init # 1.1, add enabled field VERSION = '1.1' fields = { 'id': fields.IntegerField(), 'uuid': fields.UUIDField(), 'name': fields.StringField(), 'service_type': fields.StringField(), 'enabled': fields.BooleanField(default=True), 'description': fields.StringField(nullable=True), 'recovery_method': fields.FailoverSegmentRecoveryMethodField(), } def obj_make_compatible(self, primitive, target_version): super(FailoverSegment, self).obj_make_compatible(primitive, target_version) target_version = versionutils.convert_version_to_tuple(target_version) if target_version < (1, 1) and 'enabled' in primitive: del primitive['enabled'] @staticmethod def _from_db_object(context, segment, db_segment): for key in segment.fields: setattr(segment, key, db_segment[key]) segment._context = context segment.obj_reset_changes() return segment @base.remotable_classmethod def get_by_id(cls, context, id): db_inst = db.failover_segment_get_by_id(context, id) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_uuid(cls, context, uuid): db_inst = db.failover_segment_get_by_uuid(context, uuid) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_name(cls, context, name): db_inst = db.failover_segment_get_by_name(context, name) return cls._from_db_object(context, cls(), db_inst) @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') updates = self.masakari_obj_get_changes() if 'uuid' not in updates: updates['uuid'] = uuidutils.generate_uuid() LOG.debug('Generated uuid %(uuid)s for failover segment', dict(uuid=updates['uuid'])) api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_CREATE, phase=fields.EventNotificationPhase.START) db_segment = db.failover_segment_create(self._context, updates) api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_CREATE, phase=fields.EventNotificationPhase.END) self._from_db_object(self._context, self, db_segment) @base.remotable def save(self): updates = self.masakari_obj_get_changes() updates.pop('id', None) api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_UPDATE, phase=fields.EventNotificationPhase.START) db_segment = db.failover_segment_update(self._context, self.uuid, updates) api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_UPDATE, phase=fields.EventNotificationPhase.END) self._from_db_object(self._context, self, db_segment) @base.remotable def destroy(self): if not self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='destroy', reason='already destroyed') if not self.obj_attr_is_set('uuid'): raise exception.ObjectActionError(action='destroy', reason='no uuid') api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_DELETE, phase=fields.EventNotificationPhase.START) db.failover_segment_delete(self._context, self.uuid) api_utils.notify_about_segment_api( self._context, self, action=fields.EventNotificationAction.SEGMENT_DELETE, phase=fields.EventNotificationPhase.END) delattr(self, base.get_attrname('id')) def is_under_recovery(self, filters=None): return db.is_failover_segment_under_recovery(self._context, self.uuid, filters=filters)
class Notification(base.MasakariPersistentObject, base.MasakariObject, base.MasakariObjectDictCompat): VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'notification_uuid': fields.UUIDField(), 'generated_time': fields.DateTimeField(), 'source_host_uuid': fields.UUIDField(), 'type': fields.NotificationTypeField(), 'payload': fields.DictOfStringsField(), 'status': fields.NotificationStatusField(), } @staticmethod def _from_db_object(context, notification, db_notification): for key in notification.fields: if key != 'payload': setattr(notification, key, db_notification.get(key)) else: payload = db_notification.get("payload") notification.payload = jsonutils.loads(payload) notification.obj_reset_changes() notification._context = context return notification @base.remotable_classmethod def get_by_id(cls, context, id): db_notification = db.notification_get_by_id(context, id) return cls._from_db_object(context, cls(), db_notification) @base.remotable_classmethod def get_by_uuid(cls, context, uuid): db_notification = db.notification_get_by_uuid(context, uuid) return cls._from_db_object(context, cls(), db_notification) @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') updates = self.masakari_obj_get_changes() if 'notification_uuid' not in updates: updates['notification_uuid'] = uuidutils.generate_uuid() LOG.debug('Generated uuid %(uuid)s for notifications', dict(uuid=updates['notification_uuid'])) if 'payload' in updates: updates['payload'] = jsonutils.dumps(updates['payload']) db_notification = db.notification_create(self._context, updates) self._from_db_object(self._context, self, db_notification) @base.remotable def save(self): updates = self.masakari_obj_get_changes() updates.pop('id', None) db_notification = db.notification_update(self._context, self.notification_uuid, updates) self._from_db_object(self._context, self, db_notification) @base.remotable def destroy(self): if not self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='destroy', reason='already destroyed') if not self.obj_attr_is_set('notification_uuid'): raise exception.ObjectActionError(action='destroy', reason='no uuid') db.notification_delete(self._context, self.notification_uuid) delattr(self, base.get_attrname('id'))
class FailoverSegment(base.MasakariPersistentObject, base.MasakariObject, base.MasakariObjectDictCompat): VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'uuid': fields.UUIDField(), 'name': fields.StringField(), 'service_type': fields.StringField(), 'description': fields.StringField(nullable=True), 'recovery_method': fields.FailoverSegmentRecoveryMethodField(), } @staticmethod def _from_db_object(context, segment, db_segment): for key in segment.fields: setattr(segment, key, db_segment[key]) segment._context = context segment.obj_reset_changes() return segment @base.remotable_classmethod def get_by_id(cls, context, id): db_inst = db.failover_segment_get_by_id(context, id) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_uuid(cls, context, uuid): db_inst = db.failover_segment_get_by_uuid(context, uuid) return cls._from_db_object(context, cls(), db_inst) @base.remotable_classmethod def get_by_name(cls, context, name): db_inst = db.failover_segment_get_by_name(context, name) return cls._from_db_object(context, cls(), db_inst) @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason='already created') updates = self.masakari_obj_get_changes() if 'uuid' not in updates: updates['uuid'] = uuidutils.generate_uuid() LOG.debug('Generated uuid %(uuid)s for failover segment', dict(uuid=updates['uuid'])) db_segment = db.failover_segment_create(self._context, updates) self._from_db_object(self._context, self, db_segment) @base.remotable def save(self): updates = self.masakari_obj_get_changes() updates.pop('id', None) db_segment = db.failover_segment_update(self._context, self.uuid, updates) self._from_db_object(self._context, self, db_segment) @base.remotable def destroy(self): if not self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='destroy', reason='already destroyed') if not self.obj_attr_is_set('uuid'): raise exception.ObjectActionError(action='destroy', reason='no uuid') db.failover_segment_delete(self._context, self.uuid) delattr(self, base.get_attrname('id')) def is_under_recovery(self, filters=None): return db.is_failover_segment_under_recovery(self._context, self.uuid, filters=filters)