示例#1
0
    def get_all(self, type=None, status=None, start_time=None, end_time=None,
                limit=None, offset=None, resource_id=None, region_id=None,
                project_id=None, user_id=None, owed=None, bill_methods=None):
        """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.
        """
        if limit and limit < 0:
            raise exception.InvalidParameterValue(err="Invalid limit")
        if offset and offset < 0:
            raise exception.InvalidParameterValue(err="Invalid offset")

        limit_user_id = acl.get_limited_to_user(
            request.headers, 'orders_get')

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id:
                project_ids = ([project_id]
                               if project_id in _project_ids
                               else _project_ids)
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = None

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        conn = pecan.request.db_conn
        orders_db, total_count = conn.get_orders(request.context,
                                                 type=type,
                                                 status=status,
                                                 start_time=start_time,
                                                 end_time=end_time,
                                                 owed=owed,
                                                 limit=limit,
                                                 offset=offset,
                                                 with_count=True,
                                                 resource_id=resource_id,
                                                 bill_methods=bill_methods,
                                                 region_id=region_id,
                                                 user_id=user_id,
                                                 project_ids=project_ids)
        orders = []
        for order in orders_db:
            price = self._get_order_price(order,
                                          start_time=start_time,
                                          end_time=end_time)
            order.total_price = gringutils._quantize_decimal(price)
            orders.append(models.Order.from_db_model(order))

        return models.Orders.transform(total_count=total_count,
                                       orders=orders)
示例#2
0
    def estimate(self, region_id=None):
        """Get estimation of specified project and region."""
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'project_estimate')

        if limit_user_id:  # normal user
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            project_ids = [self._id] if self._id in _project_ids else []
        else:  # accountant
            project_ids = [self._id]

        # good way to go
        conn = pecan.request.db_conn

        # Get all orders of this particular context one time
        orders_db = list(
            conn.get_orders(request.context,
                            project_ids=project_ids,
                            region_id=region_id,
                            read_deleted=False,
                            bill_methods=['hour']))

        total_price = gringutils._quantize_decimal(0)
        total_count = 0
        summaries = []

        # loop all order types
        for order_type in const.ORDER_TYPE:

            order_total_price = gringutils._quantize_decimal(0)
            order_total_count = 0

            # One user's order records will not be very large, so we can
            # traverse them directly
            for order in orders_db:
                if order.type != order_type:
                    continue
                order_total_price += order.unit_price * 24
                order_total_count += 1

            summaries.append(
                models.Summary.transform(total_count=order_total_count,
                                         order_type=order_type,
                                         total_price=order_total_price))
            total_price += order_total_price
            total_count += order_total_count

        return models.Summaries.transform(total_price=total_price,
                                          total_count=total_count,
                                          summaries=summaries)
示例#3
0
    def estimate(self, region_id=None):
        """Get estimation of specified project and region."""
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'project_estimate')

        if limit_user_id: # normal user
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            project_ids = [self._id] if self._id in _project_ids else []
        else: # accountant
            project_ids = [self._id]

        # good way to go
        conn = pecan.request.db_conn

        # Get all orders of this particular context one time
        orders_db = list(conn.get_orders(request.context,
                                         project_ids=project_ids,
                                         region_id=region_id,
                                         read_deleted=False,
                                         bill_methods=['hour']))

        total_price = gringutils._quantize_decimal(0)
        total_count = 0
        summaries = []

        # loop all order types
        for order_type in const.ORDER_TYPE:

            order_total_price = gringutils._quantize_decimal(0)
            order_total_count = 0

            # One user's order records will not be very large, so we can
            # traverse them directly
            for order in orders_db:
                if order.type != order_type:
                    continue
                order_total_price += order.unit_price * 24
                order_total_count += 1

            summaries.append(models.Summary.transform(total_count=order_total_count,
                                                      order_type=order_type,
                                                      total_price=order_total_price))
            total_price += order_total_price
            total_count += order_total_count

        return models.Summaries.transform(total_price=total_price,
                                          total_count=total_count,
                                          summaries=summaries)
示例#4
0
    def get_all(self, output_format='xlsx', type=None, status=None,
                start_time=None, end_time=None, limit=None, offset=None,
                region_id=None, project_id=None, user_id=None, owed=None):
        """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.
        """
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'export_orders')

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

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id and project_id in _project_ids:
                project_ids = [project_id]
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = []

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        users = {}
        projects = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = keystone.get_uos_user(user_id)
            user_name = contact['name'] if contact else None
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name)
            return users[user_id]

        def _get_project(project_id):
            project = projects.get(project_id)
            if project:
                return project
            project = keystone.get_project(project_id)
            project_name = project.name if project else None
            projects[project_id] = models.SimpleProject(
                project_id=project_id,
                project_name=project_name
            )
            return projects[project_id]

        MAP = [
            {"running": u"运行中",
             "stopped": u"暂停中",
             "deleted": u"被删除"},
            {"instance": u"虚拟机",
             "image": u"镜像",
             "snapshot": u"硬盘快照",
             "volume": u"云硬盘",
             "share": u"共享文件",
             "floatingip": u"公网IP",
             "listener": u"负载均衡监听器",
             "router": u"路由器",
             "alarm": u"监控报警"},
        ]

        headers = (u"资源ID", u"资源名称", u"资源类型",
                   u"资源状态", u"单价(元/小时)", u"金额(元)",
                   u"区域", u"用户ID", u"用户名称", u"项目ID",
                   u"项目名称", u"创建时间")
        data = []

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

        conn = pecan.request.db_conn
        orders_db, total_count = conn.get_orders(request.context,
                                                 type=type,
                                                 status=status,
                                                 start_time=start_time,
                                                 end_time=end_time,
                                                 owed=owed,
                                                 limit=limit,
                                                 offset=offset,
                                                 with_count=True,
                                                 region_id=region_id,
                                                 user_id=user_id,
                                                 project_ids=project_ids)
        for order in orders_db:
            price = self._get_order_price(order,
                                          start_time=start_time,
                                          end_time=end_time)
            user = _get_user(order.user_id)
            project = _get_project(order.project_id)
            order.created_at += datetime.timedelta(hours=8)
            created_at = \
                timeutils.strtime(order.created_at, fmt=OUTPUT_TIME_FORMAT)
            adata = (order.resource_id, order.resource_name,
                     MAP[1][order.type], MAP[0][order.status],
                     order.unit_price, price, order.region_id,
                     user.user_id, user.user_name,
                     project.project_id, project.project_name,
                     created_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)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
示例#5
0
    def get(self, start_time=None, end_time=None, region_id=None,
            user_id=None, project_id=None, read_deleted=None):
        """Get summary of all kinds of orders."""
        limit_user_id = acl.get_limited_to_user(
            request.headers, 'order_summary')

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id:
                project_ids = ([project_id]
                               if project_id in _project_ids
                               else _project_ids)
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = []

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        # good way to go
        conn = pecan.request.db_conn

        if read_deleted:
            if read_deleted.lower() == 'true':
                read_deleted = True
            elif read_deleted.lower() == 'false':
                read_deleted = False
            else:
                read_deleted = True
        else:
            read_deleted = True

        # Get all orders of this particular context at one time
        orders_db = list(conn.get_orders(request.context,
                                         start_time=start_time,
                                         end_time=end_time,
                                         user_id=user_id,
                                         project_ids=project_ids,
                                         region_id=region_id,
                                         read_deleted=read_deleted))

        total_price = gringutils._quantize_decimal(0)
        total_count = 0
        summaries = []

        # loop all order types
        for order_type in const.ORDER_TYPE:

            order_total_price = gringutils._quantize_decimal(0)
            order_total_count = 0

            # One user's order records will not be very large, so we can
            # traverse them directly
            for order in orders_db:
                if order.type != order_type:
                    if (order.type == const.RESOURCE_FLOATINGIPSET
                            and order_type == const.RESOURCE_FLOATINGIP):
                        # floatingipset consumption belongs to floatingip
                        pass
                    else:
                        continue
                price, count = self._get_order_price_and_count(
                    order, start_time=start_time, end_time=end_time)
                order_total_price += price
                order_total_count += count

            summaries.append(models.Summary.transform(
                total_count=order_total_count,
                order_type=order_type,
                total_price=order_total_price)
            )
            total_price += order_total_price
            total_count += order_total_count

        return models.Summaries.transform(total_price=total_price,
                                          total_count=total_count,
                                          summaries=summaries)
示例#6
0
    def get_all(self, user_id=None, type=None, duration=None):
        """Get all projects."""
        user_id = acl.get_limited_to_user(request.headers,
                                          'projects_get') or user_id
        self.conn = pecan.request.db_conn
        result = []

        if not type or type.lower() == 'pay':
            # if admin call this api, limit to admin's user_id
            if not user_id:
                user_id = request.context.user_id

            try:
                user_projects = self.conn.get_user_projects(request.context,
                                                            user_id=user_id)
            except Exception as e:
                LOG.exception('Fail to get all projects')
                raise exception.DBError(reason=e)

            project_ids = [up.project_id for up in user_projects]

            if not project_ids:
                LOG.warn('User %s has no payed projects' % user_id)
                return []

            projects = keystone.get_projects_by_project_ids(project_ids)

            for u, p in itertools.product(user_projects, projects):
                if u.project_id == p['id']:
                    billing_owner = p['users']['billing_owner']
                    project_owner = p['users']['project_owner']
                    project_creator = p['users']['project_creator']
                    up = models.UserProject(user_id=user_id,
                                            project_id=u.project_id,
                                            project_name=p['name'],
                                            user_consumption=u.user_consumption,
                                            project_consumption=u.project_consumption,
                                            billing_owner=dict(user_id=billing_owner.get('id') if billing_owner else None,
                                                               user_name=billing_owner.get('name') if billing_owner else None),
                                            project_owner=dict(user_id=project_owner.get('id') if project_owner else None,
                                                               user_name=project_owner.get('name') if project_owner else None),
                                            project_creator=dict(user_id=project_creator.get('id') if project_creator else None,
                                                                 user_name=project_creator.get('name') if project_creator else None),
                                            is_historical=u.is_historical,
                                            created_at=timeutils.parse_isotime(p['created_at']) if p['created_at'] else None)
                    result.append(up)
        elif type.lower() == 'all':
            # if admin call this api, limit to admin's user_id
            if not user_id:
                user_id = request.context.user_id

            k_projects = keystone.get_projects_by_user(user_id)
            project_ids = [p['id'] for p in k_projects]

            if not project_ids:
                LOG.warn('User %s has no projects' % user_id)
                return []

            try:
                g_projects = self.conn.get_projects_by_project_ids(request.context,
                                                                   project_ids)
            except Exception as e:
                LOG.exception('Fail to get all projects')
                raise exception.DBError(reason=e)
            for k, g in itertools.product(k_projects, g_projects):
                if k['id'] == g.project_id:
                    billing_owner = k['users']['billing_owner']
                    project_owner = k['users']['project_owner']
                    project_creator = k['users']['project_creator']
                    up = models.UserProject(user_id=user_id,
                                            project_id=g.project_id,
                                            project_name=k['name'],
                                            project_consumption=g.consumption,
                                            billing_owner=dict(user_id=billing_owner.get('id') if billing_owner else None,
                                                               user_name=billing_owner.get('name') if billing_owner else None),
                                            project_owner=dict(user_id=project_owner.get('id') if project_owner else None,
                                                               user_name=project_owner.get('name') if project_owner else None),
                                            project_creator=dict(user_id=project_creator.get('id') if project_creator else None,
                                                                 user_name=project_creator.get('name') if project_creator else None),
                                            is_historical=False,
                                            created_at=timeutils.parse_isotime(k['created_at']) if k['created_at'] else None)
                    result.append(up)

        elif type.lower() == 'simple':
            duration = gringutils.normalize_timedelta(duration)
            if duration:
                active_from = datetime.datetime.utcnow() - duration
            else:
                active_from = None
            g_projects = list(self.conn.get_projects(request.context,
                                                     user_id=user_id,
                                                     active_from=active_from))
            project_ids = [p.project_id for p in g_projects]

            if not project_ids:
                LOG.warn('User %s has no payed projects' % user_id)
                return []

            k_projects = keystone.get_projects_by_project_ids(project_ids)

            for k, g in itertools.product(k_projects, g_projects):
                if k['id'] == g.project_id:
                    up = models.UserProject(project_id=g.project_id,
                                            project_name=k['name'],
                                            domain_id=g.domain_id,
                                            billing_owner=dict(user_id=g.user_id))
                    result.append(up)

        return result
示例#7
0
    def get_all(self,
                output_format='xlsx',
                type=None,
                status=None,
                start_time=None,
                end_time=None,
                limit=None,
                offset=None,
                region_id=None,
                project_id=None,
                user_id=None,
                owed=None):
        """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.
        """
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'export_orders')

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

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id and project_id in _project_ids:
                project_ids = [project_id]
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = []

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        users = {}
        projects = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = kunkka.get_uos_user(user_id)
            user_name = contact['name'] if contact else None
            users[user_id] = models.User(user_id=user_id, user_name=user_name)
            return users[user_id]

        def _get_project(project_id):
            project = projects.get(project_id)
            if project:
                return project
            try:
                project = keystone.get_project(project_id)
                project_name = project.name if project else None
                projects[project_id] = models.SimpleProject(
                    project_id=project_id, project_name=project_name)
                return projects[project_id]
            except Exception as e:
                # Note(chengkun): some project was deleted from keystone,
                # But the project's order still in the gringotts. so when
                # we get the order it will raise 404 project not found error
                LOG.error('error to get project: %s' % e)
                return None

        MAP = [
            {
                "running": u"运行中",
                "stopped": u"暂停中",
                "deleted": u"被删除"
            },
            {
                "instance": u"虚拟机",
                "image": u"镜像",
                "snapshot": u"硬盘快照",
                "volume": u"云硬盘",
                "share": u"共享文件",
                "floatingip": u"公网IP",
                "listener": u"负载均衡监听器",
                "router": u"路由器",
                "alarm": u"监控报警"
            },
        ]

        headers = (u"资源ID", u"资源名称", u"资源类型", u"资源状态", u"单价(元/小时)", u"金额(元)",
                   u"区域", u"用户ID", u"用户名称", u"项目ID", u"项目名称", u"创建时间")
        data = []

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

        conn = pecan.request.db_conn
        orders_db, total_count = conn.get_orders(request.context,
                                                 type=type,
                                                 status=status,
                                                 start_time=start_time,
                                                 end_time=end_time,
                                                 owed=owed,
                                                 limit=limit,
                                                 offset=offset,
                                                 with_count=True,
                                                 region_id=region_id,
                                                 user_id=user_id,
                                                 project_ids=project_ids)
        for order in orders_db:
            price = self._get_order_price(order,
                                          start_time=start_time,
                                          end_time=end_time)
            user = _get_user(order.user_id)
            project = _get_project(order.project_id)
            if project is None:
                continue
            order.created_at += datetime.timedelta(hours=8)
            created_at = \
                timeutils.strtime(order.created_at, fmt=OUTPUT_TIME_FORMAT)
            adata = (order.resource_id, order.resource_name,
                     MAP[1][order.type], MAP[0][order.status],
                     order.unit_price, price, order.region_id, user.user_id,
                     user.user_name, project.project_id, project.project_name,
                     created_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)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
示例#8
0
    def get(self,
            start_time=None,
            end_time=None,
            region_id=None,
            user_id=None,
            project_id=None,
            read_deleted=None):
        """Get summary of all kinds of orders."""
        limit_user_id = acl.get_limited_to_user(request.headers,
                                                'order_summary')

        if limit_user_id:  # normal user
            user_id = None
            projects = keystone.get_projects_by_user(limit_user_id)
            _project_ids = [project['id'] for project in projects]
            if project_id:
                project_ids = ([project_id]
                               if project_id in _project_ids else _project_ids)
            else:
                project_ids = _project_ids
        else:  # accountant
            if project_id:  # look up specified project
                project_ids = [project_id]
            else:  # look up all projects
                project_ids = []

        if project_ids:
            project_ids = list(set(project_ids) - set(cfg.CONF.ignore_tenants))

        # good way to go
        conn = pecan.request.db_conn

        if read_deleted:
            if read_deleted.lower() == 'true':
                read_deleted = True
            elif read_deleted.lower() == 'false':
                read_deleted = False
            else:
                read_deleted = True
        else:
            read_deleted = True

        # Get all orders of this particular context at one time
        orders_db = list(
            conn.get_orders(request.context,
                            start_time=start_time,
                            end_time=end_time,
                            user_id=user_id,
                            project_ids=project_ids,
                            region_id=region_id,
                            read_deleted=read_deleted))

        total_price = gringutils._quantize_decimal(0)
        total_count = 0
        summaries = []

        # loop all order types
        for order_type in const.ORDER_TYPE:

            order_total_price = gringutils._quantize_decimal(0)
            order_total_count = 0

            # One user's order records will not be very large, so we can
            # traverse them directly
            for order in orders_db:
                if order.type != order_type:
                    if (order.type == const.RESOURCE_FLOATINGIPSET
                            and order_type == const.RESOURCE_FLOATINGIP):
                        # floatingipset consumption belongs to floatingip
                        pass
                    else:
                        continue
                price, count = self._get_order_price_and_count(
                    order, start_time=start_time, end_time=end_time)
                order_total_price += price
                order_total_count += count

            summaries.append(
                models.Summary.transform(total_count=order_total_count,
                                         order_type=order_type,
                                         total_price=order_total_price))
            total_price += order_total_price
            total_count += order_total_count

        return models.Summaries.transform(total_price=total_price,
                                          total_count=total_count,
                                          summaries=summaries)