Beispiel #1
0
def run_task(one):
    """
    # 对每个用户去进行监控
    :param one:
    :return:
    """
    days_dic = reckon_remaind(one.user_uuid)
    if days_dic and 'last_days' in days_dic:
        days = days_dic['last_days']
        # 用户没有主机时候不用监控
        if days <= 0:
            log.info(
                '[monitor][run_task] the user:%s no host.Need not monitor',
                one.user_uuid)
            return
        check_alert = AlertRecord.objects.filter(user_id=one.user_uuid)
        minor_alarm_days = get_config_value('minor_alarm_days')
        critical_alarm_days = get_config_value('critical_alarm_days')
        emergency_alarm_days = get_config_value('emergency_alarm_days')

        if days > minor_alarm_days:
            log.info('[monitor] run_task.the account is enough')
            return
        if days <= minor_alarm_days and days > critical_alarm_days:
            check_alert_time(one.user_uuid, check_alert, 1, days)

        elif days <= critical_alarm_days and days > emergency_alarm_days:
            check_alert_time(one.user_uuid, check_alert, 2, days)

        elif days <= emergency_alarm_days:
            check_alert_time(one.user_uuid, check_alert, 3, days)
        log.info(
            '[monitor][run_task] the user:%s\'s account can support %s days.',
            one.user_uuid, days)
Beispiel #2
0
 def __init__(self):
     
     # 客户端ID
     self.MODE = get_config_value('paypal_mode')
     
     # 客户端密钥
     self.CLIENT_ID = get_config_value('paypal_client_id')
     
     # 客户端密匙
     self.CLIENT_SECRET = get_config_value('paypal_client_secret')
Beispiel #3
0
    def __init__(self):

        # 安全检验码,以数字和字母组成的32位字符
        self.ALIPAY_KEY = get_config_value('alipay_key')

        # 合作身份者ID,以2088开头的16位纯数字
        self.ALIPAY_PARTNER = get_config_value('alipay_partner')

        # 告警通知邮箱
        self.ALIPAY_SELLER_EMAIL = get_config_value('alipay_seller_email')
Beispiel #4
0
def get_alert_strategy():
    sms_notify = int(get_config_value('sms_notify'))
    email_notify = int(get_config_value('email_notify'))
    if sms_notify == 0 and email_notify == 0:
        notify_strategy = 0
    elif sms_notify == 0 and email_notify == 1:
        notify_strategy = 1
    elif sms_notify == 1 and email_notify == 0:
        notify_strategy = 2
    else:
        notify_strategy = 3
    return notify_strategy
Beispiel #5
0
 def list(self, request):
     '''
     # 使用user_uuid查询账户详情, user_uuid不存在时使用该uuid以及默认配置创建新账户
     '''
     pk = request.GET.get('user_uuid')
     if not is_valid_user_uuid(pk):
         return Response({
             'detail': 'user_uuid非法',
             'error_code': '2400'
         },
                         status=status.HTTP_400_BAD_REQUEST)
     try:
         queryset = PaymentAccount.objects.get(user_uuid=pk)
     except PaymentAccount.DoesNotExist:
         # 查询不到该用户时使用默认配置创建新账号
         queryset = PaymentAccount(user_uuid=pk,
                                   credit=get_config_value('credit', 0))
         queryset.save()
         log.info(
             '[account] create payment account %s use default settings.',
             pk)
     except ValueError:
         log.error('[account] get account info error, user_uuid: %s', pk)
         return Response({
             'detail': '参数错误',
             'error_code': '1400'
         },
                         status=status.HTTP_400_BAD_REQUEST)
     serializer = PaymentAccountRetrieveSerializer(
         queryset, context={'request': request})
     return Response(serializer.data)
Beispiel #6
0
    def paypal_return_url(self, request):
        """
        paypal 余额支付回调接口
        """
        payment_no = request.query_params.get('paymentId')
        log.info('[payment] received paypal payment_no: %s', payment_no)
        payer_id = request.query_params.get('PayerID')
        try:
            payment = Payment.objects.get(payment_no=payment_no)
        except Payment.DoesNotExist:
            log.error('[payment] no such payment %s', )
            return Response({
                'error': u'未发现订单',
                'error_code': '3404'
            },
                            status=status.HTTP_404_NOT_FOUND)

        paypal_payment = execute_payment(payment_no, payer_id)
        if paypal_payment is None and payment.paid_status == 'waiting':
            # 交易失败
            payment.paid_status = 'failed'
            payment.save()
            return Response({'error': u'charge fail'})

        for transaction in paypal_payment.transactions:
            for related_resource in transaction.related_resources:
                sale_id = related_resource.sale.id
                payment.sale_id = sale_id
                sale_state = related_resource.sale.state
        # 充值
        payment_charge_success(payment, request.query_params)
        # return Response({'success': u'charge success'})
        return HttpResponseRedirect(
            get_config_value('redirect_url') + '/wallet')
Beispiel #7
0
def alert_message(user_uuid, level_days, notify_strategy=None):
    """
    # 调用通知接口
    """
    data = {}
    data['user_name'] = get_user_name(user_uuid)
    data['level'] = 'INFO'
    data['module'] = 'BL'
    data['msg_title'] = 'account alert'
    data['msg_content'] = '您的账户余额已不足,预估可使用[%s]天' % (level_days)
    data['msg_url'] = ''

    if notify_strategy is None:
        data['is_phone'] = 'True' if get_config_value(
            'sms_notify') else 'False'
        data['is_email'] = 'True' if get_config_value(
            'email_notify') else 'False'
    elif notify_strategy == 0:
        data['is_phone'] = 'False'
        data['is_email'] = 'False'
    elif notify_strategy == 1:
        data['is_phone'] = 'False'
        data['is_email'] = 'True'
    elif notify_strategy == 2:
        data['is_phone'] = 'True'
        data['is_email'] = 'False'
    else:
        data['is_phone'] = 'True'
        data['is_email'] = 'True'

    alert_url = ENV_INIT['ALERT_URL']

    try:
        alert_return = requests.post(alert_url, data=data, timeout=10)
    except requests.exceptions.RequestException:
        log.error('[monitor.alert_message] connect {} error'.format(alert_url))
        return

    log.debug("[monitor.alert_message] call the message api [%s]" %
              (alert_url))
    if alert_return.status_code == 200:
        log.info("[monitor.alert_message] send message[%s]success" %
                 (str(data)))
    else:
        log.error("[monitor.alert_message] send message[%s]fail" % (str(data)))
Beispiel #8
0
 def alipay_return_url(self, request):
     """
     支付宝同步回调接口
     """
     # if notify_verify(request.data) is False:
     #     print '签名验证失败'
     #     return HttpResponse('fail')
     #     print request.query_params
     #  return HttpResponse('success')
     #    完成的url
     return HttpResponseRedirect(
         get_config_value('redirect_url') + '/wallet')
Beispiel #9
0
def get_account_by_user_uuid(**kwargs):
    """
    # 使用user_uuid查询账户详情, user_uuid不存在时使用该uuid以及默认配置创建新账户
    """
    if not is_valid_user_uuid(kwargs.get('user_uuid')):
        return False
    try:
        queryset = PaymentAccount.objects.get(
            user_uuid=kwargs.get('user_uuid'))
    except PaymentAccount.DoesNotExist:
        # 查询不到该用户时使用默认配置创建新账号
        queryset = PaymentAccount(user_uuid=kwargs['user_uuid'],
                                  credit=get_config_value('credit', 0))
        queryset.save()
        log.info('[account] create payment account %s use default settings.',
                 kwargs.get('user_uuid'))
    return queryset
Beispiel #10
0
    def check_account(self, request):
        """
        检查账户余额
        :param request:
        :return:
        """
        try:
            payment_accountid = request.data['payment_accountid']
            price_uuid = request.data['price_uuid']
            num = request.data['num']
        except KeyError:
            return Response({'detail': 'the key is not enough or error'},
                            status=status.HTTP_400_BAD_REQUEST)
        # print 'type(price_uuid):',type(price_uuid)
        price = gain_price_byuuid(price_uuid=price_uuid)
        if price:
            dict1 = {}
            # 估算余额可以支持使用的时长
            try:
                days_dic = reckon_remaind(payment_accountid, num, price.price)
                if days_dic['last_days'] < int(
                        get_config_value('min_remaining_days')):
                    dict1['is_allow'] = False
                else:
                    dict1['is_allow'] = True

                dict1['last_days'] = days_dic['last_days']
                dict1['active_money'] = days_dic['active_money']
                return Response(dict1, status=status.HTTP_200_OK)
            except Exception as e:
                log.error('[monitor] {}'.format(e.__str__()))
                return Response({'detail': 'server error'},
                                status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            return Response({'detail': 'the price strategy is not existed'},
                            status.HTTP_400_BAD_REQUEST)
Beispiel #11
0
def reckon_remaind(user_uuid, num=0, minute_price=0):
    """
    # user_uuid,minute_price
    # 通过user_uuid估算剩余使用天数(天),
    """

    log.info(
        '[monitor] reckon_remaind user_uuid:[%s],num=[%s],minute_price[%s]' %
        (user_uuid, num, minute_price))
    # 默认值
    data_dic = {'last_days': 0, 'active_money': 0, 'host_num': 1}

    try:
        num = int(num)
        minute_price = float(minute_price)
        host_url = create_url('1a' + user_uuid)
    except Exception:
        log.error('[monitor] reckon_remaind parameter is in invalid')
        return data_dic

    # 查看用户账户余额
    account = get_account_by_user_uuid(user_uuid=user_uuid)
    if not account:
        return data_dic

    strategy = get_config_value('strategy')
    if strategy == 'NO_BALANCE_LEFT':
        credit = 0
    else:
        credit = get_config_value('credit', 0)

    # 如果余额加信用额度小于0,就直接返回
    if account.balance + credit <= 0:
        log.info(
            '[monitor] reckon_remaind user:%s,account.balance:%s,credit:%s balance \
        less than 0' % (user_uuid, account.balance, credit))
        data_dic['active_money'] = account.balance + credit
        return data_dic

    try:
        hosts_all = requests.get(host_url, timeout=10).json()
        log.debug('[monitor] get data from [%s]return[%s]' %
                  (host_url, str(hosts_all)))
    except Exception:
        log.error(
            '[monitor] util.run_task:connect beancounter timeout or refused')
        return data_dic

    host_userid = ''
    if isinstance(hosts_all, dict) and 'id' in hosts_all:
        host_userid = hosts_all['id']

    if not host_userid:
        return data_dic

    # 没有主机的情况
    if 'hosts' not in hosts_all or len(hosts_all['hosts']) == 0:
        data_dic['host_num'] = 0
        if num and minute_price:
            data_dic['last_days'] = round(
                float(account.balance + credit) /
                (minute_price * num * 60 * 24), 2)
        else:
            data_dic['last_days'] = 0

        data_dic['active_money'] = account.balance
        log.debug(
            '[monitor] [reckon_remaind] the user:%s no host. last_days=%s',
            user_uuid, data_dic['last_days'])
        return data_dic

    no_pay_fee = 0
    price_minute = 0
    for host in hosts_all['hosts']:
        hostObj = Host(user_uuid, host_userid, host)
        if hostObj.is_invalid():
            log.error('[monitor] The host is invalid')
            continue

        price_minute += hostObj.price
        no_pay_fee += hostObj.get_nopay_fee()
        # 如果主机删除,生成账单并扣费
        if hostObj.is_deleted():
            hostObj.create_bill()
            log.info(
                '[monitor][reckon_remaind] the user:%s\'s host:%s is deleted',
                user_uuid, hostObj.host_uuid)

    # 实际可用余额
    active_money = account.balance - no_pay_fee

    # 实际可用余额小于0,直接返回
    if active_money <= 0:
        data_dic['active_money'] = active_money
        log.info('[monitor] [reckon_remaind] the user:%s active_money=%s',
                 user_uuid, active_money)
        return data_dic

    if num and minute_price:
        # 如果是check_account接口来调用,那么每分钟价格需要加上需要开启主机的数量和每种规格的价格
        price_minute = price_minute + minute_price * num

    if price_minute > 0:
        last_days = round(
            float(active_money + credit) / (price_minute * 60 * 24), 2)
    else:
        last_days = 0

    data_dic['last_days'] = last_days
    data_dic['active_money'] = active_money

    return data_dic
Beispiel #12
0
def change_balance(user_uuid,
                   modify_source_type,
                   modify_balance,
                   modify_source_uuid,
                   payment_account_uuid=None):
    """
    # 账户变更接口, 变更用户额度以及可用性. 
    {
        "payment_account_uuid":"68c4add4-9f14-11e6-80d3-6451066036bd",
        "modify_balance":-100,
        "modify_source_type": "bill",
        "modify_source_uuid":"68c4add4-9f14-11e6-80d3-6451066036bd"
    }
    """
    try:
        if user_uuid:
            paymentAccount = PaymentAccount.objects.get(user_uuid=user_uuid)
        elif payment_account_uuid:
            paymentAccount = PaymentAccount.objects.get(
                payment_account_uuid=payment_account_uuid)
        else:
            log.error('[account] no param payment_account_uuid or user_uuid')
            return False
    except PaymentAccount.DoesNotExist:
        log.error('[account] %s not found', payment_account_uuid or user_uuid)
        return False

    if modify_balance < 0 and modify_source_type not in ('bill', 'admin',
                                                         'refund'):
        log.error('[account] modify_source_type not match modify_balance')
        return False

    elif modify_balance > 0 and modify_source_type not in ('payment', 'admin'):
        log.error('[account] modify_source_type not match modify_balance')
        return False

    # 基于策略以及额度判断
    balance = paymentAccount.balance + modify_balance
    if get_config_value('strategy', 'NO_BALANCE_LEFT') == 'NO_BALANCE_LEFT':
        is_valid = False if balance < 0 else True

    if get_config_value('strategy', 'NO_BALANCE_LEFT') == 'NO_CREDIT_LEFT':
        is_valid = False if (balance + paymentAccount.credit) < 0 else True

    try:
        accountRecord = AccountRecord(payment_account_uuid=paymentAccount,
                                      modify_balance=modify_balance,
                                      modify_source_type=modify_source_type,
                                      modify_source_uuid=modify_source_uuid)
        # 用户额度变更
        paymentAccount.balance = balance
        paymentAccount.is_valid = is_valid
        paymentAccount.save()
        # 变更记录生成
        accountRecord.save()
        log.info('[account] change balance from modify_source_uuid %s success',
                 modify_source_uuid)
        if modify_balance > 0:
            reset_monitor(user_id=paymentAccount.user_uuid)
            log.info('[account] notify monitor reset alarm times')
        return True
    except TransactionManagementError:
        log.error('[account] change balance from modify_source_uuid %s error',
                  modify_source_uuid)
        return False