예제 #1
0
    def estimate(self):
        """Get the price per day and the remaining days."""

        policy.check_policy(HOOK.context,
                            "account:estimate",
                            action="account:estimate")
        _gnocchi_fetcher = fetcher.GnocchiFetcher()

        user_id = self._id
        account = self._account(user_id=user_id)
        price_per_hour = _gnocchi_fetcher.get_current_consume(
            HOOK.context.project_id)

        def _estimate(balance, price_per_hour, remaining_day):
            return models.Estimate(balance=round(balance, 2),
                                   price_per_hour=round(price_per_hour, 2),
                                   remaining_day=remaining_day)

        if price_per_hour == 0:
            if account['balance'] < 0:
                return _estimate(account['balance'], price_per_hour, -2)
            else:
                return _estimate(account['balance'], price_per_hour, -1)
        elif price_per_hour > 0:
            if account['balance'] < 0:
                return _estimate(account['balance'], price_per_hour, -2)
            else:
                price_per_day = price_per_hour * 24
                remaining_day = int(account['balance'] / price_per_day)
        return _estimate(account['balance'], price_per_hour, remaining_day)
예제 #2
0
    def get(self,
            user_id=None,
            type=None,
            start_time=None,
            end_time=None,
            limit=None,
            offset=None,
            sort_key='created_at',
            sort_dir='desc'):
        """Get all charges of all account."""

        policy.check_policy(HOOK.context, "charges:all", action="charges:all")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        users = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = ks_client.get_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email)
            return users[user_id]

        charges = HOOK.conductor_rpcapi.get_charges(HOOK.context,
                                                    user_id=user_id,
                                                    type=type,
                                                    limit=limit,
                                                    offset=offset,
                                                    start_time=start_time,
                                                    end_time=end_time,
                                                    sort_key=sort_key,
                                                    sort_dir=sort_dir)
        charges_list = []
        for charge in charges:
            acharge = models.Charge.from_db_model(charge)
            acharge.target = _get_user(charge['user_id'])
            charges_list.append(acharge)

        total_price, total_count = (
            HOOK.conductor_rpcapi.get_charges_price_and_count(
                HOOK.context,
                user_id=user_id,
                type=type,
                start_time=start_time,
                end_time=end_time))

        return models.Charges.transform(total_price=total_price,
                                        total_count=total_count,
                                        charges=charges_list)
예제 #3
0
 def post(self, data):
     """Create a new project."""
     policy.check_policy(HOOK.context, "project:post")
     try:
         project = data.as_dict()
         return HOOK.conductor_rpcapi.create_project(HOOK.context, project)
     except Exception:
         LOG.exception('Fail to create project: %s' % project)
         raise exception.ProjectCreateFailed(project_id=data.project_id,
                                             user_id=data.user_id)
예제 #4
0
 def delete(self):
     """Delete the account including the projects that belong to it."""
     policy.check_policy(HOOK.context,
                         "account:delete",
                         action="account:delete")
     try:
         HOOK.conductor_rpcapi.delete_account(HOOK.context, self._id)
     except exception.NotFound:
         LOG.Warning('Could not find account whose user_id is %s' %
                     self._id)
     except Exception as e:
         LOG.error('Fail to delete the account: %s' % self._id)
         raise exception.DBError(reason=e)
예제 #5
0
 def post(self, data):
     """Create a new account."""
     policy.check_policy(HOOK.context,
                         "account:post",
                         action="account:post")
     try:
         account = data.as_dict()
         response = HOOK.conductor_rpcapi.create_account(
             HOOK.context, account)
         return response
     except Exception as e:
         LOG.error('Fail to create account: %s' % data.as_dict())
         raise exception.DBError(reason=e)
예제 #6
0
 def summary(self, project_id=None, all_get=False):
     gnocchi_client = fetcher.GnocchiFetcher()
     policy.check_policy(HOOK.context, "order:summary",
                         action="order:summary")
     if not project_id and not all_get:
         project_id = HOOK.headers.get("X-Project-Id")
     if all_get and acl.context_is_admin(HOOK.headers):
         project_id = None
     try:
         result = gnocchi_client.get_summary(
             project_id)
     except Exception as e:
         LOG.error('Exception reason: %s' % e)
         raise
     return result
예제 #7
0
 def bills(self, resource_type, project_id=None,
           limit=None, marker=None, all_get=False):
     gnocchi_client = fetcher.GnocchiFetcher()
     policy.check_policy(HOOK.context, "order:bills",
                         action="order:bills")
     if not project_id and not all_get:
         project_id = HOOK.headers.get("X-Project-Id")
     if all_get and acl.context_is_admin(HOOK.headers):
         project_id = None
     try:
         resources = gnocchi_client.get_bills(
             resource_type, project_id, limit, marker)
     except Exception as e:
         LOG.error('Exception reason: %s' % e)
         raise
     return resources
예제 #8
0
    def level(self, level):
        """Update the account's level."""
        policy.check_policy(HOOK.context,
                            "account:level",
                            action="account:level")

        if not isinstance(level, int) or level < 0 or level > 9:
            raise exception.InvalidParameterValue(err="Invalid Level")
        try:
            account = HOOK.conductor_rpcapi.change_account_level(
                HOOK.context, self._id, level)
        except Exception as e:
            LOG.error('Fail to change the account level of: %s' % self._id)
            raise exception.DBError(reason=e)

        return models.UserAccount(**account)
예제 #9
0
    def charges(self,
                type=None,
                start_time=None,
                end_time=None,
                limit=None,
                offset=None):
        """Get this account's charge records."""
        policy.check_policy(HOOK.context,
                            "charges:get",
                            action="account:charges")

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        user_id = acl.get_limited_to_user(HOOK.headers,
                                          'account:charge') or self._id

        charges = HOOK.conductor_rpcapi.get_charges(HOOK.context,
                                                    user_id=user_id,
                                                    type=type,
                                                    limit=limit,
                                                    offset=offset,
                                                    start_time=start_time,
                                                    end_time=end_time)
        charges_list = []
        for charge in charges:
            charges_list.append(models.Charge(**charge))

        total_price, total_count = (
            HOOK.conductor_rpcapi.get_charges_price_and_count(
                HOOK.context,
                user_id=user_id,
                type=type,
                start_time=start_time,
                end_time=end_time))

        return models.Charges.transform(total_price=total_price,
                                        total_count=total_count,
                                        charges=charges_list)
예제 #10
0
    def put(self, data):
        """Charge the account."""
        policy.check_policy(HOOK.context,
                            "account:charge",
                            action="account:charge")

        # check accountant charge value
        lacv = int(CONF.limited_accountant_charge_value)
        if data.value > lacv:
            raise exception.InvalidChargeValue(value=data.value)
        try:
            charge = HOOK.conductor_rpcapi.charge_account(
                HOOK.context, self._id, **data.as_dict())

        except exception.NotAuthorized as e:
            LOG.error('Fail to charge the account:%s'
                      'due to not authorization' % self._id)
            raise exception.NotAuthorized()
        except Exception as e:
            LOG.error('Fail to charge the account:%s,'
                      'charge value: %s' % (self._id, data.value))
            raise exception.DBError(reason=e)
        return models.Charge.from_db_model(charge)
예제 #11
0
    def get_all(self, owed=None, limit=None, offset=None, duration=None):
        """Get this account."""
        policy.check_policy(HOOK.context, "account:all", action="account:all")
        owed = False

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        duration = timeutils.normalize_timedelta(duration)
        if duration:
            active_from = timeutils.utcnow() - duration
        else:
            active_from = None

        try:
            accounts = HOOK.conductor_rpcapi.get_accounts(
                HOOK.context,
                owed=owed,
                limit=limit,
                offset=offset,
                active_from=active_from)
            count = len(accounts)
        except exception.NotAuthorized as e:
            LOG.error('Failed to get all accounts')
            raise exception.NotAuthorized()
        except Exception as e:
            LOG.error('Failed to get all accounts')
            raise exception.DBError(reason=e)

        accounts = [
            models.AdminAccount.transform(**account) for account in accounts
        ]

        return models.AdminAccounts.transform(total_count=count,
                                              accounts=accounts)
예제 #12
0
    def get(self, output_format='xlsx', user_id=None,
            start_time=None, end_time=None,
            limit=None, offset=None, all_get=False):
        """Export all charges of special user, output formats supported:
           * Excel (Sets + Books)
           * YAML (Sets + Books)
           * HTML (Sets)
           * TSV (Sets)
           * CSV (Sets)
           * JSON (Sets)
        """
        policy.check_policy(HOOK.context, "charges:export",
                            action="charges:export")

        tablib.formats.json.json = json

        if output_format.lower() not in ["xls", "xlsx", "csv", "yaml", "json"]:
            raise exception.InvalidOutputFormat(output_format=output_format)

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        policy.check_policy(HOOK.context, "charges:export",
                            action="charges:export")

        if all_get and acl.context_is_admin(HOOK.headers):
            user_id = None

        headers = (u"充值记录ID", u"充值对象用户名", u"充值对象ID",
                   u"充值对象邮箱", u"充值金额", u"充值类型",
                   u"充值来源", u"充值人员ID",
                   u"充值人员用户名", u"充值时间", u"状态")
        data = []

        users = {}

        def _get_user(user_id):
            if not user_id:
                return models.User(user_id=None,
                                   user_name=None,
                                   email=None)
            user = users.get(user_id)
            if user:
                return user
            contact = ks_client.get_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email)
            return users[user_id]

        charges = HOOK.conductor_rpcapi.get_charges(
            HOOK.context,
            user_id=user_id,
            limit=limit,
            offset=offset,
            start_time=start_time,
            end_time=end_time)
        for charge in charges:
            charge_st = timeutils.str2ts(charge['charge_time']) + (3600 * 8)
            charge['charge_time'] = timeutils.ts2str(charge_st)
            acharge = models.Charge.from_db_model(charge)
            acharge.actor = _get_user(charge['operator'])
            acharge.target = _get_user(charge['user_id'])
            charge_time = charge['charge_time']

            adata = (acharge.charge_id, acharge.target.user_name,
                     acharge.target.user_id, acharge.target.email,
                     str(acharge.value), acharge.type, acharge.come_from,
                     acharge.actor.user_id, acharge.actor.user_name,
                     charge_time, u"正常")
            data.append(adata)

        data = tablib.Dataset(*data, headers=headers)

        response.content_type = "application/binary; charset=UTF-8"
        response.content_disposition = \
            "attachment; filename=charges.%s" % output_format
        # content = getattr(data, output_format)
        content = data.export(output_format)
        response.write(content)
        return response
예제 #13
0
    def get_all(self, output_format='xlsx', type=None, status=None,
                start_time=None, end_time=None, limit=None, marker=None,
                project_id=None, user_id=None, owed=None,
                all_get=False):
        """Get queried orders
        If start_time and end_time is not None, will get orders that have bills
        during start_time and end_time, or return all orders directly.
        """
        policy.check_policy(HOOK.context, "charges:export",
                            action="charges:export")

        tablib.formats.json.json = json
        _gnocchi_fetcher = fetcher.GnocchiFetcher()

        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")

        policy.check_policy(HOOK.context, "charges:export",
                            action="charges:export")

        if all_get and acl.context_is_admin(HOOK.headers):
            user_id = None

        MAP = {"instance": u"虚拟机",
               "volume": u"云硬盘",
               "image": u"镜像",
               "ratelimit": u"限速",
               "network_lbaas_loadbalancer": u"负载均衡"}

        headers = (u"资源ID", u"资源名称", u"资源类型",
                   u"金额(元)", u"用户ID", u"项目ID",
                   u"创建时间")
        data = []

        adata = (u"过滤条件: 资源类型: %s, 用户ID: %s, "
                 u"项目ID: %s, 起始时间: %s, 结束时间: %s" %
                 (type, user_id, project_id,
                  start_time, end_time),
                 "", "", "", "", "", "")
        data.append(adata)

        resources = []

        for service in MAP:
            resources += _gnocchi_fetcher.get_resources(project_id, service)

        for resource in resources:
            if 'total.cost' in resource['metrics']:
                price = _gnocchi_fetcher.get_resource_price(
                    resource['metrics']['total.cost'], start_time, end_time)
                adata = (resource['id'], resource['display_name'],
                         MAP[resource['type']], price,
                         resource['user_id'], resource['project_id'],
                         resource['started_at'])
                data.append(adata)

        data = tablib.Dataset(*data, headers=headers)

        response.content_type = "application/binary; charset=UTF-8"
        response.content_disposition = \
            "attachment; filename=orders.%s" % output_format
        content = getattr(data, output_format)
        response.write(content)
        return response
예제 #14
0
 def get(self):
     """Get this account."""
     policy.check_policy(HOOK.context, "account:get", action="account:get")
     user_id = self._id
     return models.AdminAccount(**self._account(user_id=user_id))