示例#1
0
 def _check_resource_to_order(self, resource, resource_to_order,
                              bad_resources, try_to_fix):
     try:
         order = resource_to_order[resource.id]
     except KeyError:
         # Situation 1: There may exist resources that have no orders
         # NOTE(suo): The resource billed by month/year may also has no
         # order, but for now, we couldn't know which billing type it is
         # only from the GET resource method, on this occasion, we take
         # this resource as the hourly billing type, then create the order
         # in auto-fix process
         if resource.status == const.STATE_ERROR:
             bad_resources.append(resource)
             return
         if not resource.is_bill:
             return
         try_to_fix['1'].append(resource)
     else:
         # Situation 2: There may exist resource whose status doesn't match
         # with its order's
         if resource.status == const.STATE_ERROR:
             bad_resources.append(resource)
         elif order['unit'] in ['month', 'year']:
             # if the order is billed by month or year, we don't check
             # it for now, just pass, and set it to checked later
             pass
         elif (resource.resource_type == const.RESOURCE_LISTENER
               and resource.admin_state != order['status']):
             # for loadbalancer listener
             action_time = utils.format_datetime(timeutils.strtime())
             try_to_fix['2'].append(
                 Situation2Item(order['order_id'], resource.resource_type,
                                action_time, resource.admin_state,
                                resource.project_id))
         elif (resource.resource_type != const.RESOURCE_LISTENER
               and resource.status != order['status']):
             action_time = utils.format_datetime(timeutils.strtime())
             try_to_fix['2'].append(
                 Situation2Item(order['order_id'], resource.resource_type,
                                action_time, resource.status,
                                resource.project_id))
         # Situation 3: Resource's order has been created, but its bill not
         # be created by master
         elif (not order['cron_time']
               and order['status'] != const.STATE_STOPPED):
             try_to_fix['3'].append(
                 Situation3Item(order['order_id'], resource.created_at,
                                resource.project_id))
         # Situation 5: The order's unit_price is different from the
         # resource's actual price
         else:
             unit_price = (
                 self.RESOURCE_CREATE_MAP[resource.resource_type].\
                 get_unit_price(resource, 'hour'))
             order_unit_price = utils._quantize_decimal(order['unit_price'])
             if unit_price is not None and unit_price != order_unit_price:
                 try_to_fix['5'].append(
                     Situation5Item(order['order_id'], resource, unit_price,
                                    resource.project_id))
         resource_to_order[resource.id]['checked'] = True
示例#2
0
def listener_list(project_id, region_name=None, project_name=None):
    client = get_neutronclient(region_name)
    if project_id:
        listeners = client.list_listeners(
            tenant_id=project_id).get('listeners')
    else:
        listeners = client.list_listeners().get('listeners')

    formatted_listeners = []
    for listener in listeners:
        status = utils.transform_status(listener['status'])
        admin_state = (const.STATE_RUNNING
                       if listener['admin_state_up'] else const.STATE_STOPPED)
        created_at = utils.format_datetime(
            listener.get('created_at', timeutils.strtime()))
        formatted_listeners.append(
            Listener(id=listener['id'],
                     name=listener['name'],
                     admin_state_up=listener['admin_state_up'],
                     admin_state=admin_state,
                     connection_limit=listener['connection_limit'],
                     project_id=listener['tenant_id'],
                     project_name=project_name,
                     resource_type=const.RESOURCE_LISTENER,
                     status=status,
                     original_status=listener['status'],
                     created_at=created_at))

    return formatted_listeners
示例#3
0
 def to_message(self):
     msg = {
         "event_type": "router.create.end.again",
         "payload": {"router": {"id": self.id, "name": self.name, "tenant_id": self.project_id}},
         "timestamp": utils.format_datetime(timeutils.strtime()),
     }
     return msg
示例#4
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()
示例#5
0
def listener_list(project_id, region_name=None, project_name=None):
    client = get_neutronclient(region_name)
    if project_id:
        listeners = client.list_listeners(tenant_id=project_id).get("listeners")
    else:
        listeners = client.list_listeners().get("listeners")

    formatted_listeners = []
    for listener in listeners:
        status = utils.transform_status(listener["status"])
        admin_state = const.STATE_RUNNING if listener["admin_state_up"] else const.STATE_STOPPED
        created_at = utils.format_datetime(listener.get("created_at", timeutils.strtime()))
        formatted_listeners.append(
            Listener(
                id=listener["id"],
                name=listener["name"],
                admin_state_up=listener["admin_state_up"],
                admin_state=admin_state,
                connection_limit=listener["connection_limit"],
                project_id=listener["tenant_id"],
                project_name=project_name,
                resource_type=const.RESOURCE_LISTENER,
                status=status,
                original_status=listener["status"],
                created_at=created_at,
            )
        )

    return formatted_listeners
示例#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()
示例#7
0
def listener_list(project_id, region_name=None, project_name=None):
    client = get_neutronclient(region_name)
    if project_id:
        listeners = client.list_listeners(
            tenant_id=project_id).get('listeners')
    else:
        listeners = client.list_listeners().get('listeners')

    formatted_listeners = []
    for listener in listeners:
        status = utils.transform_status(listener['status'])
        admin_state = (const.STATE_RUNNING
                       if listener['admin_state_up']
                       else const.STATE_STOPPED)
        created_at = utils.format_datetime(
            listener.get('created_at', timeutils.strtime()))
        formatted_listeners.append(
            Listener(id=listener['id'],
                     name=listener['name'],
                     admin_state_up=listener['admin_state_up'],
                     admin_state=admin_state,
                     connection_limit=listener['connection_limit'],
                     project_id=listener['tenant_id'],
                     project_name=project_name,
                     resource_type=const.RESOURCE_LISTENER,
                     status=status,
                     original_status=listener['status'],
                     created_at=created_at))

    return formatted_listeners
示例#8
0
 def restore_resource(self, data):
     action_time = \
         gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
     remarks = '%s Has Been Restored' % data.resource_type.capitalize()
     self.master_api.resource_restore(request.context, self._id,
                                      action_time,
                                      remarks)
示例#9
0
    def delete_resource(self, data):
        """Update the order when delete the resource"""

        action_time = \
            gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
        remarks = '%s Has Been Deleted' % data.resource_type.capitalize()
        self.master_api.resource_deleted(request.context, self._id,
                                         action_time, remarks)
示例#10
0
    def delete_resource(self, data):
        """Update the order when delete the resource"""

        action_time = \
            gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
        remarks = '%s Has Been Deleted' % data.resource_type.capitalize()
        self.master_api.resource_deleted(request.context, self._id,
                                         action_time, remarks)
示例#11
0
 def stop_resource(self, data):
     action_time = \
         gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
     if data.resource_type == 'instance':
         self.master_api.instance_stopped(request.context, self._id,
                                          action_time)
     else:
         remarks = '%s Has Been Stopped' % data.resource_type.capitalize()
         self.master_api.resource_stopped(request.context, self._id,
                                          action_time, remarks)
示例#12
0
 def stop_resource(self, data):
     action_time = \
         gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
     if data.resource_type == 'instance':
         self.master_api.instance_stopped(request.context, self._id,
                                          action_time)
     else:
         remarks = '%s Has Been Stopped' % data.resource_type.capitalize()
         self.master_api.resource_stopped(request.context, self._id,
                                          action_time, remarks)
示例#13
0
 def _check_order_to_resource(self, resource_id, order, try_to_fix):
     # if the order is billed by month or year, we don't check it
     if order['unit'] in ['month', 'year']:
         LOG.warn("The monthly/yearly billing resource %s has been "
                  "deleted, the order is %s, please check it manually",
                  resource_id, order['order_id'])
     else:
         # Situation 4: The resource of the order has been deleted
         deleted_at = utils.format_datetime(timeutils.strtime())
         try_to_fix['4'].append(Situation4Item(order['order_id'],
                                               deleted_at,
                                               order['project_id']))
示例#14
0
 def to_message(self):
     msg = {
         'event_type': 'image.activate.again',
         'payload': {
             'id': self.id,
             'name': self.name,
             'size': self.size,
             'owner': self.project_id,
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#15
0
 def to_message(self):
     msg = {
         "event_type": "alarm.creation.again",
         "payload": {
             "alarm_id": self.id,
             "detail": {"name": self.name},
             "user_id": self.user_id,
             "project_id": self.project_id,
         },
         "timestamp": utils.format_datetime(timeutils.strtime()),
     }
     return msg
示例#16
0
 def _check_order_to_resource(self, resource_id, order, try_to_fix):
     # if the order is billed by month or year, we don't check it
     if order['unit'] in ['month', 'year']:
         LOG.warn("The monthly/yearly billing resource %s has been "
                  "deleted, the order is %s, please check it manually",
                  resource_id, order['order_id'])
     else:
         # Situation 4: The resource of the order has been deleted
         deleted_at = utils.format_datetime(timeutils.strtime())
         try_to_fix['4'].append(Situation4Item(order['order_id'],
                                               deleted_at,
                                               order['project_id']))
示例#17
0
 def to_message(self):
     msg = {
         'event_type': 'router.create.end.again',
         'payload': {
             'router': {
                 'id': self.id,
                 'name': self.name,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#18
0
 def to_message(self):
     msg = {
         'event_type': 'snapshot.create.end.again',
         'payload': {
             'snapshot_id': self.id,
             'display_name': self.name,
             'volume_size': self.size,
             'user_id': self.user_id,
             'tenant_id': self.project_id
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#19
0
 def to_message(self):
     msg = {
         'event_type': 'snapshot.create.end.again',
         'payload': {
             'snapshot_id': self.id,
             'display_name': self.name,
             'volume_size': self.size,
             'user_id': self.user_id,
             'tenant_id': self.project_id
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#20
0
 def to_message(self):
     msg = {
         'event_type': 'router.create.end.again',
         'payload': {
             'router': {
                 'id': self.id,
                 'name': self.name,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#21
0
 def to_message(self):
     msg = {
         'event_type': 'alarm.creation.again',
         'payload': {
             'alarm_id': self.id,
             'detail': {
                 'name': self.name,
             },
             'user_id': self.user_id,
             'project_id': self.project_id
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#22
0
 def to_message(self):
     msg = {
         'event_type': 'alarm.creation.again',
         'payload': {
             'alarm_id': self.id,
             'detail': {
                 'name': self.name,
             },
             'user_id': self.user_id,
             'project_id': self.project_id
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#23
0
 def to_message(self):
     msg = {
         "event_type": "listener.create.end",
         "payload": {
             "listener": {
                 "id": self.id,
                 "name": self.name,
                 "admin_state_up": self.admin_state_up,
                 "connection_limit": self.connection_limit,
                 "tenant_id": self.project_id,
             }
         },
         "timestamp": utils.format_datetime(timeutils.strtime()),
     }
     return msg
示例#24
0
 def to_message(self):
     msg = {
         "event_type": "floatingipset.create.end.again",
         "payload": {
             "floatingipset": {
                 "id": self.id,
                 "uos:name": self.name,
                 "uos:service_provider": self.providers,
                 "rate_limit": self.size,
                 "tenant_id": self.project_id,
             }
         },
         "timestamp": utils.format_datetime(timeutils.strtime()),
     }
     return msg
示例#25
0
 def to_message(self):
     msg = {
         'event_type': 'listener.create.end',
         'payload': {
             'listener': {
                 'id': self.id,
                 'name': self.name,
                 'admin_state_up': self.admin_state_up,
                 'connection_limit': self.connection_limit,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#26
0
 def to_message(self):
     msg = {
         'event_type': 'floatingipset.create.end.again',
         'payload': {
             'floatingipset': {
                 'id': self.id,
                 'uos:name': self.name,
                 'uos:service_provider': self.providers,
                 'rate_limit': self.size,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#27
0
 def to_message(self):
     msg = {
         'event_type': 'floatingipset.create.end.again',
         'payload': {
             'floatingipset': {
                 'id': self.id,
                 'uos:name': self.name,
                 'uos:service_provider': self.providers,
                 'rate_limit': self.size,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#28
0
 def to_message(self):
     msg = {
         'event_type': 'listener.create.end',
         'payload': {
             'listener': {
                 'id': self.id,
                 'name': self.name,
                 'admin_state_up': self.admin_state_up,
                 'connection_limit': self.connection_limit,
                 'tenant_id': self.project_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#29
0
    def resize_resource(self, data):
        """Update the order when resize the resource"""

        action_time = \
            gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
        remarks = '%s Has Been Resized' % data.resource_type.capitalize()

        self._validate_resize(data.as_dict())

        if data.resource_type == 'instance':
            self.master_api.instance_resized(request.context, self._id,
                                             action_time, data.new_flavor,
                                             data.old_flavor, data.service,
                                             data.region_id, remarks)
        else:
            self.master_api.resource_resized(request.context,
                                             self._id, action_time,
                                             data.quantity, remarks)
示例#30
0
 def to_message(self):
     msg = {
         'event_type': 'compute.instance.create.end.again',
         'payload': {
             'instance_type': self.flavor_name,
             'disk_gb': self.disk_gb,
             'instance_id': self.id,
             'display_name': self.name,
             'user_id': self.user_id,
             'tenant_id': self.project_id,
             'image_name': self.image_name,
             'image_meta': {
                 'base_image_ref': self.image_id
             }
         },
         'timestamp': utils.format_datetime(timeutils.strtime())
     }
     return msg
示例#31
0
    def resize_resource(self, data):
        """Update the order when resize the resource"""

        action_time = \
            gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
        remarks = '%s Has Been Resized' % data.resource_type.capitalize()

        self._validate_resize(data.as_dict())

        if data.resource_type == 'instance':
            self.master_api.instance_resized(request.context, self._id,
                                             action_time, data.new_flavor,
                                             data.old_flavor, data.service,
                                             data.region_id, remarks)
        else:
            self.master_api.resource_resized(request.context, self._id,
                                             action_time, data.quantity,
                                             remarks)
示例#32
0
 def post(self, data):
     conn = pecan.request.db_conn
     try:
         order = conn.create_order(request.context, **data.as_dict())
         if order.unit in ['month', 'year']:
             self.master_api.create_monthly_job(
                 request.context, order.order_id,
                 timeutils.isotime(order.cron_time))
         else:
             action_time = \
                 gringutils.format_datetime(
                     timeutils.strtime(timeutils.utcnow()))
             remarks = '%s Has Been Created.' % order.type.capitalize()
             self.master_api.resource_created(request.context,
                                              order.order_id, action_time,
                                              remarks)
     except Exception as e:
         LOG.exception('Fail to create order: %s, for reason %s' %
                       (data.as_dict(), e))
示例#33
0
 def post(self, data):
     conn = pecan.request.db_conn
     try:
         order = conn.create_order(request.context, **data.as_dict())
         if order.unit in ['month', 'year']:
             self.master_api.create_monthly_job(
                 request.context, order.order_id,
                 timeutils.isotime(order.cron_time))
         else:
             action_time = \
                 gringutils.format_datetime(
                     timeutils.strtime(timeutils.utcnow()))
             remarks = '%s Has Been Created.' % order.type.capitalize()
             self.master_api.resource_created(request.context,
                                              order.order_id,
                                              action_time,
                                              remarks)
     except Exception as e:
         LOG.exception('Fail to create order: %s, for reason %s' %
                       (data.as_dict(), e))
示例#34
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'])
示例#35
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
示例#36
0
 def start_resource(self, data):
     action_time = \
         gringutils.format_datetime(timeutils.strtime(timeutils.utcnow()))
     remarks = '%s Has Been Started' % data.resource_type.capitalize()
     self.master_api.resource_started(request.context, self._id,
                                      action_time, remarks)
示例#37
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
示例#38
0
 def _check_resource_to_order(self, resource, resource_to_order,
                              bad_resources, try_to_fix):
     try:
         order = resource_to_order[resource.id]
     except KeyError:
         # Situation 1: There may exist resources that have no orders
         # NOTE(suo): The resource billed by month/year may also has no
         # order, but for now, we couldn't know which billing type it is
         # only from the GET resource method, on this occasion, we take
         # this resource as the hourly billing type, then create the order
         # in auto-fix process
         if resource.status == const.STATE_ERROR:
             bad_resources.append(resource)
             return
         if not resource.is_bill:
             return
         try_to_fix['1'].append(resource)
     else:
         # Situation 2: There may exist resource whose status doesn't match
         # with its order's
         if resource.status == const.STATE_ERROR:
             bad_resources.append(resource)
         elif order['unit'] in ['month', 'year']:
             # if the order is billed by month or year, we don't check
             # it for now, just pass, and set it to checked later
             pass
         elif (resource.resource_type == const.RESOURCE_LISTENER and
               resource.admin_state != order['status']):
             # for loadbalancer listener
             action_time = utils.format_datetime(timeutils.strtime())
             try_to_fix['2'].append(Situation2Item(order['order_id'],
                                                   resource.resource_type,
                                                   action_time,
                                                   resource.admin_state,
                                                   resource.project_id))
         elif (resource.resource_type != const.RESOURCE_LISTENER and
               resource.status != order['status']):
             action_time = utils.format_datetime(timeutils.strtime())
             try_to_fix['2'].append(Situation2Item(order['order_id'],
                                                   resource.resource_type,
                                                   action_time,
                                                   resource.status,
                                                   resource.project_id))
         # Situation 3: Resource's order has been created, but its bill not
         # be created by master
         elif (not order['cron_time'] and
               order['status'] != const.STATE_STOPPED):
             try_to_fix['3'].append(Situation3Item(order['order_id'],
                                                   resource.created_at,
                                                   resource.project_id))
         # Situation 5: The order's unit_price is different from the
         # resource's actual price
         else:
             unit_price = (
                 self.RESOURCE_CREATE_MAP[resource.resource_type].\
                 get_unit_price(resource, 'hour'))
             order_unit_price = utils._quantize_decimal(order['unit_price'])
             if unit_price is not None and unit_price != order_unit_price:
                 try_to_fix['5'].append(Situation5Item(order['order_id'],
                                                       resource,
                                                       unit_price,
                                                       resource.project_id))
         resource_to_order[resource.id]['checked'] = True
示例#39
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'])
示例#40
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'])
示例#41
0
    def get(self,
            output_format='xlsx',
            user_id=None,
            start_time=None,
            end_time=None,
            limit=None,
            offset=None):
        """Export all charges of special user, output formats supported:
           * Excel (Sets + Books)
           * JSON (Sets + Books)
           * YAML (Sets + Books)
           * HTML (Sets)
           * TSV (Sets)
           * CSV (Sets)
        """
        if output_format.lower() not in ["xls", "xlsx", "csv", "json", "yaml"]:
            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")

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

        if limit_user_id:
            user_id = limit_user_id

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

        users = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = kunkka.get_uos_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            real_name = contact.get('real_name') or 'unknown'
            mobile = contact.get('phone') or 'unknown'
            company = contact.get('company') or 'unknown'
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email,
                                         real_name=real_name,
                                         mobile=mobile,
                                         company=company)
            return users[user_id]

        self.conn = pecan.request.db_conn
        charges = self.conn.get_charges(request.context,
                                        user_id=user_id,
                                        limit=limit,
                                        offset=offset,
                                        start_time=start_time,
                                        end_time=end_time)
        for charge in charges:
            charge.charge_time += datetime.timedelta(hours=8)
            acharge = models.Charge.from_db_model(charge)
            acharge.actor = _get_user(charge.operator)
            acharge.target = _get_user(charge.user_id)
            charge_time = \
                timeutils.strtime(charge.charge_time, fmt=OUTPUT_TIME_FORMAT)

            adata = (acharge.charge_id, acharge.target.user_name,
                     acharge.target.user_id, acharge.target.real_name,
                     acharge.target.email, acharge.target.company,
                     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)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
示例#42
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'])
示例#43
0
    def get(self, output_format='xlsx', user_id=None,
            start_time=None, end_time=None,
            limit=None, offset=None):
        """Export all charges of special user, output formats supported:
           * Excel (Sets + Books)
           * JSON (Sets + Books)
           * YAML (Sets + Books)
           * HTML (Sets)
           * TSV (Sets)
           * CSV (Sets)
        """
        if output_format.lower() not in ["xls", "xlsx", "csv", "json", "yaml"]:
            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")

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

        if limit_user_id:
            user_id = limit_user_id

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

        users = {}

        def _get_user(user_id):
            user = users.get(user_id)
            if user:
                return user
            contact = keystone.get_uos_user(user_id) or {}
            user_name = contact.get('name')
            email = contact.get('email')
            real_name = contact.get('real_name') or 'unknown'
            mobile = contact.get('mobile_number') or 'unknown'
            company = contact.get('company') or 'unknown'
            users[user_id] = models.User(user_id=user_id,
                                         user_name=user_name,
                                         email=email,
                                         real_name=real_name,
                                         mobile=mobile,
                                         company=company)
            return users[user_id]

        self.conn = pecan.request.db_conn
        charges = self.conn.get_charges(request.context,
                                        user_id=user_id,
                                        limit=limit,
                                        offset=offset,
                                        start_time=start_time,
                                        end_time=end_time)
        for charge in charges:
            charge.charge_time += datetime.timedelta(hours=8)
            acharge = models.Charge.from_db_model(charge)
            acharge.actor = _get_user(charge.operator)
            acharge.target = _get_user(charge.user_id)
            charge_time = \
                timeutils.strtime(charge.charge_time, fmt=OUTPUT_TIME_FORMAT)

            adata = (acharge.charge_id, acharge.target.user_name,
                     acharge.target.user_id, acharge.target.real_name,
                     acharge.target.email, acharge.target.company,
                     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)
        if output_format == 'csv':
            content = content.decode("utf-8").encode("gb2312")
        response.write(content)
        return response
示例#44
0
def to_primitive(value, convert_instances=False, convert_datetime=True,
                 level=0, max_depth=3):
    """Convert a complex object into primitives.

    Handy for JSON serialization. We can optionally handle instances,
    but since this is a recursive function, we could have cyclical
    data structures.

    To handle cyclical data structures we could track the actual objects
    visited in a set, but not all objects are hashable. Instead we just
    track the depth of the object inspections and don't go too deep.

    Therefore, convert_instances=True is lossy ... be aware.

    """
    # handle obvious types first - order of basic types determined by running
    # full tests on nova project, resulting in the following counts:
    # 572754 <type 'NoneType'>
    # 460353 <type 'int'>
    # 379632 <type 'unicode'>
    # 274610 <type 'str'>
    # 199918 <type 'dict'>
    # 114200 <type 'datetime.datetime'>
    #  51817 <type 'bool'>
    #  26164 <type 'list'>
    #   6491 <type 'float'>
    #    283 <type 'tuple'>
    #     19 <type 'long'>
    if isinstance(value, _simple_types):
        return value

    if isinstance(value, datetime.datetime):
        if convert_datetime:
            return timeutils.strtime(value)
        else:
            return value

    # value of itertools.count doesn't get caught by nasty_type_tests
    # and results in infinite loop when list(value) is called.
    if type(value) == itertools.count:
        return six.text_type(value)

    # FIXME(vish): Workaround for LP bug 852095. Without this workaround,
    #              tests that raise an exception in a mocked method that
    #              has a @wrap_exception with a notifier will fail. If
    #              we up the dependency to 0.5.4 (when it is released) we
    #              can remove this workaround.
    if getattr(value, '__module__', None) == 'mox':
        return 'mock'

    if level > max_depth:
        return '?'

    # The try block may not be necessary after the class check above,
    # but just in case ...
    try:
        recursive = functools.partial(to_primitive,
                                      convert_instances=convert_instances,
                                      convert_datetime=convert_datetime,
                                      level=level,
                                      max_depth=max_depth)
        if isinstance(value, dict):
            return dict((k, recursive(v)) for k, v in value.iteritems())
        elif isinstance(value, (list, tuple)):
            return [recursive(lv) for lv in value]

        # It's not clear why xmlrpclib created their own DateTime type, but
        # for our purposes, make it a datetime type which is explicitly
        # handled
        if xmlrpclib and isinstance(value, xmlrpclib.DateTime):
            value = datetime.datetime(*tuple(value.timetuple())[:6])

        if convert_datetime and isinstance(value, datetime.datetime):
            return timeutils.strtime(value)
        elif isinstance(value, gettextutils.Message):
            return value.data
        elif hasattr(value, 'iteritems'):
            return recursive(dict(value.iteritems()), level=level + 1)
        elif hasattr(value, '__iter__'):
            return recursive(list(value))
        elif convert_instances and hasattr(value, '__dict__'):
            # Likely an instance of something. Watch for cycles.
            # Ignore class member vars.
            return recursive(value.__dict__, level=level + 1)
        elif netaddr and isinstance(value, netaddr.IPAddress):
            return six.text_type(value)
        else:
            if any(test(value) for test in _nasty_type_tests):
                return six.text_type(value)
            return value
    except TypeError:
        # Class objects are tricky since they may define something like
        # __iter__ defined but it isn't callable as list().
        return six.text_type(value)