def _basic_action(self, lease_id, event_id, action_time, reservation_status=None): """Commits basic lease actions such as starting and ending.""" lease = self.get_lease(lease_id) event_status = 'DONE' for reservation in lease['reservations']: resource_type = reservation['resource_type'] try: self.resource_actions[resource_type][action_time]( reservation['resource_id'] ) except common_ex.ClimateException: LOG.exception("Failed to execute action %(action)s " "for lease %(lease)s" % { 'action': action_time, 'lease': lease_id, }) event_status = 'ERROR' db_api.reservation_update(reservation['id'], {'status': 'error'}) else: if reservation_status is not None: db_api.reservation_update(reservation['id'], {'status': reservation_status}) db_api.event_update(event_id, {'status': event_status})
def _update_before_end_event(self, old_lease, new_lease, notifications, before_end_date=None): event = db_api.event_get_first_sorted_by_filters( 'lease_id', 'asc', { 'lease_id': old_lease['id'], 'event_type': 'before_end_lease' } ) if event: # NOTE(casanch1) do nothing if the event does not exist. # This is for backward compatibility update_values = {} if not before_end_date: # before_end_date needs to be calculated based on # previous delta prev_before_end_delta = old_lease['end_date'] - event['time'] before_end_date = new_lease['end_date'] - prev_before_end_delta self._update_before_end_event_date(update_values, before_end_date, new_lease) if event['status'] == 'DONE': update_values['status'] = 'UNDONE' notifications.append('event.before_end_lease.stop') db_api.event_update(event['id'], update_values)
def _event(self): """Tries to commit event. If there is an event in Climate DB to be done, do it and change its status to 'DONE'. """ LOG.debug('Trying to get event from DB.') event = db_api.event_get_first_sorted_by_filters( sort_key='time', sort_dir='asc', filters={'status': 'UNDONE'} ) if not event: return if event['time'] < datetime.datetime.now(): db_api.event_update(event['id'], {'status': 'IN_PROGRESS'}) event_type = event['event_type'] event_fn = getattr(self, event_type, None) if event_fn is None: raise exceptions.EventError(error='Event type %s is not ' 'supported' % event_type) try: eventlet.spawn_n(service_utils.with_empty_context(event_fn), event['lease_id'], event['id']) lease = db_api.lease_get(event['lease_id']) with trusts.create_ctx_from_trust(lease['trust_id']) as ctx: self._send_notification(lease, ctx, events=['event.%s' % event_type]) except Exception: db_api.event_update(event['id'], {'status': 'ERROR'}) LOG.exception(_('Error occurred while event handling.'))
def _event(self): """Tries to commit event. If there is an event in Climate DB to be done, do it and change its status to 'DONE'. """ LOG.debug('Trying to get event from DB.') event = db_api.event_get_first_sorted_by_filters( sort_key='time', sort_dir='asc', filters={'status': 'UNDONE'} ) if not event: return if event['time'] < datetime.datetime.utcnow(): db_api.event_update(event['id'], {'status': 'IN_PROGRESS'}) event_type = event['event_type'] event_fn = getattr(self, event_type, None) if event_fn is None: raise exceptions.EventError(error='Event type %s is not ' 'supported' % event_type) try: eventlet.spawn_n(service_utils.with_empty_context(event_fn), event['lease_id'], event['id']) lease = db_api.lease_get(event['lease_id']) with trusts.create_ctx_from_trust(lease['trust_id']) as ctx: self._send_notification(lease, ctx, events=['event.%s' % event_type]) except Exception: db_api.event_update(event['id'], {'status': 'ERROR'}) LOG.exception(_('Error occurred while event handling.'))
def _basic_action(self, lease_id, event_id, action_time, reservation_status=None): """Commits basic lease actions such as starting and ending.""" lease = self.get_lease(lease_id) event_status = 'DONE' for reservation in lease['reservations']: resource_type = reservation['resource_type'] try: self.resource_actions[resource_type][action_time]( reservation['resource_id']) except common_ex.ClimateException: LOG.exception("Failed to execute action %(action)s " "for lease %(lease)s" % { 'action': action_time, 'lease': lease_id, }) event_status = 'ERROR' db_api.reservation_update(reservation['id'], {'status': 'error'}) else: if reservation_status is not None: db_api.reservation_update(reservation['id'], {'status': reservation_status}) db_api.event_update(event_id, {'status': event_status})
def _event(self): """Tries to commit event. If there is an event in Climate DB to be done, do it and change its status to 'DONE'. """ LOG.debug('Trying to get event from DB.') events = db_api.event_get_all_sorted_by_filters( sort_key='time', sort_dir='asc', filters={'status': 'UNDONE'} ) if not events: return event = events[0] if event['time'] < datetime.datetime.utcnow(): db_api.event_update(event['id'], {'status': 'IN_PROGRESS'}) event_type = event['event_type'] event_fn = getattr(self, event_type, None) if event_fn is None: raise exceptions.ClimateException('Event type %s is not ' 'supported' % event_type) try: eventlet.spawn_n(service_utils.with_empty_context(event_fn), event['lease_id'], event['id']) except Exception: db_api.event_update(event['id'], {'status': 'ERROR'}) LOG.exception('Error occurred while event handling.')
def _event(self): """Tries to commit event. If there is an event in Climate DB to be done, do it and change its status to 'DONE'. """ LOG.debug(_("Trying to get event from DB.")) events = db_api.event_get_all_sorted_by_filters(sort_key="time", sort_dir="asc", filters={"status": "UNDONE"}) if not events: return event = events[0] if event["time"] < datetime.datetime.utcnow(): db_api.event_update(event["id"], {"status": "IN_PROGRESS"}) event_type = event["event_type"] event_fn = getattr(self, event_type, None) if event_fn is None: raise exceptions.ClimateException("Event type %s is not " "supported" % event_type) try: eventlet.spawn_n(service_utils.with_empty_context(event_fn), event["lease_id"], event["id"]) except Exception: db_api.event_update(event["id"], {"status": "ERROR"}) LOG.exception(_("Error occurred while event handling."))
def _basic_action(self, lease_id, event_id, action_time, reservation_status=None): """Commits basic lease actions such as starting and ending.""" lease = self.get_lease(lease_id) for reservation in lease['reservations']: resource_type = reservation['resource_type'] self.resource_actions[resource_type][action_time]( reservation['resource_id'] ) if reservation_status is not None: db_api.reservation_update(reservation['id'], {'status': reservation_status}) db_api.event_update(event_id, {'status': 'DONE'})
def _basic_action(self, lease_id, event_id, action_time, reservation_status=None): """Commits basic lease actions such as starting and ending.""" lease = self.get_lease(lease_id) for reservation in lease["reservations"]: resource_type = reservation["resource_type"] try: self.resource_actions[resource_type][action_time](reservation["resource_id"]) except exceptions.ClimateException: LOG.exception( "Failed to execute action %(action)s " "for lease %(lease)d" % {"action": action_time, "lease": lease_id} ) if reservation_status is not None: db_api.reservation_update(reservation["id"], {"status": reservation_status}) db_api.event_update(event_id, {"status": "DONE"})
def before_end_lease(self, lease_id, event_id): db_api.event_update(event_id, {'status': 'DONE'})
def update_lease(self, lease_id, values): if not values: return db_api.lease_get(lease_id) if len(values) == 1 and 'name' in values: db_api.lease_update(lease_id, values) return db_api.lease_get(lease_id) lease = db_api.lease_get(lease_id) start_date = values.get( 'start_date', datetime.datetime.strftime(lease['start_date'], LEASE_DATE_FORMAT)) end_date = values.get( 'end_date', datetime.datetime.strftime(lease['end_date'], LEASE_DATE_FORMAT)) before_end_date = values.get('before_end_notification', None) now = datetime.datetime.now() now = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute) if start_date == 'now': start_date = now else: start_date = self._date_from_string(start_date) end_date = self._date_from_string(end_date) values['start_date'] = start_date values['end_date'] = end_date if (lease['start_date'] < now and values['start_date'] != lease['start_date']): raise common_ex.NotAuthorized( 'Cannot modify the start date of already started leases') if (lease['start_date'] > now and values['start_date'] < now): raise common_ex.NotAuthorized( 'Start date must later than current date') if lease['end_date'] < now: raise common_ex.NotAuthorized( 'Terminated leases can only be renamed') if (values['end_date'] < now or values['end_date'] < values['start_date']): raise common_ex.NotAuthorized( 'End date must be later than current and start date') with trusts.create_ctx_from_trust(lease['trust_id']): if before_end_date: try: before_end_date = self._date_from_string(before_end_date) self._check_date_within_lease_limits(before_end_date, values) except common_ex.ClimateException as e: LOG.error("Invalid before_end_date param. %s" % e.message) raise e # TODO(frossigneux) rollback if an exception is raised for reservation in ( db_api.reservation_get_all_by_lease_id(lease_id)): reservation['start_date'] = values['start_date'] reservation['end_date'] = values['end_date'] resource_type = reservation['resource_type'] self.plugins[resource_type].update_reservation( reservation['id'], reservation) event = db_api.event_get_first_sorted_by_filters( 'lease_id', 'asc', { 'lease_id': lease_id, 'event_type': 'start_lease' } ) if not event: raise common_ex.ClimateException( 'Start lease event not found') db_api.event_update(event['id'], {'time': values['start_date']}) event = db_api.event_get_first_sorted_by_filters( 'lease_id', 'asc', { 'lease_id': lease_id, 'event_type': 'end_lease' } ) if not event: raise common_ex.ClimateException( 'End lease event not found') db_api.event_update(event['id'], {'time': values['end_date']}) notifications = ['update'] self._update_before_end_event(lease, values, notifications, before_end_date) db_api.lease_update(lease_id, values) lease = db_api.lease_get(lease_id) with trusts.create_ctx_from_trust(lease['trust_id']) as ctx: self._send_notification(lease, ctx, events=notifications) return lease
def _basic_action(self, lease_id, event_id, action_time, reservation_status=None): """Commits basic lease actions such as starting and ending.""" lease = self.get_lease(lease_id) event_status = 'DONE' if action_time == 'on_start': lease_action = states.lease.START status_reason = "Starting lease..." elif action_time == 'on_end': lease_action = states.lease.STOP status_reason = "Stopping lease..." else: raise AttributeError("action_time is %s instead of either on_start or on_end" % action_time) lease_state = states.LeaseState(id=lease_id, action=lease_action, status=states.lease.IN_PROGRESS, status_reason=status_reason) lease_state.save() for reservation in lease['reservations']: resource_type = reservation['resource_type'] try: self.resource_actions[resource_type][action_time]( reservation['resource_id'] ) except common_ex.ClimateException: LOG.exception("Failed to execute action %(action)s " "for lease %(lease)s" % { 'action': action_time, 'lease': lease_id, }) event_status = 'ERROR' db_api.reservation_update(reservation['id'], {'status': 'error'}) else: if reservation_status is not None: db_api.reservation_update(reservation['id'], {'status': reservation_status}) db_api.event_update(event_id, {'status': event_status}) if event_status == 'DONE': lease_status = states.lease.COMPLETE if action_time == 'on_start': status_reason = "Successfully started lease" elif action_time == 'on_end': status_reason = "Successfully stopped lease" else: raise AttributeError("action_time is %s instead of either on_start or on_end" % action_time) elif event_status == 'ERROR': lease_status = states.lease.FAILED if action_time == 'on_start': status_reason = "Failed to start lease" elif action_time == 'on_end': status_reason = "Failed to stop lease" else: raise AttributeError("action_time is %s instead of either on_start or on_end" % action_time) else: raise AttributeError("event_status is %s instead of either DONE or ERROR" % event_status) lease_state.update(action=lease_action, status=lease_status, status_reason=status_reason) lease_state.save()
def update_lease(self, lease_id, values): if not values: return db_api.lease_get(lease_id) if len(values) == 1 and 'name' in values: db_api.lease_update(lease_id, values) return db_api.lease_get(lease_id) lease = db_api.lease_get(lease_id) start_date = values.get( 'start_date', datetime.datetime.strftime(lease['start_date'], LEASE_DATE_FORMAT)) end_date = values.get( 'end_date', datetime.datetime.strftime(lease['end_date'], LEASE_DATE_FORMAT)) before_end_date = values.get('before_end_notification', None) now = datetime.datetime.utcnow() now = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute) if start_date == 'now': start_date = now else: start_date = self._date_from_string(start_date) end_date = self._date_from_string(end_date) values['start_date'] = start_date values['end_date'] = end_date if (lease['start_date'] < now and values['start_date'] != lease['start_date']): raise common_ex.NotAuthorized( 'Cannot modify the start date of already started leases') if (lease['start_date'] > now and values['start_date'] < now): raise common_ex.NotAuthorized( 'Start date must later than current date') if lease['end_date'] < now: raise common_ex.NotAuthorized( 'Terminated leases can only be renamed') if (values['end_date'] < now or values['end_date'] < values['start_date']): raise common_ex.NotAuthorized( 'End date must be later than current and start date') with trusts.create_ctx_from_trust(lease['trust_id']): if before_end_date: try: before_end_date = self._date_from_string(before_end_date) self._check_date_within_lease_limits(before_end_date, values) except common_ex.ClimateException as e: LOG.error("Invalid before_end_date param. %s" % e.message) raise e # TODO(frossigneux) rollback if an exception is raised for reservation in ( db_api.reservation_get_all_by_lease_id(lease_id)): reservation['start_date'] = values['start_date'] reservation['end_date'] = values['end_date'] resource_type = reservation['resource_type'] self.plugins[resource_type].update_reservation( reservation['id'], reservation) event = db_api.event_get_first_sorted_by_filters( 'lease_id', 'asc', { 'lease_id': lease_id, 'event_type': 'start_lease' } ) if not event: raise common_ex.ClimateException( 'Start lease event not found') db_api.event_update(event['id'], {'time': values['start_date']}) event = db_api.event_get_first_sorted_by_filters( 'lease_id', 'asc', { 'lease_id': lease_id, 'event_type': 'end_lease' } ) if not event: raise common_ex.ClimateException( 'End lease event not found') db_api.event_update(event['id'], {'time': values['end_date']}) notifications = ['update'] self._update_before_end_event(lease, values, notifications, before_end_date) db_api.lease_update(lease_id, values) lease_state = states.LeaseState(id=lease_id, action=states.lease.UPDATE, status=states.lease.COMPLETE, status_reason="Successfully updated lease") lease_state.save() lease = db_api.lease_get(lease_id) with trusts.create_ctx_from_trust(lease['trust_id']) as ctx: self._send_notification(lease, ctx, events=notifications) return lease