Example #1
0
    def __init__(self, user_id, **kwargs):
        self.id = kwargs.get('id')
        self.user_id = user_id

        self.resource_id = kwargs.get('resource_id')
        self.resource_type = kwargs.get('resource_type')

        self.start_time = utils.make_decimal(kwargs.get('start_time', 0))
        self.end_time = utils.make_decimal(kwargs.get('end_time', 0))
        self.rate = utils.make_decimal(kwargs.get('rate', 0))
        self.cost = utils.make_decimal(kwargs.get('cost', 0))
        self.metadata = kwargs.get('metadata')
Example #2
0
 def execute(self, context, resource, values, resource_bak, **kwargs):
     old_rate = resource.rate
     resource.properties = values.get('properties')
     rule = plugin_base.Rule.load(context, rule_id=resource.rule_id)
     resource.rate = utils.make_decimal(rule.get_price(resource))
     resource.delta_rate = resource.rate - old_rate
     resource.store(context)
Example #3
0
    def settle_account(self, context, task=None):
        '''Settle account for user.'''

        notifier = bilean_notifier.Notifier()
        timestamp = utils.make_decimal(wallclock())
        self._settle_account(context, timestamp=timestamp)

        if task == 'notify' and self._notify_or_not():
            self.status_reason = "The balance is almost used up"
            self.status = self.WARNING
            # Notify user
            msg = {'user': self.id, 'notification': self.status_reason}
            notifier.info('billing.notify', msg)
        elif task == 'freeze' and self.balance <= 0:
            reason = _("Balance overdraft")
            LOG.info(_LI("Freeze user %(user_id)s, reason: %(reason)s"),
                     {'user_id': self.id, 'reason': reason})
            resources = plugin_base.Resource.load_all(
                context, user_id=self.id, project_safe=False)
            for resource in resources:
                resource.do_delete(context, timestamp=timestamp)
            self.rate = 0
            self.status = self.FREEZE
            self.status_reason = reason
            # Notify user
            msg = {'user': self.id, 'notification': self.status_reason}
            notifier.info('billing.notify', msg)

        self.store(context)
Example #4
0
    def do_recharge(self, context, value, recharge_type=None, timestamp=None,
                    metadata=None):
        """Recharge for user and update status.

        param context: The request context.
        param value: Recharge value.
        param recharge_type: Rechage type, 'Recharge'|'System bonus'.
        param timestamp: Record when recharge action occurs.
        param metadata: Some other keyword.
        """
        self.balance += utils.make_decimal(value)
        if self.status == self.INIT and self.balance > 0:
            self.status = self.FREE
            self.status_reason = "Recharged"
        elif self.status == self.FREEZE and self.balance > 0:
            reason = _("Status change from 'FREEZE' to 'FREE' because "
                       "of recharge.")
            self.status = self.FREE
            self.status_reason = reason
        elif self.status == self.WARNING:
            if not self._notify_or_not():
                reason = _("Status change from 'WARNING' to 'ACTIVE' because "
                           "of recharge.")
                self.status = self.ACTIVE
                self.status_reason = reason
        self.store(context)

        # Create recharge record
        values = {'user_id': self.id,
                  'value': value,
                  'type': recharge_type,
                  'timestamp': timestamp,
                  'metadata': metadata}
        db_api.recharge_create(context, values)
Example #5
0
 def _notify_or_not(self):
     '''Check if user should be notified.'''
     cfg.CONF.import_opt('prior_notify_time',
                         'bilean.scheduler.cron_scheduler',
                         group='scheduler')
     prior_notify_time = cfg.CONF.scheduler.prior_notify_time * 3600
     rest_usage = utils.make_decimal(prior_notify_time) * self.rate
     return self.balance < rest_usage
Example #6
0
    def __init__(self, user_id, **kwargs):
        self.id = user_id
        self.name = kwargs.get('name')
        self.policy_id = kwargs.get('policy_id')
        self.balance = utils.make_decimal(kwargs.get('balance', 0))
        self.rate = utils.make_decimal(kwargs.get('rate', 0))
        self.credit = kwargs.get('credit', 0)
        self.last_bill = utils.make_decimal(kwargs.get('last_bill', 0))

        self.status = kwargs.get('status', self.INIT)
        self.status_reason = kwargs.get('status_reason', 'Init user')

        self.created_at = kwargs.get('created_at')
        self.updated_at = kwargs.get('updated_at')
        self.deleted_at = kwargs.get('deleted_at')

        if self.name is None:
            self.name = self._retrieve_name(self.id)
Example #7
0
 def _settle_account(self, context, timestamp=None):
     if self.rate == 0:
         LOG.info(_LI("Ignore settlement action because user is in '%s' "
                      "status."), self.status)
         return
     now = timestamp or utils.make_decimal(wallclock())
     usage_seconds = now - self.last_bill
     cost = self.rate * usage_seconds
     self.balance -= cost
     self.last_bill = now
Example #8
0
    def __init__(self, target, action, context, **kwargs):
        # context will be persisted into database so that any worker thread
        # can pick the action up and execute it on behalf of the initiator

        self.id = kwargs.get('id', None)
        self.name = kwargs.get('name', '')

        self.context = context

        self.action = action
        self.target = target

        # Why this action is fired, it can be a UUID of another action
        self.cause = kwargs.get('cause', '')

        # Owner can be an UUID format ID for the worker that is currently
        # working on the action.  It also serves as a lock.
        self.owner = kwargs.get('owner', None)

        self.start_time = utils.make_decimal(kwargs.get('start_time', 0))
        self.end_time = utils.make_decimal(kwargs.get('end_time', 0))

        # Timeout is a placeholder in case some actions may linger too long
        self.timeout = kwargs.get('timeout', cfg.CONF.default_action_timeout)

        # Return code, useful when action is not automatically deleted
        # after execution
        self.status = kwargs.get('status', self.INIT)
        self.status_reason = kwargs.get('status_reason', '')

        # All parameters are passed in using keyword arguments which is
        # a dictionary stored as JSON in DB
        self.inputs = kwargs.get('inputs', {})
        self.outputs = kwargs.get('outputs', {})

        self.created_at = kwargs.get('created_at', None)
        self.updated_at = kwargs.get('updated_at', None)

        self.data = kwargs.get('data', {})
Example #9
0
    def execute(self, context, resource, **kwargs):
        user = user_mod.User.load(context, user_id=resource.user_id)
        pid = user.policy_id
        try:
            if pid:
                policy = policy_mod.Policy.load(context, policy_id=pid)
            else:
                policy = policy_mod.Policy.load_default(context)
        except exception.PolicyNotFound as e:
            LOG.error(_LE("Error when find policy: %s"), e)
        if policy is not None:
            rule = policy.find_rule(context, resource.resource_type)

            # Update resource with rule_id and rate
            resource.rule_id = rule.id
            resource.rate = utils.make_decimal(rule.get_price(resource))
        resource.store(context)
Example #10
0
    def load(cls, context, user_id=None, user=None, realtime=False,
             show_deleted=False, project_safe=True):
        '''Retrieve a user from database.'''
        if context.is_admin:
            project_safe = False
        if user is None:
            user = db_api.user_get(context, user_id,
                                   show_deleted=show_deleted,
                                   project_safe=project_safe)
            if user is None:
                raise exception.UserNotFound(user=user_id)

        u = cls._from_db_record(user)
        if not realtime:
            return u
        if u.rate > 0 and u.status != u.FREEZE:
            seconds = utils.make_decimal(wallclock()) - u.last_bill
            u.balance -= u.rate * seconds
        return u
Example #11
0
    def consumption_statistics(self, cnxt, user_id=None, filters=None,
                               start_time=None, end_time=None, summary=False,
                               project_safe=True):
        user_id = user_id or cnxt.project
        result = {}
        if start_time is None:
            start_time = 0
        else:
            start_time = utils.format_time_to_seconds(start_time)
            start_time = utils.make_decimal(start_time)

        now_time = utils.format_time_to_seconds(timeutils.utcnow())
        now_time = utils.make_decimal(now_time)
        if end_time is None:
            end_time = now_time
        else:
            end_time = utils.format_time_to_seconds(end_time)
            end_time = utils.make_decimal(end_time)

        consumptions = cons_mod.Consumption.load_all(cnxt, user_id=user_id,
                                                     filters=filters,
                                                     project_safe=project_safe)
        for cons in consumptions:
            if cons.start_time > end_time or cons.end_time < start_time:
                continue
            et = min(cons.end_time, end_time)
            st = max(cons.start_time, start_time)
            seconds = et - st
            cost = cons.rate * seconds
            if summary:
                if cons.resource_type not in result:
                    result[cons.resource_type] = cost
                else:
                    result[cons.resource_type] += cost
            else:
                if cons.resource_id not in result:
                    tmp = {'resource_type': cons.resource_type,
                           'cost': cost}
                    result[cons.resource_id] = tmp
                else:
                    result[cons.resource_id]['cost'] += cost

        resources = plugin_base.Resource.load_all(cnxt, user_id=user_id,
                                                  filters=filters,
                                                  project_safe=project_safe)
        for res in resources:
            if res.last_bill > end_time or now_time < start_time:
                continue
            et = min(now_time, end_time)
            st = max(res.last_bill, start_time)
            seconds = et - st
            cost = res.rate * seconds
            if summary:
                if res.resource_type not in result:
                    result[res.resource_type] = cost
                else:
                    result[res.resource_type] += cost
            else:
                if res.id not in result:
                    tmp = {'resource_type': res.resource_type,
                           'cost': cost}
                    result[res.id] = tmp
                else:
                    result[res.id]['cost'] += cost

        if summary:
            for key in six.iterkeys(result):
                result[key] = utils.dec2str(result[key])
            return result
        else:
            consumptions = []
            for key in six.iterkeys(result):
                consumption = cons_mod.Consumption(
                    user_id,
                    resource_id=key,
                    resource_type=result[key]['resource_type'],
                    cost=result[key]['cost'],
                    start_time=start_time,
                    end_time=end_time)
                consumptions.append(consumption.to_dict())
            return consumptions