AliyunPoolCore.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. using dodohold.core;
  2. using Dataoke;
  3. using Tea;
  4. using AlibabaCloud.SDK.BssOpenApi20171214.Models;
  5. using AlibabaCloud.SDK.Ecs20140526.Models;
  6. using AlibabaCloud.SDK.Vpc20160428.Models;
  7. using TencentCloud.Dbbrain.V20210527.Models;
  8. using Org.BouncyCastle.Bcpg.OpenPgp;
  9. using TencentCloud.Tke.V20180525.Models;
  10. using static molilian.core.TkPoolCore;
  11. using ZstdSharp.Unsafe;
  12. using System.Collections.Generic;
  13. namespace molilian.core
  14. {
  15. public partial class AliyunPoolCore
  16. {
  17. private static readonly object _lockObj = new();
  18. private static IEnumerable<AliyunPoolDTO> _cached;
  19. public static AliyunPoolDTO? GetOne(int id)
  20. {
  21. var list = List();
  22. if (!list.Any()) return null;
  23. return list.Where(e => e.id == id).FirstOrDefault();
  24. }
  25. public static IEnumerable<AliyunPoolDTO> List(bool force = false)
  26. {
  27. if (!force && _cached != null) return _cached;
  28. string cache_key = $"cache:aliyun_pool";
  29. var list = RedisHelper.Get<IEnumerable<AliyunPoolDTO>>(cache_key);
  30. if (force || list == null)
  31. {
  32. lock (_lockObj)
  33. {
  34. list = new DBContext.Table("aliyun_pool")
  35. .Where("status=@status", new { status = 1 })
  36. .Select<AliyunPoolDTO>();
  37. list = new DBContext.Table("aliyun_pool")
  38. .Where("status=@status", new { status = 1 })
  39. .Select<AliyunPoolDTO>();
  40. if (list == null) return default;
  41. RedisHelper.Set(cache_key, list, 30 * 86400);
  42. }
  43. }
  44. _cached = list;
  45. return list;
  46. }
  47. public static void Refresh()
  48. {
  49. _ = List(true);
  50. }
  51. public static void UpdateDrawBalance(string name, decimal amout)
  52. {
  53. new DBContext.Table("aliyun_pool")
  54. .Add("balance", amout)
  55. .Add("last_time", DateTime.Now)
  56. .Where("name=@name", new { name })
  57. .Update();
  58. _ = List(true);
  59. }
  60. public void GetBlances()
  61. {
  62. var list = new DBContext.Table("aliyun_pool").Where(string.Empty, new { }).Select<AliyunPoolDTO>();
  63. foreach (var item in list)
  64. {
  65. if (string.IsNullOrEmpty(item.accessKeyId)) continue;
  66. decimal amout = 0;
  67. try
  68. {
  69. AliyunCore core = new AliyunCore(item);
  70. var response = core.QueryAccountBalance();
  71. var balance = response.Body.Data.AvailableAmount;
  72. if (decimal.TryParse(balance, out amout))
  73. {
  74. UpdateDrawBalance(item.name, amout);
  75. if (item.balance != amout && amout <= item.balance_alert_threshold)
  76. {
  77. string message = $"【{item.company}】阿里云当前余额:{amout} 元";
  78. NotifyCore.AnPushNotify("余额预警", message);
  79. NotifyCore.Notify(new NifyMessage
  80. {
  81. message = message,
  82. priority = NifyMessagePriority.high,
  83. tags = ["red_circle"]
  84. });
  85. }
  86. }
  87. }
  88. catch (Exception ex)
  89. {
  90. new LoggerLibrary("aliyun", "balance_error")
  91. .Info($"Account:{item.id}\tbalance:{amout}")
  92. .Info(ex.Message, ex.StackTrace)
  93. .SaveAsync();
  94. }
  95. }
  96. }
  97. public static List<AliyunEcsDTO> EcsList(AliyunPoolDTO item)
  98. {
  99. List<AliyunEcsDTO> result = [];
  100. decimal amout = 0;
  101. try
  102. {
  103. AliyunCore core = new AliyunCore(item);
  104. var regions = item.regions.Split(',');
  105. foreach (var region in regions)
  106. {
  107. var instances = core.GetInstances(region);
  108. foreach (var instance in instances.Instance)
  109. {
  110. var data = new AliyunEcsDTO();
  111. data.cpu = (int)instance.Cpu;
  112. data.instance_id = instance.InstanceId;
  113. data.instance_name = instance.InstanceName;
  114. data.host_name = instance.HostName;
  115. if (DateTime.TryParse(instance.ExpiredTime, out DateTime expired_time))
  116. {
  117. data.expired_time = expired_time;
  118. }
  119. if (DateTime.TryParse(instance.CreationTime, out DateTime creation_time))
  120. {
  121. data.creation_time = creation_time;
  122. }
  123. data.memory = (int)instance.Memory / 1024;
  124. data.region_id = instance.RegionId;
  125. data.instance_type = instance.InstanceType;
  126. var networks = core.DescribeNetworkInterfaces(data.region_id, data.instance_id);
  127. data.AddressIps = new List<AddressIpDTO>();
  128. foreach (var networkInterface in networks)
  129. {
  130. //找出网卡信息
  131. string networkInterfaceId = networkInterface.NetworkInterfaceId;
  132. var privateIps = networkInterface?.PrivateIpSets;
  133. foreach (var taraget in privateIps.PrivateIpSet)
  134. {
  135. string privateIp = taraget.PrivateIpAddress;
  136. //找到当前公网IP
  137. string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;
  138. if (string.IsNullOrEmpty(currentPublicIp))
  139. {
  140. var currentEips = core.DescribeEipsAddresse(region, string.Empty);
  141. var currentEip = currentEips?.Where(e => privateIp.Equals(e.PrivateIpAddress))?.FirstOrDefault();
  142. currentPublicIp = currentEip?.IpAddress;
  143. if (string.IsNullOrEmpty(currentPublicIp))
  144. {
  145. var emptyPrivateEips = currentEips?.Where(e => string.IsNullOrEmpty(e.PrivateIpAddress));
  146. foreach (var emptyEip in emptyPrivateEips)
  147. {
  148. var body = core.DescribeNetworkInterfaceAttribute(region, emptyEip.InstanceId);
  149. if (body != null)
  150. {
  151. if (body.PrivateIpAddress == privateIp)
  152. {
  153. currentPublicIp = emptyEip?.IpAddress;
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. data.AddressIps.Add(new AddressIpDTO
  161. {
  162. networkInterfaceId = networkInterfaceId,
  163. privateIp = privateIp,
  164. publicIp = currentPublicIp,
  165. });
  166. }
  167. }
  168. result.Add(data);
  169. }
  170. }
  171. }
  172. catch (Exception ex)
  173. {
  174. new LoggerLibrary("aliyun", "balance_error")
  175. .Info($"Account:{item.id}\tbalance:{amout}")
  176. .Info(ex.Message, ex.StackTrace)
  177. .SaveAsync();
  178. }
  179. return result;
  180. }
  181. public static List<AliyunEcsDTO> EcsList()
  182. {
  183. List<AliyunEcsDTO> result = new List<AliyunEcsDTO>();
  184. var list = new DBContext.Table("aliyun_pool").Where(string.Empty, new { }).Select<AliyunPoolDTO>();
  185. foreach (var item in list)
  186. {
  187. if (string.IsNullOrEmpty(item.accessKeyId)) continue;
  188. decimal amout = 0;
  189. try
  190. {
  191. AliyunCore core = new AliyunCore(item);
  192. var regions = item.regions.Split(',');
  193. foreach (var region in regions)
  194. {
  195. var instances = core.GetInstances(region);
  196. foreach (var instance in instances.Instance)
  197. {
  198. var data = new AliyunEcsDTO();
  199. data.cpu = (int)instance.Cpu;
  200. data.instance_id = instance.InstanceId;
  201. data.instance_name = instance.InstanceName;
  202. data.host_name = instance.HostName;
  203. if (DateTime.TryParse(instance.ExpiredTime, out DateTime expired_time))
  204. {
  205. data.expired_time = expired_time;
  206. }
  207. if (DateTime.TryParse(instance.CreationTime, out DateTime creation_time))
  208. {
  209. data.creation_time = creation_time;
  210. }
  211. data.memory = (int)instance.Memory / 1024;
  212. data.region_id = instance.RegionId;
  213. data.instance_type = instance.InstanceType;
  214. var networks = core.DescribeNetworkInterfaces(data.region_id, data.instance_id);
  215. data.AddressIps = new List<AddressIpDTO>();
  216. foreach (var networkInterface in networks)
  217. {
  218. //找出网卡信息
  219. string networkInterfaceId = networkInterface.NetworkInterfaceId;
  220. var privateIps = networkInterface?.PrivateIpSets;
  221. foreach (var taraget in privateIps.PrivateIpSet)
  222. {
  223. //找到当前公网IP
  224. string currentPublicIp = taraget?.AssociatedPublicIp?.PublicIpAddress;
  225. data.AddressIps.Add(new AddressIpDTO
  226. {
  227. networkInterfaceId = networkInterfaceId,
  228. privateIp = taraget.PrivateIpAddress,
  229. publicIp = currentPublicIp,
  230. });
  231. }
  232. }
  233. result.Add(data);
  234. }
  235. }
  236. }
  237. catch (Exception ex)
  238. {
  239. new LoggerLibrary("aliyun", "balance_error")
  240. .Info($"Account:{item.id}\tbalance:{amout}")
  241. .Info(ex.Message, ex.StackTrace)
  242. .SaveAsync();
  243. }
  244. }
  245. return result;
  246. }
  247. }
  248. }