Esempio n. 1
0
 def create_bill(self, order_id, action_time=None, remarks=None,
                 end_time=None):
     if isinstance(action_time, basestring):
         action_time = timeutils.parse_strtime(action_time,
                                               fmt=TIMESTAMP_TIME_FORMAT)
     if isinstance(end_time, basestring):
         end_time = timeutils.parse_strtime(end_time,
                                            fmt=TIMESTAMP_TIME_FORMAT)
     _body = dict(order_id=order_id,
                  action_time=action_time,
                  remarks=remarks,
                  end_time=end_time)
     resp, body = self.client.post('/bills', body=_body)
     return body
Esempio n. 2
0
    def load_monthly_cron_jobs(self):
        """Load monthly cron jobs

        Because owed monthly resource will not cron again, so there is no
        need to load owed monthly resources
        """
        # owed="" will be tranlated to owed=False by wsme
        orders = self._get_cron_orders(bill_methods=['month', 'year'],
                                       owed="")
        for order in orders:
            if not order['cron_time']:
                continue
            elif isinstance(order['cron_time'], basestring):
                cron_time = timeutils.parse_strtime(
                    order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
            else:
                cron_time = order['cron_time']

            # Because if not specify run_date for date_time job or the
            # specified run_date is less than the current time, the date
            # time job will use the current time, so there is no need to
            # distinguish the danger_time
            self._create_monthly_job(order['order_id'],
                                     run_date=cron_time)
            self.locks[order['order_id']] = gthreading.Lock()
Esempio n. 3
0
    def instance_stopped(self, ctxt, order_id, action_time):
        """Instance stopped for a month continuously will not be charged

        """
        with self._get_lock(order_id):
            LOG.debug("Instance stopped, its order_id: %s, action_time: %s",
                      order_id, action_time)

            # close the old bill
            self._close_bill(ctxt, order_id, action_time)

            # Caculate cron_time after 30 days from now
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=TIMESTAMP_TIME_FORMAT)
            cron_time = action_time + datetime.timedelta(days=30)

            # change the order's unit price and its active subscriptions
            self.gclient.change_order(order_id,
                                      const.STATE_STOPPED_IN_30_DAYS,
                                      cron_time=cron_time,
                                      first_change_to=const.STATE_STOPPED)

            # create a bill cross 30 days
            self.gclient.create_bill(order_id,
                                     action_time=action_time,
                                     remarks="Instance Has Been Stopped",
                                     end_time=cron_time)

            # create a cron job that will execute after 30 days
            self._create_cron_job(order_id, start_date=cron_time)
Esempio n. 4
0
    def instance_stopped(self, ctxt, order_id, action_time):
        """Instance stopped for a month continuously will not be charged

        """
        with self._get_lock(order_id):
            LOG.debug("Instance stopped, its order_id: %s, action_time: %s",
                      order_id, action_time)

            # close the old bill
            self._close_bill(ctxt, order_id, action_time)

            # Caculate cron_time after 30 days from now
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=TIMESTAMP_TIME_FORMAT)
            cron_time = action_time + datetime.timedelta(days=30)

            # change the order's unit price and its active subscriptions
            self.gclient.change_order(order_id,
                                      const.STATE_STOPPED_IN_30_DAYS,
                                      cron_time=cron_time,
                                      first_change_to=const.STATE_STOPPED)

            # create a bill cross 30 days
            self.gclient.create_bill(order_id,
                                     action_time=action_time,
                                     remarks="Instance Has Been Stopped",
                                     end_time=cron_time)

            # create a cron job that will execute after 30 days
            self._create_cron_job(order_id, start_date=cron_time)
Esempio n. 5
0
    def load_date_jobs(self):
        states = [
            const.STATE_RUNNING, const.STATE_STOPPED, const.STATE_SUSPEND
        ]
        for s in states:
            LOG.debug('Loading date jobs in %s state', s)

            orders = self.gclient.get_orders(status=s,
                                             owed=True,
                                             region_id=cfg.CONF.region_name)

            for order in orders:
                # load delete resource date job
                if isinstance(order['date_time'], basestring):
                    date_time = timeutils.parse_strtime(
                        order['date_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                else:
                    date_time = order['date_time']

                danger_time = (datetime.datetime.utcnow() +
                               datetime.timedelta(seconds=30))
                if date_time > danger_time:
                    self._create_date_job(order['order_id'], order['type'],
                                          order['resource_id'],
                                          order['region_id'],
                                          order['date_time'])
                else:
                    LOG.warning(
                        'The resource(%s) is in danger time after '
                        'master started', order['resource_id'])
                    self._delete_owed_resource(order['type'],
                                               order['resource_id'],
                                               order['region_id'])

        LOG.warning('Load date jobs successfully.')
Esempio n. 6
0
    def load_hourly_cron_jobs(self):
        orders = self._get_cron_orders(bill_methods=['hour'],
                                       region_id=cfg.CONF.region_name)
        for order in orders:
            if not order['cron_time']:
                continue
            elif isinstance(order['cron_time'], basestring):
                cron_time = timeutils.parse_strtime(
                    order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
            else:
                cron_time = order['cron_time']

            # create cron job
            danger_time = (datetime.datetime.utcnow() +
                           datetime.timedelta(seconds=30))
            if cron_time > danger_time:
                self._create_cron_job(order['order_id'],
                                      start_date=cron_time)
            else:
                LOG.warning("The order(%s) is in danger time after master "
                            "started", order['order_id'])
                while cron_time <= danger_time:
                    cron_time += datetime.timedelta(hours=1)
                cron_time -= datetime.timedelta(hours=1)
                action_time = utils.format_datetime(
                    timeutils.strtime(cron_time))
                self._create_bill(self.ctxt,
                                  order['order_id'],
                                  action_time,
                                  "System Adjust")
            self.locks[order['order_id']] = gthreading.Lock()
Esempio n. 7
0
    def load_hourly_cron_jobs(self):
        orders = self._get_cron_orders(bill_methods=['hour'],
                                       region_id=cfg.CONF.region_name)
        for order in orders:
            if not order['cron_time']:
                continue
            elif isinstance(order['cron_time'], basestring):
                cron_time = timeutils.parse_strtime(
                    order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
            else:
                cron_time = order['cron_time']

            # create cron job
            danger_time = (datetime.datetime.utcnow() +
                           datetime.timedelta(seconds=30))
            if cron_time > danger_time:
                self._create_cron_job(order['order_id'], start_date=cron_time)
            else:
                LOG.warning(
                    "The order(%s) is in danger time after master "
                    "started", order['order_id'])
                while cron_time <= danger_time:
                    cron_time += datetime.timedelta(hours=1)
                cron_time -= datetime.timedelta(hours=1)
                action_time = utils.format_datetime(
                    timeutils.strtime(cron_time))
                self._create_bill(self.ctxt, order['order_id'], action_time,
                                  "System Adjust")
            self.locks[order['order_id']] = gthreading.Lock()
Esempio n. 8
0
    def load_date_jobs(self):
        states = [const.STATE_RUNNING, const.STATE_STOPPED,
                  const.STATE_SUSPEND]
        for s in states:
            LOG.debug('Loading date jobs in %s state', s)

            orders = self.gclient.get_orders(status=s, owed=True,
                                             region_id=cfg.CONF.region_name)

            for order in orders:
                # load delete resource date job
                if isinstance(order['date_time'], basestring):
                    date_time = timeutils.parse_strtime(
                        order['date_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                else:
                    date_time = order['date_time']

                danger_time = (datetime.datetime.utcnow() +
                               datetime.timedelta(seconds=30))
                if date_time > danger_time:
                    self._create_date_job(order['order_id'],
                                          order['type'],
                                          order['resource_id'],
                                          order['region_id'],
                                          order['date_time'])
                else:
                    LOG.warning('The resource(%s) is in danger time after '
                                'master started', order['resource_id'])
                    self._delete_owed_resource(order['type'],
                                               order['resource_id'],
                                               order['region_id'])

        LOG.warning('Load date jobs successfully.')
Esempio n. 9
0
 def close_bill(self, order_id, action_time):
     if isinstance(action_time, basestring):
         action_time = timeutils.parse_strtime(action_time,
                                               fmt=TIMESTAMP_TIME_FORMAT)
     _body = dict(order_id=order_id, action_time=action_time)
     resp, body = self.client.put('/bills/close', body=_body)
     return body
Esempio n. 10
0
    def load_30_days_date_jobs(self):
        # load change unit price date job
        orders = self.gclient.get_orders(status=const.STATE_STOPPED,
                                         region_id=cfg.CONF.region_name,
                                         bill_methods=['hour'],
                                         type=const.RESOURCE_INSTANCE)
        for order in orders:
            if not order['cron_time']:
                LOG.warn('There is no cron_time for the stopped order: %s',
                         order)
                continue
            if isinstance(order['cron_time'], basestring):
                cron_time = timeutils.parse_strtime(
                    order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
            else:
                cron_time = order['cron_time']

            danger_time = (datetime.datetime.utcnow() +
                           datetime.timedelta(seconds=30))
            cron_time = cron_time - datetime.timedelta(hours=1)
            if cron_time > danger_time:
                self._create_date_job_after_30_days(order['order_id'],
                                                    cron_time)
            else:
                LOG.warning("The order(%s) is in danger time after master "
                            "started", order['order_id'])
                self._change_order_unit_price(order['order_id'])
        LOG.warning('Load 30-days date jobs successfully.')
Esempio n. 11
0
    def _check_if_owed_resources_match_owed_orders(self,
                                                   should_stop_resources,
                                                   should_delete_resources,
                                                   projects):
        for project in projects:
            orders = list(self.gclient.get_active_orders(
                region_id=self.region_name,
                project_id=project['project_id'],
                owed=True))
            if not orders:
                continue
            for order in orders:
                if isinstance(order['date_time'], basestring):
                    order['date_time'] = timeutils.parse_strtime(
                        order['date_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)
                if isinstance(order['cron_time'], basestring):
                    order['cron_time'] = timeutils.parse_strtime(
                        order['cron_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)

                resource = self.RESOURCE_GET_MAP[order['type']](
                    order['resource_id'],
                    region_name=self.region_name)

                if not resource:
                    LOG.warn('The resource of the order(%s) not exists',
                             order)
                    continue

                now = datetime.datetime.utcnow()
                if order['date_time'] < now:
                    should_delete_resources.append(resource)
                elif order['unit'] in ['month', 'year']:
                    continue
                elif (order['type'] == const.RESOURCE_FLOATINGIP and
                        not resource.is_reserved and order['owed']):
                    should_delete_resources.append(resource)
                elif (resource.resource_type == const.RESOURCE_LISTENER and
                        not resource.is_last_up and
                        resource.admin_state !=
                        self.RESOURCE_STOPPED_STATE[order['type']]):
                    should_stop_resources.append(resource)
                elif (resource.resource_type != const.RESOURCE_LISTENER and
                        resource.status !=
                        self.RESOURCE_STOPPED_STATE[order['type']]):
                    should_stop_resources.append(resource)
Esempio n. 12
0
    def _check_if_owed_resources_match_owed_orders(self,
                                                   should_stop_resources,
                                                   should_delete_resources,
                                                   projects):
        for project in projects:
            orders = list(self.gclient.get_active_orders(
                region_id=self.region_name,
                project_id=project['project_id'],
                owed=True))
            if not orders:
                continue
            for order in orders:
                if isinstance(order['date_time'], basestring):
                    order['date_time'] = timeutils.parse_strtime(
                        order['date_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)
                if isinstance(order['cron_time'], basestring):
                    order['cron_time'] = timeutils.parse_strtime(
                        order['cron_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)

                resource = self.RESOURCE_GET_MAP[order['type']](
                    order['resource_id'],
                    region_name=self.region_name)

                if not resource:
                    LOG.warn('The resource of the order(%s) not exists',
                             order)
                    continue

                now = datetime.datetime.utcnow()
                if order['date_time'] < now:
                    should_delete_resources.append(resource)
                elif order['unit'] in ['month', 'year']:
                    continue
                elif (order['type'] == const.RESOURCE_FLOATINGIP and
                        not resource.is_reserved and order['owed']):
                    should_delete_resources.append(resource)
                elif (resource.resource_type == const.RESOURCE_LISTENER and
                        not resource.is_last_up and
                        resource.admin_state !=
                        self.RESOURCE_STOPPED_STATE[order['type']]):
                    should_stop_resources.append(resource)
                elif (resource.resource_type != const.RESOURCE_LISTENER and
                        resource.status !=
                        self.RESOURCE_STOPPED_STATE[order['type']]):
                    should_stop_resources.append(resource)
Esempio n. 13
0
 def create_bill(self,
                 order_id,
                 action_time=None,
                 remarks=None,
                 end_time=None):
     if isinstance(action_time, basestring):
         action_time = timeutils.parse_strtime(action_time,
                                               fmt=TIMESTAMP_TIME_FORMAT)
     if isinstance(end_time, basestring):
         end_time = timeutils.parse_strtime(end_time,
                                            fmt=TIMESTAMP_TIME_FORMAT)
     _body = dict(order_id=order_id,
                  action_time=action_time,
                  remarks=remarks,
                  end_time=end_time)
     resp, body = self.client.post('/bills', body=_body)
     return body
Esempio n. 14
0
 def close_bill(self, order_id, action_time):
     if isinstance(action_time, basestring):
         action_time = timeutils.parse_strtime(action_time,
                                               fmt=TIMESTAMP_TIME_FORMAT)
     _body = dict(order_id=order_id,
                  action_time=action_time)
     resp, body = self.client.put('/bills/close', body=_body)
     return body
Esempio n. 15
0
    def _handle_monthly_order(self, order_id):
        LOG.warn("Handle monthly billing order: %s", order_id)
        try:
            with self._get_lock(order_id):
                # check resource and order before deduct
                order = self.gclient.get_order(order_id)

                # do not deduct doctor project for now
                if order['project_id'] in cfg.CONF.ignore_tenants:
                    return

                method = self.RESOURCE_GET_MAP[order['type']]
                resource = method(order['resource_id'], order['region_id'])
                if not resource:
                    LOG.warn("The resource(%s|%s) has been deleted",
                             order['type'], order['resource_id'])
                    return

                if order['renew_period'] > 1:
                    remarks = "Renew for %s %ss" % \
                            (order['renew_period'], order['renew_method'])
                else:
                    remarks = "Renew for %s %s" % \
                            (order['renew_period'], order['renew_method'])

                # deduct the order.
                result = self.gclient.create_bill(order_id,
                                                  remarks=remarks)

                # if deduct successfully, create another monthly job.
                if result['type'] == const.BILL_NORMAL:
                    if isinstance(order['cron_time'], basestring):
                        cron_time = timeutils.parse_strtime(
                            order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                    else:
                        cron_time = order['cron_time']

                    months = utils.to_months(order['renew_method'],
                                             order['renew_period'])
                    next_cron_time = utils.add_months(cron_time, months)
                    self._create_monthly_job(order_id, next_cron_time)

                # if deduct failed because of not sufficient balance,
                # or the order's renew is not activated, stop the resource,
                # and create a date job to delete the resoruce.
                elif result['type'] == const.BILL_ORDER_OWED:
                    self._stop_owed_resource(result['resource_type'],
                                             result['resource_id'],
                                             result['region_id'])
                    self._create_date_job(order_id,
                                          result['resource_type'],
                                          result['resource_id'],
                                          result['region_id'],
                                          result['date_time'])
        except Exception as e:
            LOG.exception("Some exceptions happen when deducting order: %s, "
                          "for reason: %s", order_id, e)
Esempio n. 16
0
    def _handle_monthly_order(self, order_id):
        LOG.warn("Handle monthly billing order: %s", order_id)
        try:
            with self._get_lock(order_id):
                # check resource and order before deduct
                order = self.gclient.get_order(order_id)

                # do not deduct doctor project for now
                if order['project_id'] in cfg.CONF.ignore_tenants:
                    return

                method = self.RESOURCE_GET_MAP[order['type']]
                resource = method(order['resource_id'], order['region_id'])
                if not resource:
                    LOG.warn("The resource(%s|%s) has been deleted",
                             order['type'], order['resource_id'])
                    return

                if order['renew_period'] > 1:
                    remarks = "Renew for %s %ss" % \
                            (order['renew_period'], order['renew_method'])
                else:
                    remarks = "Renew for %s %s" % \
                            (order['renew_period'], order['renew_method'])

                # deduct the order.
                result = self.gclient.create_bill(order_id, remarks=remarks)

                # if deduct successfully, create another monthly job.
                if result['type'] == const.BILL_NORMAL:
                    if isinstance(order['cron_time'], basestring):
                        cron_time = timeutils.parse_strtime(
                            order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                    else:
                        cron_time = order['cron_time']

                    months = utils.to_months(order['renew_method'],
                                             order['renew_period'])
                    next_cron_time = utils.add_months(cron_time, months)
                    self._create_monthly_job(order_id, next_cron_time)

                # if deduct failed because of not sufficient balance,
                # or the order's renew is not activated, stop the resource,
                # and create a date job to delete the resoruce.
                elif result['type'] == const.BILL_ORDER_OWED:
                    self._stop_owed_resource(result['resource_type'],
                                             result['resource_id'],
                                             result['region_id'])
                    self._create_date_job(order_id, result['resource_type'],
                                          result['resource_id'],
                                          result['region_id'],
                                          result['date_time'])
        except Exception as e:
            LOG.exception(
                "Some exceptions happen when deducting order: %s, "
                "for reason: %s", order_id, e)
Esempio n. 17
0
    def _pre_deduct(self, order_id):
        LOG.warn("Prededucting order: %s", order_id)
        try:
            with self._get_lock(order_id):
                # check resource and order before deduct
                order = self.gclient.get_order(order_id)

                # do not deduct doctor project for now
                if order['project_id'] in cfg.CONF.ignore_tenants:
                    return

                method = self.RESOURCE_GET_MAP[order['type']]
                resource = method(order['resource_id'], order['region_id'])
                if not resource:
                    LOG.warn("The resource(%s|%s) has been deleted",
                             order['type'], order['resource_id'])
                    return

                if isinstance(order['cron_time'], basestring):
                    cron_time = timeutils.parse_strtime(
                        order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                else:
                    cron_time = order['cron_time']

                remarks = 'Hourly Billing'
                now = timeutils.utcnow()
                if now - cron_time >= datetime.timedelta(hours=1):
                    result = self.gclient.create_bill(order_id,
                                                      action_time=now,
                                                      remarks=remarks)
                else:
                    result = self.gclient.create_bill(order_id,
                                                      remarks=remarks)

                # Order is owed
                if result['type'] == const.BILL_ORDER_OWED:
                    self._stop_owed_resource(result['resource_type'],
                                             result['resource_id'],
                                             result['region_id'])
                    self._create_date_job(order_id,
                                          result['resource_type'],
                                          result['resource_id'],
                                          result['region_id'],
                                          result['date_time'])
                # Account is charged but order is still owed
                elif result['type'] == const.BILL_OWED_ACCOUNT_CHARGED:
                    self._delete_date_job(order_id)
        except Exception as e:
            LOG.warn("Some exceptions happen when deducting order: %s, "
                     "for reason: %s", order_id, e)
Esempio n. 18
0
    def _pre_deduct(self, order_id):
        LOG.warn("Prededucting order: %s", order_id)
        try:
            with self._get_lock(order_id):
                # check resource and order before deduct
                order = self.gclient.get_order(order_id)

                # do not deduct doctor project for now
                if order['project_id'] in cfg.CONF.ignore_tenants:
                    return

                method = self.RESOURCE_GET_MAP[order['type']]
                resource = method(order['resource_id'], order['region_id'])
                if not resource:
                    LOG.warn("The resource(%s|%s) has been deleted",
                             order['type'], order['resource_id'])
                    return

                if isinstance(order['cron_time'], basestring):
                    cron_time = timeutils.parse_strtime(
                        order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
                else:
                    cron_time = order['cron_time']

                remarks = 'Hourly Billing'
                now = timeutils.utcnow()
                if now - cron_time >= datetime.timedelta(hours=1):
                    result = self.gclient.create_bill(order_id,
                                                      action_time=now,
                                                      remarks=remarks)
                else:
                    result = self.gclient.create_bill(order_id,
                                                      remarks=remarks)

                # Order is owed
                if result['type'] == const.BILL_ORDER_OWED:
                    self._stop_owed_resource(result['resource_type'],
                                             result['resource_id'],
                                             result['region_id'])
                    self._create_date_job(order_id, result['resource_type'],
                                          result['resource_id'],
                                          result['region_id'],
                                          result['date_time'])
                # Account is charged but order is still owed
                elif result['type'] == const.BILL_OWED_ACCOUNT_CHARGED:
                    self._delete_date_job(order_id)
        except Exception as e:
            LOG.warn(
                "Some exceptions happen when deducting order: %s, "
                "for reason: %s", order_id, e)
Esempio n. 19
0
    def _create_date_job(self, order_id, resource_type, resource_id, region_id,
                         action_time):
        """Create a date job to delete the owed resource

        This job will be executed once, the job id is resource_id.
        """
        job_id = self._make_date_job_id(order_id)
        if isinstance(action_time, basestring):
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=ISO8601_UTC_TIME_FORMAT)

        self.apsched.add_job(self._delete_owed_resource,
                             'date',
                             args=[resource_type, resource_id, region_id],
                             id=job_id,
                             run_date=action_time,
                             replace_existing=True)
        LOG.warn('create date job for order: %s', order_id)
Esempio n. 20
0
    def _create_cron_job(self, order_id, action_time=None, start_date=None):
        """Create a interval job to deduct the order

        This kind of job will be executed periodically, the job id is order_id
        """
        job_id = self._make_cron_job_id(order_id)
        if action_time:
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=TIMESTAMP_TIME_FORMAT)
            start_date = action_time + datetime.timedelta(hours=1)

        self.apsched.add_job(self._pre_deduct,
                             'interval',
                             args=[order_id],
                             id=job_id,
                             hours=1,
                             start_date=start_date)
        LOG.warn('create cron job for order: %s', order_id)
Esempio n. 21
0
    def _create_cron_job(self, order_id, action_time=None, start_date=None):
        """Create a interval job to deduct the order

        This kind of job will be executed periodically, the job id is order_id
        """
        job_id = self._make_cron_job_id(order_id)
        if action_time:
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=TIMESTAMP_TIME_FORMAT)
            start_date = action_time + datetime.timedelta(hours=1)

        self.apsched.add_job(self._pre_deduct,
                             'interval',
                             args=[order_id],
                             id=job_id,
                             hours=1,
                             start_date=start_date)
        LOG.warn('create cron job for order: %s', order_id)
Esempio n. 22
0
    def get_unit_price(self, order_id, message, status, cron_time=None):
        unit_price = 0

        if isinstance(cron_time, basestring):
            cron_time = timeutils.parse_strtime(cron_time, fmt=ISO8601_UTC_TIME_FORMAT)

        # delta = cron_time - timeutils.utcnow()
        # if status == const.STATE_STOPPED and delta > datetime.timedelta(hours=1):
        #    return 0

        # didn't check the stopped instance for now
        if status == const.STATE_STOPPED:
            return

        for ext in self.product_items.extensions:
            if ext.name.startswith(status):
                unit_price += ext.obj.get_unit_price(order_id, message)

        return unit_price
Esempio n. 23
0
    def get_unit_price(self, order_id, message, status, cron_time=None):
        unit_price = 0

        if isinstance(cron_time, basestring):
            cron_time = timeutils.parse_strtime(cron_time,
                                                fmt=ISO8601_UTC_TIME_FORMAT)

        #delta = cron_time - timeutils.utcnow()
        #if status == const.STATE_STOPPED and delta > datetime.timedelta(hours=1):
        #    return 0

        # didn't check the stopped instance for now
        if status == const.STATE_STOPPED:
            return

        for ext in self.product_items.extensions:
            if ext.name.startswith(status):
                unit_price += ext.obj.get_unit_price(order_id, message)

        return unit_price
Esempio n. 24
0
    def _create_date_job(self, order_id, resource_type, resource_id, region_id,
                         action_time):
        """Create a date job to delete the owed resource

        This job will be executed once, the job id is resource_id.
        """
        job_id = self._make_date_job_id(order_id)
        if isinstance(action_time, basestring):
            action_time = timeutils.parse_strtime(action_time,
                                                  fmt=ISO8601_UTC_TIME_FORMAT)

        self.apsched.add_job(self._delete_owed_resource,
                             'date',
                             args=[resource_type,
                                   resource_id,
                                   region_id],
                             id=job_id,
                             run_date=action_time,
                             replace_existing=True)
        LOG.warn('create date job for order: %s', order_id)
Esempio n. 25
0
    def load_monthly_cron_jobs(self):
        """Load monthly cron jobs

        Because owed monthly resource will not cron again, so there is no
        need to load owed monthly resources
        """
        # owed="" will be tranlated to owed=False by wsme
        orders = self._get_cron_orders(bill_methods=['month', 'year'], owed="")
        for order in orders:
            if not order['cron_time']:
                continue
            elif isinstance(order['cron_time'], basestring):
                cron_time = timeutils.parse_strtime(
                    order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)
            else:
                cron_time = order['cron_time']

            # Because if not specify run_date for date_time job or the
            # specified run_date is less than the current time, the date
            # time job will use the current time, so there is no need to
            # distinguish the danger_time
            self._create_monthly_job(order['order_id'], run_date=cron_time)
            self.locks[order['order_id']] = gthreading.Lock()
Esempio n. 26
0
    def check_owed_hour_resources_and_notify(self):  # noqa
        """Check owed hour-billing resources and notify them

        Get owed accounts, send them sms/email notifications.
        """
        try:
            accounts = self._assigned_accounts()
        except Exception:
            LOG.exception("Fail to get assigned accounts")
            accounts = []
        LOG.warn("[%s] Notifying owed accounts, assigned accounts number: %s",
                 self.member_id, len(accounts))

        bill_methods=['hour',]

        for account in accounts:
            try:
                if not isinstance(account, dict):
                    account = account.as_dict()

                if account['level'] == 9:
                    continue

                if account['owed']:
                    orders = list(
                        self.gclient.get_active_orders(
                            user_id=account['user_id'],
                            owed=True,
                            bill_methods=bill_methods)
                    )
                    if not orders:
                        continue

                    contact = keystone.get_user(account['user_id']).to_dict()
                    _projects = self.gclient.get_projects(
                        user_id=account['user_id'],
                        type='simple')

                    orders_dict = {}
                    for project in _projects:
                        orders_dict[project['project_id']] = []

                    for order in orders:
                        # check if the resource exists
                        resource = self.RESOURCE_GET_MAP[order['type']](
                            order['resource_id'],
                            region_name=order['region_id'])
                        if not resource:
                            # NOTE(chengkun): just warning if the resource not exists
                            LOG.warn("[%s] The resource(%s|%s) has been "
                                     "deleted",
                                     self.member_id,
                                     order['type'], order['resource_id'])
                            continue

                        order_d = {}
                        order_d['order_id'] = order['order_id']
                        order_d['region_id'] = order['region_id']
                        order_d['resource_id'] = order['resource_id']
                        order_d['resource_name'] = order['resource_name']
                        order_d['type'] = order['type']

                        if isinstance(order['date_time'], basestring):
                            order['date_time'] = timeutils.parse_strtime(
                                order['date_time'],
                                fmt=ISO8601_UTC_TIME_FORMAT)

                        now = datetime.datetime.utcnow()
                        reserved_days = (order['date_time'] - now).days
                        if reserved_days < 0:
                            LOG.warn("[%s] The order %s reserved_days is "
                                     "less than 0",
                                     self.member_id, order['order_id'])
                            reserved_days = 0
                        order_d['reserved_days'] = reserved_days

                        order_d['date_time'] = timeutils.strtime(
                            order['date_time'],
                            fmt=ISO8601_UTC_TIME_FORMAT)

                        orders_dict[order['project_id']].append(order_d)

                    projects = []
                    for project in _projects:
                        if orders_dict[project['project_id']]:
                            adict = {}
                            adict['project_id'] = project['project_id']
                            adict['project_name'] = project['project_name']
                            adict['orders'] = (orders_dict[
                                               project['project_id']])
                            projects.append(adict)

                    if not projects:
                        continue

                    reserved_days = utils.cal_reserved_days(account['level'])
                    account['reserved_days'] = reserved_days
                    country_code = contact.get("country_code") or "86"
                    language = "en_US" if country_code != '86' else "zh_CN"
                    self.notifier.notify_has_owed(self.ctxt, account, contact,
                                                  projects, language=language)
                else:
                    orders = self.gclient.get_active_orders(
                        user_id=account['user_id'],
                        bill_methods=bill_methods)
                    if not orders:
                        continue

                    _projects = self.gclient.get_projects(
                        user_id=account['user_id'], type='simple')

                    estimation = {}
                    for project in _projects:
                        estimation[project['project_id']] = 0

                    price_per_hour = 0
                    for order in orders:
                        # check if the resource exists
                        resource = self.RESOURCE_GET_MAP[order['type']](
                            order['resource_id'],
                            region_name=order['region_id'])
                        if not resource:
                            # just warning the resource not exists
                            LOG.warn("[%s] The resource(%s|%s) may has been "
                                     "deleted",
                                     self.member_id, order['type'],
                                     order['resource_id'])
                            continue

                        price_per_hour += utils._quantize_decimal(
                            order['unit_price'])
                        estimation[order['project_id']] += \
                            utils._quantize_decimal(order['unit_price'])

                    price_per_day = price_per_hour * 24
                    account_balance = utils._quantize_decimal(
                        account['balance'])

                    if price_per_day == 0:
                        continue

                    days_to_owe_d = float(account_balance / price_per_day)
                    days_to_owe = round(days_to_owe_d)

                    if days_to_owe > cfg.CONF.checker.days_to_owe:
                        continue

                    # caculate projects
                    projects = []
                    for project in _projects:
                        adict = {}
                        adict['project_id'] = project['project_id']
                        adict['project_name'] = project['project_name']
                        adict['estimation'] = str(
                            estimation[project['project_id']] * 24)
                        projects.append(adict)

                    if not projects:
                        continue

                    contact = keystone.get_uos_user(account['user_id'])
                    country_code = contact.get("country_code") or "86"
                    language = "en_US" if country_code != '86' else "zh_CN"
                    self.notifier.notify_before_owed(self.ctxt, account,
                                                     contact, projects,
                                                     str(price_per_day),
                                                     days_to_owe,
                                                     language=language)
            except Exception:
                LOG.exception("Some exceptions occurred when checking owed "
                              "account: %s", account['user_id'])
Esempio n. 27
0
    def check_owed_order_resources_and_notify(self):  #noqa
        """Check order-billing resources and notify related accounts

        Send sms/email notifications for each has-owed or will-owed order.
        """
        try:
            accounts = self._assigned_accounts()
        except Exception:
            LOG.exception("Fail to get assigned accounts")
            accounts = []
        LOG.warn("[%s] Notifying owed accounts, assigned accounts number: %s",
                 self.member_id, len(accounts))

        bill_methods = ['month', 'year']

        for account in accounts:
            try:
                if not isinstance(account, dict):
                    account = account.as_dict()

                if account['level'] == 9:
                    continue

                contact = keystone.get_uos_user(account['user_id'])
                country_code = contact.get("country_code") or "86"
                language = "en_US" if country_code != '86' else "zh_CN"
                account['reserved_days'] = utils.cal_reserved_days(account['level'])

                orders = list(
                    self.gclient.get_active_orders(
                        user_id=account['user_id'],
                        bill_methods=bill_methods)
                )

                for order in orders:
                    # check if the resource exists
                    resource = self.RESOURCE_GET_MAP[order['type']](
                        order['resource_id'],
                        region_name=order['region_id'])
                    if not resource:
                        # warning that the resource not exists
                        LOG.warn("[%s] The resource(%s|%s) has been "
                                 "deleted",
                                 self.member_id,
                                 order['type'], order['resource_id'])
                        continue

                    order_d = {}
                    order_d['order_id'] = order['order_id']
                    order_d['region_id'] = order['region_id']
                    order_d['resource_id'] = order['resource_id']
                    order_d['resource_name'] = order['resource_name']
                    order_d['type'] = order['type']
                    order_d['owed'] = order['owed']

                    if isinstance(order['date_time'], basestring):
                        order['date_time'] = timeutils.parse_strtime(
                            order['date_time'],
                            fmt=ISO8601_UTC_TIME_FORMAT)

                    if isinstance(order['cron_time'], basestring):
                        order['cron_time'] = timeutils.parse_strtime(
                            order['cron_time'],
                            fmt=ISO8601_UTC_TIME_FORMAT)

                    # if order is owed, reserved_days represent how long resource will be reserved;
                    # if not, reserved_days repesent how long resource will be expired
                    now = datetime.datetime.utcnow()
                    if order['owed']:
                        reserved_days = (order['date_time'] - now).days
                    else:
                        reserved_days = (order['cron_time'] - now).days
                    if reserved_days < 0:
                        LOG.warn("[%s] The order %s reserved_days is "
                                 "less than 0",
                                 self.member_id, order['order_id'])
                        reserved_days = 0
                    order_d['reserved_days'] = reserved_days

                    order_d['date_time'] = timeutils.strtime(
                        order['date_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)

                    order_d['cron_time'] = timeutils.strtime(
                        order['cron_time'],
                        fmt=ISO8601_UTC_TIME_FORMAT)

                    is_notify_will_owed = (order_d['reserved_days'] <= cfg.CONF.checker.days_to_owe)
                    if order_d['owed'] or (not order_d['owed'] and is_notify_will_owed):
                        self.notifier.notify_order_billing_owed(self.ctxt, account, contact,
                                                                order_d, language=language)

            except Exception:
                LOG.exception("Some exceptions occurred when checking owed "
                              "account: %s", account['user_id'])
Esempio n. 28
0
    def check_owed_hour_resources_and_notify(self):  # noqa
        """Check owed hour-billing resources and notify them

        Get owed accounts, send them sms/email notifications.
        """
        try:
            accounts = self._assigned_accounts()
        except Exception:
            LOG.exception("Fail to get assigned accounts")
            accounts = []
        LOG.warn("[%s] Notifying owed accounts, assigned accounts number: %s",
                 self.member_id, len(accounts))

        bill_methods = [
            'hour',
        ]

        for account in accounts:
            try:
                if not isinstance(account, dict):
                    account = account.as_dict()

                if account['level'] == 9:
                    continue

                if account['owed']:
                    orders = list(
                        self.gclient.get_active_orders(
                            user_id=account['user_id'],
                            owed=True,
                            bill_methods=bill_methods))
                    if not orders:
                        continue

                    contact = keystone.get_user(account['user_id']).to_dict()
                    _projects = self.gclient.get_projects(
                        user_id=account['user_id'], type='simple')

                    orders_dict = {}
                    for project in _projects:
                        orders_dict[project['project_id']] = []

                    for order in orders:
                        # check if the resource exists
                        resource = self.RESOURCE_GET_MAP[order['type']](
                            order['resource_id'],
                            region_name=order['region_id'])
                        if not resource:
                            # NOTE(chengkun): just warning if the resource not exists
                            LOG.warn(
                                "[%s] The resource(%s|%s) has been "
                                "deleted", self.member_id, order['type'],
                                order['resource_id'])
                            continue

                        order_d = {}
                        order_d['order_id'] = order['order_id']
                        order_d['region_id'] = order['region_id']
                        order_d['resource_id'] = order['resource_id']
                        order_d['resource_name'] = order['resource_name']
                        order_d['type'] = order['type']

                        if isinstance(order['date_time'], basestring):
                            order['date_time'] = timeutils.parse_strtime(
                                order['date_time'],
                                fmt=ISO8601_UTC_TIME_FORMAT)

                        now = datetime.datetime.utcnow()
                        reserved_days = (order['date_time'] - now).days
                        if reserved_days < 0:
                            LOG.warn(
                                "[%s] The order %s reserved_days is "
                                "less than 0", self.member_id,
                                order['order_id'])
                            reserved_days = 0
                        order_d['reserved_days'] = reserved_days

                        order_d['date_time'] = timeutils.strtime(
                            order['date_time'], fmt=ISO8601_UTC_TIME_FORMAT)

                        orders_dict[order['project_id']].append(order_d)

                    projects = []
                    for project in _projects:
                        if orders_dict[project['project_id']]:
                            adict = {}
                            adict['project_id'] = project['project_id']
                            adict['project_name'] = project['project_name']
                            adict['orders'] = (
                                orders_dict[project['project_id']])
                            projects.append(adict)

                    if not projects:
                        continue

                    reserved_days = utils.cal_reserved_days(account['level'])
                    account['reserved_days'] = reserved_days
                    country_code = contact.get("country_code") or "86"
                    language = "en_US" if country_code != '86' else "zh_CN"
                    self.notifier.notify_has_owed(self.ctxt,
                                                  account,
                                                  contact,
                                                  projects,
                                                  language=language)
                else:
                    orders = self.gclient.get_active_orders(
                        user_id=account['user_id'], bill_methods=bill_methods)
                    if not orders:
                        continue

                    _projects = self.gclient.get_projects(
                        user_id=account['user_id'], type='simple')

                    estimation = {}
                    for project in _projects:
                        estimation[project['project_id']] = 0

                    price_per_hour = 0
                    for order in orders:
                        # check if the resource exists
                        resource = self.RESOURCE_GET_MAP[order['type']](
                            order['resource_id'],
                            region_name=order['region_id'])
                        if not resource:
                            # just warning the resource not exists
                            LOG.warn(
                                "[%s] The resource(%s|%s) may has been "
                                "deleted", self.member_id, order['type'],
                                order['resource_id'])
                            continue

                        price_per_hour += utils._quantize_decimal(
                            order['unit_price'])
                        estimation[order['project_id']] += \
                            utils._quantize_decimal(order['unit_price'])

                    price_per_day = price_per_hour * 24
                    account_balance = utils._quantize_decimal(
                        account['balance'])

                    if price_per_day == 0:
                        continue

                    days_to_owe_d = float(account_balance / price_per_day)
                    days_to_owe = round(days_to_owe_d)

                    if days_to_owe > cfg.CONF.checker.days_to_owe:
                        continue

                    # caculate projects
                    projects = []
                    for project in _projects:
                        adict = {}
                        adict['project_id'] = project['project_id']
                        adict['project_name'] = project['project_name']
                        adict['estimation'] = str(
                            estimation[project['project_id']] * 24)
                        projects.append(adict)

                    if not projects:
                        continue

                    contact = keystone.get_uos_user(account['user_id'])
                    country_code = contact.get("country_code") or "86"
                    language = "en_US" if country_code != '86' else "zh_CN"
                    self.notifier.notify_before_owed(self.ctxt,
                                                     account,
                                                     contact,
                                                     projects,
                                                     str(price_per_day),
                                                     days_to_owe,
                                                     language=language)
            except Exception:
                LOG.exception(
                    "Some exceptions occurred when checking owed "
                    "account: %s", account['user_id'])
Esempio n. 29
0
    def check_owed_order_resources_and_notify(self):  #noqa
        """Check order-billing resources and notify related accounts

        Send sms/email notifications for each has-owed or will-owed order.
        """
        try:
            accounts = self._assigned_accounts()
        except Exception:
            LOG.exception("Fail to get assigned accounts")
            accounts = []
        LOG.warn("[%s] Notifying owed accounts, assigned accounts number: %s",
                 self.member_id, len(accounts))

        bill_methods = ['month', 'year']

        for account in accounts:
            try:
                if not isinstance(account, dict):
                    account = account.as_dict()

                if account['level'] == 9:
                    continue

                contact = keystone.get_uos_user(account['user_id'])
                country_code = contact.get("country_code") or "86"
                language = "en_US" if country_code != '86' else "zh_CN"
                account['reserved_days'] = utils.cal_reserved_days(
                    account['level'])

                orders = list(
                    self.gclient.get_active_orders(user_id=account['user_id'],
                                                   bill_methods=bill_methods))

                for order in orders:
                    # check if the resource exists
                    resource = self.RESOURCE_GET_MAP[order['type']](
                        order['resource_id'], region_name=order['region_id'])
                    if not resource:
                        # warning that the resource not exists
                        LOG.warn(
                            "[%s] The resource(%s|%s) has been "
                            "deleted", self.member_id, order['type'],
                            order['resource_id'])
                        continue

                    order_d = {}
                    order_d['order_id'] = order['order_id']
                    order_d['region_id'] = order['region_id']
                    order_d['resource_id'] = order['resource_id']
                    order_d['resource_name'] = order['resource_name']
                    order_d['type'] = order['type']
                    order_d['owed'] = order['owed']

                    if isinstance(order['date_time'], basestring):
                        order['date_time'] = timeutils.parse_strtime(
                            order['date_time'], fmt=ISO8601_UTC_TIME_FORMAT)

                    if isinstance(order['cron_time'], basestring):
                        order['cron_time'] = timeutils.parse_strtime(
                            order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)

                    # if order is owed, reserved_days represent how long resource will be reserved;
                    # if not, reserved_days repesent how long resource will be expired
                    now = datetime.datetime.utcnow()
                    if order['owed']:
                        reserved_days = (order['date_time'] - now).days
                    else:
                        reserved_days = (order['cron_time'] - now).days
                    if reserved_days < 0:
                        LOG.warn(
                            "[%s] The order %s reserved_days is "
                            "less than 0", self.member_id, order['order_id'])
                        reserved_days = 0
                    order_d['reserved_days'] = reserved_days

                    order_d['date_time'] = timeutils.strtime(
                        order['date_time'], fmt=ISO8601_UTC_TIME_FORMAT)

                    order_d['cron_time'] = timeutils.strtime(
                        order['cron_time'], fmt=ISO8601_UTC_TIME_FORMAT)

                    is_notify_will_owed = (order_d['reserved_days'] <=
                                           cfg.CONF.checker.days_to_owe)
                    if order_d['owed'] or (not order_d['owed']
                                           and is_notify_will_owed):
                        self.notifier.notify_order_billing_owed(
                            self.ctxt,
                            account,
                            contact,
                            order_d,
                            language=language)

            except Exception:
                LOG.exception(
                    "Some exceptions occurred when checking owed "
                    "account: %s", account['user_id'])