监控阿里云多账号余额

监控阿里云多账号余额
首次编写时间:2023-3-18
  已经算是半成品,凭借我的聪明才智(开玩笑,哈哈哈),今天做的。
更新时间:2023-3-22
       截止到今天,我已经写好了(中间掺杂了别的任务),有加签和非加签版本的钉钉报警。没想过后面挺多细节需要注意,我补充下。
 
一、需求引入
  我们公司有很多个阿里云账号,每次登录进去看用户余额,让我不胜其烦(各种加载,网络慢的各种转圈),甚至试过一次忘记充值,导致被停机,搞到写故障报告。曾经试过配置到短信转发器SmsForwarder,但是那玩意经常抽风,不发到钉钉上,所以形同虚设。
  所以我觉得非常有必要,借他山之石(阿里云的api接口)进行监控账号余额,解放我的双手。
 
二、需求实现
  首先需要准备一个yaml 的文件(python能很好支持这种文件的解析),记录账号下的 AccessKey ID和 AccessKey Secret,后面调用阿里的接口用来保证安全性的。
假设叫 acc.yaml,里面内容类似这样,记录阿里子账号的akID 和 akSecret,格式大致如下:
账号1的名字:
  akId: 账号1 的 akID
  akSecret: 账号1 的 akSecret

账号2的名字: 
akId: 账号2 的 akID
akSecret: 账号2 的 akSecret
。。。。

 

这里的坑主要包括:

1、首先我们账号有个纯数字的,而我用于装账号的数组 aliaccount,对于数字是不能用双引号引起来的!其他诸如中文或者纯字符串就需要。所以最后应该长这样

aliaccount[123, "windy", "加加_1"]

 

2、比较账号余额超过阈值

  我一开始查到的是用 Decimal 函数( https://blog.csdn.net/baidu_19473529/article/details/103544403),这个不好用,本来查出来余额保留两位小数,用这个函数会保留n多位小数。然后我干脆用float 去判断。

  但是有个账号余额查出来又有逗号,导致用float 比较报错,这时候需要去掉数字之间的逗号,参考:

 

3、最后是钉钉加签,python3版本的(大家留作模板用)

主程序:

  1 # -*- coding: utf-8 -*-
  2 # This file is auto-generated, don't edit it. Thanks.
  3 import sys
  4 
  5 from typing import List
  6 
  7 from alibabacloud_bssopenapi20171214.client import Client as BssOpenApi20171214Client
  8 from alibabacloud_tea_openapi import models as open_api_models
  9 from alibabacloud_tea_util import models as util_models
 10 from alibabacloud_tea_util.client import Client as UtilClient
 11 
 12 from aliyunsdkcore.client import AcsClient
 13 
 14 from aliyunsdkbssopenapi.request.v20171214.QueryAccountBalanceRequest import QueryAccountBalanceRequest
 15 
 16 import json
 17 import yaml
 18 
 19 import requests
 20 
 21 import datetime
 22 import time
 23 ### 钉钉加签用
 24 import base64
 25 import hmac
 26 import hashlib
 27 import urllib.parse
 28 
 29 
 30 # 1、发送消息的函数
 31 ## 1.1 钉钉机器人-不加签
 32 def send_msg(msg):
 33     url = 'xxxx'
 34     program = {"msgtype": "text", "text": {"content": msg}, "at": {"atMobiles": ['手机号码'], "isAtAll": "false"}}
 35     headers = {'Content-Type': 'application/json'}
 36     try:
 37         f = requests.post(url, data=json.dumps(program), headers=headers)
 38     except Exception as e:
 39         return False
 40     return f.status_code
 41 
 42 ## 1.2 钉钉机器人-加签
 43 def sendmsg_sign(msg):
 44     timestamp = str(round(time.time() * 1000))
 45     secret = 'xxx'
 46 
 47     secret_enc = secret.encode('utf-8')
 48     string_to_sign = '{}\n{}'.format(timestamp, secret)
 49     string_to_sign_enc = string_to_sign.encode('utf-8')
 50     hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
 51 
 52     sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
 53     url = "https://oapi.dingtalk.com/robot/send?access_token=xxx&timestamp={}&
 54 sign={}" \
 55             .format(timestamp, sign)
 56 
 57     data  = {"msgtype": "text", "text": {"content": msg}, "at": {"atMobiles": ['手机号码'], "isAtAll": "false"}}
 58     headers = {'Content-Type': 'application/json'}
 59     response = requests.post(url=url, headers=headers, data=json.dumps(data))
 60     print(response.text)
 61     
 62     
 63     
 64 ## 1、以key-value方式,获得yaml文件中,每个账号下的 AKID 和 AKSecret
 65 def yaml_data(n, k):
 66     with open('acc.yaml','r',encoding='utf-8') as f:
 67         data = yaml.safe_load(f)
 68         try:
 69             if n in data.keys():
 70                 return data[n][k]
 71             else:
 72                 print(f"n:{n}不存在")
 73         
 74         except Exception as e :
 75             print(f"key值{e}不存在")
 76 
 77             
 78 ## 2、调用阿里云接口,查询账户余额
 79 def AvailableAmount(Name, Akid, AkSecret):
 80     client = AcsClient(Akid, AkSecret, 'cn-shenzhen')
 81     request = QueryAccountBalanceRequest()
 82     request.set_accept_format('json')
 83 
 84     result = client.do_action_with_exception(request)
 85     res_json = json.loads(str(result, encoding="utf-8"))
 86 
 87     if res_json is not None and res_json["Code"] == "200":
 88         availableAmount = res_json["Data"]["AvailableAmount"]
 89     # 去掉数字中的逗号
 90         availableAmount = availableAmount.replace(',', '')
 91         daydate = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
 92         
 93         if float(availableAmount) < float(value):
 94             send_msg("当前时间:%s\n云账号:%s\n用户余额只剩:%s" %(daydate, Name, availableAmount))
 95             sendmsg_sign("当前时间:%s\n云账号:%s\n用户余额只剩:%s" %(daydate, Name, availableAmount))
 96             
 97             
 98 ## 3、主函数        
 99 if __name__ == '__main__':
100 
101     ## 报警阈值设置为 30 元
102     value = 30
103     account = ["账号1名字","账号2名字", 纯数字账号名字] 
104 
105     for i in range(0, len(aliaccount)):
106        akId = yaml_data(account[i], "akId")
107        akSecret = yaml_data(account[i], "akSecret")
108       
109        AvailableAmount(account[i], akId, akSecret)
110            

效果如下图:

 

 

最后万分感谢给我帮助的文档,排名不分先后~~

参考:

(1)python-读取yaml文件中的数据:https://blog.csdn.net/weixin_43632687/article/details/125216361

(2)python实现监控阿里云账户余额:https://blog.csdn.net/baidu_19473529/article/details/103544403

(3)获取阿里云账户余额并通过飞书通知:https://www.jianshu.com/p/08bddff16cef

 

posted @ 2023-03-17 22:40  windysai  阅读(203)  评论(2编辑  收藏  举报