pixelarraylib 1.0.2__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pixelarraylib-1.0.2/pixelarraylib.egg-info → pixelarraylib-1.0.4}/PKG-INFO +2 -22
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/README.md +0 -21
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/__init__.py +1 -1
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/__main__.py +25 -21
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/acr.py +50 -2
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/eci.py +92 -21
- pixelarraylib-1.0.4/pixelarraylib/aliyun/eip.py +96 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/oss.py +58 -15
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/scripts/__init__.py +3 -3
- pixelarraylib-1.0.4/pixelarraylib/scripts/build_website.py +259 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4/pixelarraylib.egg-info}/PKG-INFO +2 -22
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib.egg-info/SOURCES.txt +2 -1
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib.egg-info/requires.txt +1 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pyproject.toml +2 -1
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/requirements.txt +1 -0
- pixelarraylib-1.0.2/pixelarraylib/scripts/summary_code_count.py +0 -430
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/LICENSE +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/MANIFEST.in +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/__init__.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/aliyun_email.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/billing.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/content_scanner.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/domain.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/ecs.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/fc.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/sms.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/aliyun/sts.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/db_utils/mysql.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/db_utils/redis.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/decorators/__init__.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/decorators/decorators.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/gitlab/__init__.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/gitlab/code_analyzer.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/gitlab/pypi_package_manager.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/monitor/__init__.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/monitor/feishu.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/net/request.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/scripts/collect_code_to_txt.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/scripts/create_test_case_files.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/scripts/nginx_proxy_to_ecs.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/scripts/remove_empty_lines.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/system/__init__.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib/system/common.py +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib.egg-info/dependency_links.txt +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib.egg-info/entry_points.txt +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/pixelarraylib.egg-info/top_level.txt +0 -0
- {pixelarraylib-1.0.2 → pixelarraylib-1.0.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pixelarraylib
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: PixelArray Python开发工具库 - 包含阿里云服务、数据库工具、装饰器、监控等功能
|
|
5
5
|
Author-email: Lu qi <qi.lu@pixelarrayai.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,6 +33,7 @@ Requires-Dist: alibabacloud_alidns20150109
|
|
|
33
33
|
Requires-Dist: alibabacloud_eci20180808
|
|
34
34
|
Requires-Dist: alibabacloud_bssopenapi20171214
|
|
35
35
|
Requires-Dist: alibabacloud_cr20181201
|
|
36
|
+
Requires-Dist: alibabacloud_vpc20160428
|
|
36
37
|
Requires-Dist: oss2
|
|
37
38
|
Requires-Dist: pymysql
|
|
38
39
|
Requires-Dist: aiomysql
|
|
@@ -81,27 +82,6 @@ from pixelarraylib.decorators import useful_decorators
|
|
|
81
82
|
pixelarraylib create_test_case_files
|
|
82
83
|
```
|
|
83
84
|
|
|
84
|
-
#### 代码提交统计
|
|
85
|
-
```bash
|
|
86
|
-
# 统计最近30天的代码提交
|
|
87
|
-
pixelarraylib summary_code_count
|
|
88
|
-
|
|
89
|
-
# 统计指定日期范围的提交
|
|
90
|
-
pixelarraylib summary_code_count --since="2025-05-09"
|
|
91
|
-
|
|
92
|
-
# 统计特定作者的提交
|
|
93
|
-
pixelarraylib summary_code_count --author="张三"
|
|
94
|
-
|
|
95
|
-
# 输出到CSV文件
|
|
96
|
-
pixelarraylib summary_code_count --output=stats.csv
|
|
97
|
-
|
|
98
|
-
# 只统计特定文件类型
|
|
99
|
-
pixelarraylib summary_code_count --file-types="py,js,vue"
|
|
100
|
-
|
|
101
|
-
# 查看帮助信息
|
|
102
|
-
pixelarraylib summary_code_count --help
|
|
103
|
-
```
|
|
104
|
-
|
|
105
85
|
## 功能特性
|
|
106
86
|
|
|
107
87
|
- **阿里云服务集成**: 包含CMS、Green、DM、FC、SMS、STS等服务
|
|
@@ -32,27 +32,6 @@ from pixelarraylib.decorators import useful_decorators
|
|
|
32
32
|
pixelarraylib create_test_case_files
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
#### 代码提交统计
|
|
36
|
-
```bash
|
|
37
|
-
# 统计最近30天的代码提交
|
|
38
|
-
pixelarraylib summary_code_count
|
|
39
|
-
|
|
40
|
-
# 统计指定日期范围的提交
|
|
41
|
-
pixelarraylib summary_code_count --since="2025-05-09"
|
|
42
|
-
|
|
43
|
-
# 统计特定作者的提交
|
|
44
|
-
pixelarraylib summary_code_count --author="张三"
|
|
45
|
-
|
|
46
|
-
# 输出到CSV文件
|
|
47
|
-
pixelarraylib summary_code_count --output=stats.csv
|
|
48
|
-
|
|
49
|
-
# 只统计特定文件类型
|
|
50
|
-
pixelarraylib summary_code_count --file-types="py,js,vue"
|
|
51
|
-
|
|
52
|
-
# 查看帮助信息
|
|
53
|
-
pixelarraylib summary_code_count --help
|
|
54
|
-
```
|
|
55
|
-
|
|
56
35
|
## 功能特性
|
|
57
36
|
|
|
58
37
|
- **阿里云服务集成**: 包含CMS、Green、DM、FC、SMS、STS等服务
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
ArrayLib 命令行工具入口点
|
|
4
4
|
支持的命令:
|
|
5
5
|
- pixelarraylib create_test_case_files
|
|
6
|
-
- pixelarraylib summary_code_count [options]
|
|
7
6
|
- pixelarraylib collect_code_to_txt [options]
|
|
8
7
|
- pixelarraylib nginx_proxy_to_ecs [options]
|
|
9
8
|
- pixelarraylib remove_empty_lines <input_file> [output_file]
|
|
9
|
+
- pixelarraylib build_website
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import sys
|
|
@@ -22,10 +22,10 @@ def main():
|
|
|
22
22
|
epilog="""
|
|
23
23
|
示例用法:
|
|
24
24
|
pixelarraylib create_test_case_files --help # 创建测试用例文件
|
|
25
|
-
pixelarraylib summary_code_count --help # 查看统计工具帮助
|
|
26
25
|
pixelarraylib collect_code_to_txt --help # 查看收集工具帮助
|
|
27
26
|
pixelarraylib nginx_proxy_to_ecs --help # 查看Nginx反向代理到ECS工具帮助
|
|
28
27
|
pixelarraylib remove_empty_lines --help # 查看去除空行工具帮助
|
|
28
|
+
pixelarraylib build_website --help # 查看一键构建网站工具帮助
|
|
29
29
|
""",
|
|
30
30
|
)
|
|
31
31
|
parser.print_help()
|
|
@@ -36,27 +36,15 @@ def main():
|
|
|
36
36
|
if command == "create_test_case_files":
|
|
37
37
|
# 导入并执行创建测试用例文件功能
|
|
38
38
|
try:
|
|
39
|
-
from pixelarraylib.scripts.create_test_case_files import
|
|
39
|
+
from pixelarraylib.scripts.create_test_case_files import (
|
|
40
|
+
main as create_test_main,
|
|
41
|
+
)
|
|
40
42
|
|
|
41
43
|
create_test_main()
|
|
42
44
|
except ImportError as e:
|
|
43
45
|
print(f"错误:无法导入 create_test_case_files 模块: {e}")
|
|
44
46
|
sys.exit(1)
|
|
45
47
|
|
|
46
|
-
elif command == "summary_code_count":
|
|
47
|
-
# 导入并执行代码统计功能
|
|
48
|
-
try:
|
|
49
|
-
from pixelarraylib.scripts.summary_code_count import main as summary_main
|
|
50
|
-
|
|
51
|
-
# 修改sys.argv,移除第一个参数(arraylib),让summary_code_count正确处理参数
|
|
52
|
-
original_argv = sys.argv
|
|
53
|
-
sys.argv = [original_argv[0]] + original_argv[2:]
|
|
54
|
-
summary_main()
|
|
55
|
-
sys.argv = original_argv
|
|
56
|
-
except ImportError as e:
|
|
57
|
-
print(f"错误:无法导入 summary_code_count 模块: {e}")
|
|
58
|
-
sys.exit(1)
|
|
59
|
-
|
|
60
48
|
elif command == "collect_code_to_txt":
|
|
61
49
|
# 导入并执行代码收集功能
|
|
62
50
|
try:
|
|
@@ -74,7 +62,9 @@ def main():
|
|
|
74
62
|
elif command == "nginx_proxy_to_ecs":
|
|
75
63
|
# 导入并执行Nginx反向代理到ECS功能
|
|
76
64
|
try:
|
|
77
|
-
from pixelarraylib.scripts.nginx_proxy_to_ecs import
|
|
65
|
+
from pixelarraylib.scripts.nginx_proxy_to_ecs import (
|
|
66
|
+
main as nginx_proxy_to_ecs,
|
|
67
|
+
)
|
|
78
68
|
|
|
79
69
|
# 修改sys.argv,移除第一个参数(arraylib),让nginx_proxy_to_ecs正确处理参数
|
|
80
70
|
original_argv = sys.argv
|
|
@@ -88,7 +78,9 @@ def main():
|
|
|
88
78
|
elif command == "remove_empty_lines":
|
|
89
79
|
# 导入并执行去除空行功能
|
|
90
80
|
try:
|
|
91
|
-
from pixelarraylib.scripts.remove_empty_lines import
|
|
81
|
+
from pixelarraylib.scripts.remove_empty_lines import (
|
|
82
|
+
main as remove_empty_lines_main,
|
|
83
|
+
)
|
|
92
84
|
|
|
93
85
|
# 修改sys.argv,移除第一个参数(arraylib),让remove_empty_lines正确处理参数
|
|
94
86
|
original_argv = sys.argv
|
|
@@ -99,6 +91,18 @@ def main():
|
|
|
99
91
|
print(f"错误:无法导入 remove_empty_lines 模块: {e}")
|
|
100
92
|
sys.exit(1)
|
|
101
93
|
|
|
94
|
+
elif command == "build_website":
|
|
95
|
+
# 导入并执行一键构建网站功能
|
|
96
|
+
try:
|
|
97
|
+
from pixelarraylib.scripts.build_website import main as build_website_main
|
|
98
|
+
original_argv = sys.argv
|
|
99
|
+
sys.argv = [original_argv[0]] + original_argv[2:]
|
|
100
|
+
build_website_main()
|
|
101
|
+
sys.argv = original_argv
|
|
102
|
+
except ImportError as e:
|
|
103
|
+
print(f"错误:无法导入 build_website 模块: {e}")
|
|
104
|
+
sys.exit(1)
|
|
105
|
+
|
|
102
106
|
elif command in ["-h", "--help"]:
|
|
103
107
|
parser = argparse.ArgumentParser(
|
|
104
108
|
description="ArrayLib 命令行工具",
|
|
@@ -106,17 +110,17 @@ def main():
|
|
|
106
110
|
epilog="""
|
|
107
111
|
示例用法:
|
|
108
112
|
pixelarraylib create_test_case_files --help # 创建测试用例文件
|
|
109
|
-
pixelarraylib summary_code_count --help # 查看统计工具帮助
|
|
110
113
|
pixelarraylib collect_code_to_txt --help # 查看收集工具帮助
|
|
111
114
|
pixelarraylib nginx_proxy_to_ecs --help # 查看Nginx反向代理到ECS工具帮助
|
|
112
115
|
pixelarraylib remove_empty_lines --help # 查看去除空行工具帮助
|
|
116
|
+
pixelarraylib build_website --help # 查看一键构建网站工具帮助
|
|
113
117
|
""",
|
|
114
118
|
)
|
|
115
119
|
parser.print_help()
|
|
116
120
|
else:
|
|
117
121
|
print(f"错误:未知命令 '{command}'")
|
|
118
122
|
print(
|
|
119
|
-
"可用命令:create_test_case_files,
|
|
123
|
+
"可用命令:create_test_case_files, collect_code_to_txt, nginx_proxy_to_ecs, remove_empty_lines, build_website"
|
|
120
124
|
)
|
|
121
125
|
print("使用 'pixelarraylib --help' 查看帮助")
|
|
122
126
|
sys.exit(1)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
+
import re
|
|
3
4
|
|
|
4
5
|
from typing import List
|
|
5
6
|
|
|
@@ -113,8 +114,31 @@ class ACRUtils:
|
|
|
113
114
|
feishu_alert.send(f"列出命名空间失败: {e}")
|
|
114
115
|
return {}, False
|
|
115
116
|
|
|
117
|
+
def exists_namespace(self, instance_id: str, namespace_name: str):
|
|
118
|
+
"""
|
|
119
|
+
description:
|
|
120
|
+
判断命名空间是否存在
|
|
121
|
+
parameters:
|
|
122
|
+
instance_id (str): 实例ID
|
|
123
|
+
namespace_name (str): 命名空间名称
|
|
124
|
+
return:
|
|
125
|
+
bool: 是否存在
|
|
126
|
+
"""
|
|
127
|
+
response, success = self.list_namespaces(instance_id)
|
|
128
|
+
if not success:
|
|
129
|
+
return False, False
|
|
130
|
+
namespace_names = [
|
|
131
|
+
namespace["NamespaceName"] for namespace in response["Namespaces"]
|
|
132
|
+
]
|
|
133
|
+
return namespace_name in namespace_names, True
|
|
134
|
+
|
|
116
135
|
def create_repository(
|
|
117
|
-
self,
|
|
136
|
+
self,
|
|
137
|
+
instance_id: str,
|
|
138
|
+
namespace_name: str,
|
|
139
|
+
repository_name: str,
|
|
140
|
+
repository_type: str,
|
|
141
|
+
summary: str,
|
|
118
142
|
):
|
|
119
143
|
"""
|
|
120
144
|
description:
|
|
@@ -129,13 +153,16 @@ class ACRUtils:
|
|
|
129
153
|
dict: 创建结果
|
|
130
154
|
success(bool): 是否成功
|
|
131
155
|
"""
|
|
156
|
+
if not re.fullmatch(r"[a-z\-]+", repository_name):
|
|
157
|
+
print("仓库名称只能包含小写英文字母和横杠")
|
|
158
|
+
return {}, False
|
|
132
159
|
try:
|
|
133
160
|
request = cr_20181201_models.CreateRepositoryRequest(
|
|
134
161
|
instance_id=instance_id,
|
|
135
162
|
repo_namespace_name=namespace_name,
|
|
136
163
|
repo_name=repository_name,
|
|
137
164
|
repo_type=repository_type,
|
|
138
|
-
summary=summary
|
|
165
|
+
summary=summary,
|
|
139
166
|
)
|
|
140
167
|
response = self.client.create_repository(request)
|
|
141
168
|
return response.body.to_map(), True
|
|
@@ -164,6 +191,27 @@ class ACRUtils:
|
|
|
164
191
|
feishu_alert.send(f"列出仓库失败: {e}")
|
|
165
192
|
return {}, False
|
|
166
193
|
|
|
194
|
+
def exists_repository(
|
|
195
|
+
self, instance_id: str, namespace_name: str, repository_name: str
|
|
196
|
+
):
|
|
197
|
+
"""
|
|
198
|
+
description:
|
|
199
|
+
判断仓库是否存在
|
|
200
|
+
parameters:
|
|
201
|
+
instance_id (str): 实例ID
|
|
202
|
+
namespace_name (str): 命名空间名称
|
|
203
|
+
repository_name (str): 仓库名称
|
|
204
|
+
return:
|
|
205
|
+
bool: 是否存在
|
|
206
|
+
"""
|
|
207
|
+
response, success = self.list_repositories(instance_id, namespace_name)
|
|
208
|
+
if not success:
|
|
209
|
+
return False, False
|
|
210
|
+
repository_names = [
|
|
211
|
+
repository["RepoName"] for repository in response["Repositories"]
|
|
212
|
+
]
|
|
213
|
+
return repository_name in repository_names, True
|
|
214
|
+
|
|
167
215
|
def delete_repository(
|
|
168
216
|
self, instance_id: str, namespace_name: str, repository_id: str
|
|
169
217
|
):
|
|
@@ -5,15 +5,19 @@ from typing import Optional, Dict, Any, List
|
|
|
5
5
|
from alibabacloud_eci20180808.client import Client as EciClient
|
|
6
6
|
from alibabacloud_eci20180808.models import (
|
|
7
7
|
CreateContainerGroupRequest,
|
|
8
|
+
DescribeAvailableResourceRequestDestinationResource,
|
|
8
9
|
DescribeContainerGroupsRequest,
|
|
9
10
|
CreateContainerGroupRequestContainer,
|
|
10
11
|
CreateContainerGroupRequestImageRegistryCredential,
|
|
11
12
|
CreateContainerGroupRequestTag,
|
|
12
|
-
|
|
13
|
+
DescribeRegionsRequest,
|
|
14
|
+
DescribeAvailableResourceRequest,
|
|
15
|
+
DeleteContainerGroupRequest,
|
|
13
16
|
)
|
|
14
17
|
from alibabacloud_tea_openapi import models as open_api_models
|
|
15
18
|
from alibabacloud_tea_util import models as util_models
|
|
16
19
|
from pixelarraylib.monitor.feishu import Feishu
|
|
20
|
+
from pixelarraylib.aliyun.eip import EIPUtils
|
|
17
21
|
|
|
18
22
|
feishu_alert = Feishu("devtoolkit服务报警")
|
|
19
23
|
|
|
@@ -32,6 +36,11 @@ class ECIUtils:
|
|
|
32
36
|
self.access_key_id = access_key_id
|
|
33
37
|
self.access_key_secret = access_key_secret
|
|
34
38
|
self.client = self._create_client()
|
|
39
|
+
self.eip_utils = EIPUtils(
|
|
40
|
+
region_id=region_id,
|
|
41
|
+
access_key_id=access_key_id,
|
|
42
|
+
access_key_secret=access_key_secret,
|
|
43
|
+
)
|
|
35
44
|
|
|
36
45
|
def _create_client(self) -> EciClient:
|
|
37
46
|
"""
|
|
@@ -48,27 +57,55 @@ class ECIUtils:
|
|
|
48
57
|
)
|
|
49
58
|
return EciClient(config)
|
|
50
59
|
|
|
60
|
+
def describe_available_resource(self, cpu: float, memory: float) -> Dict[str, Any]:
|
|
61
|
+
"""
|
|
62
|
+
description:
|
|
63
|
+
查询可用资源
|
|
64
|
+
parameters:
|
|
65
|
+
cpu(float): CPU
|
|
66
|
+
memory(float): 内存
|
|
67
|
+
return:
|
|
68
|
+
dict: 查询结果
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
describe_zones_request = DescribeAvailableResourceRequest(
|
|
72
|
+
region_id=self.region_id,
|
|
73
|
+
destination_resource=DescribeAvailableResourceRequestDestinationResource(
|
|
74
|
+
category="InstanceType",
|
|
75
|
+
cores=cpu,
|
|
76
|
+
memory=memory,
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
runtime = util_models.RuntimeOptions()
|
|
80
|
+
response = self.client.describe_available_resource_with_options(
|
|
81
|
+
describe_zones_request, runtime
|
|
82
|
+
)
|
|
83
|
+
return response.body.to_map(), True
|
|
84
|
+
except Exception as error:
|
|
85
|
+
feishu_alert.send(f"查询可用资源失败: {error}")
|
|
86
|
+
return {}
|
|
87
|
+
|
|
51
88
|
def create_container_group(
|
|
52
89
|
self,
|
|
53
90
|
container_group_name: str,
|
|
54
|
-
acr_region_id: str,
|
|
55
91
|
acr_credentials: Dict,
|
|
56
92
|
images: List[Dict[str, Any]],
|
|
57
|
-
|
|
58
|
-
|
|
93
|
+
cpu: float,
|
|
94
|
+
memory: float,
|
|
59
95
|
restart_policy: str = "Always",
|
|
96
|
+
allocate_public_ip: bool = True,
|
|
60
97
|
):
|
|
61
98
|
"""
|
|
62
99
|
description:
|
|
63
100
|
创建容器组
|
|
64
101
|
parameters:
|
|
65
102
|
container_group_name(str): 容器组名称
|
|
66
|
-
acr_region_id(str): ACR地域ID
|
|
67
103
|
acr_credentials(Dict): ACR凭证
|
|
68
104
|
images(List[Dict[str, Any]]): 镜像列表
|
|
69
|
-
|
|
70
|
-
|
|
105
|
+
cpu(float): CPU
|
|
106
|
+
memory(float): 内存
|
|
71
107
|
restart_policy(str): 重启策略
|
|
108
|
+
allocate_public_ip(bool): 是否分配公网IP
|
|
72
109
|
return:
|
|
73
110
|
dict: 创建结果
|
|
74
111
|
success(bool): 是否成功
|
|
@@ -77,39 +114,46 @@ class ECIUtils:
|
|
|
77
114
|
for image in images:
|
|
78
115
|
container_0 = CreateContainerGroupRequestContainer(
|
|
79
116
|
name=image["repository_name"],
|
|
80
|
-
image=f"pixelarrayai-registry
|
|
117
|
+
image=f"pixelarrayai-registry.{self.region_id}.cr.aliyuncs.com/{image['namespace_name']}/{image['repository_name']}:latest",
|
|
81
118
|
)
|
|
82
119
|
containers.append(container_0)
|
|
83
120
|
|
|
84
121
|
image_registry_credentials = [
|
|
85
122
|
CreateContainerGroupRequestImageRegistryCredential(
|
|
86
123
|
password=acr_credentials["password"],
|
|
87
|
-
server=f"pixelarrayai-registry
|
|
88
|
-
user_name=acr_credentials["
|
|
124
|
+
server=f"pixelarrayai-registry.{self.region_id}.cr.aliyuncs.com",
|
|
125
|
+
user_name=acr_credentials["username"],
|
|
89
126
|
)
|
|
90
127
|
]
|
|
91
128
|
|
|
92
129
|
tag_0 = CreateContainerGroupRequestTag(key="team", value="pixelarrayai")
|
|
130
|
+
|
|
131
|
+
if allocate_public_ip:
|
|
132
|
+
response, success = self.eip_utils.allocate_eip()
|
|
133
|
+
if not success:
|
|
134
|
+
feishu_alert.send(f"创建容器组失败: 分配公网IP失败")
|
|
135
|
+
return {}, False
|
|
136
|
+
eip_instance_id = response["AllocationId"]
|
|
137
|
+
else:
|
|
138
|
+
eip_instance_id = None
|
|
139
|
+
|
|
93
140
|
create_container_group_request = CreateContainerGroupRequest(
|
|
94
141
|
region_id=self.region_id,
|
|
95
|
-
zone_id=f"{self.region_id}-{zone_id}",
|
|
96
142
|
container_group_name=container_group_name,
|
|
97
143
|
restart_policy=restart_policy,
|
|
98
|
-
cpu=
|
|
99
|
-
memory=
|
|
100
|
-
resource_group_id="rg-acfm3aqovjsymaa",
|
|
144
|
+
cpu=cpu,
|
|
145
|
+
memory=memory,
|
|
101
146
|
dns_policy="Default",
|
|
102
|
-
instance_type=instance_type,
|
|
103
147
|
active_deadline_seconds=600,
|
|
104
148
|
spot_strategy="SpotAsPriceGo",
|
|
105
|
-
host_name="ecitest",
|
|
106
149
|
tag=[tag_0],
|
|
107
150
|
image_registry_credential=image_registry_credentials,
|
|
108
151
|
termination_grace_period_seconds=60,
|
|
109
|
-
container=
|
|
152
|
+
container=containers,
|
|
110
153
|
auto_match_image_cache=False,
|
|
111
154
|
share_process_namespace=True,
|
|
112
155
|
schedule_strategy="VSwitchOrdered",
|
|
156
|
+
eip_instance_id=eip_instance_id,
|
|
113
157
|
)
|
|
114
158
|
runtime = util_models.RuntimeOptions()
|
|
115
159
|
try:
|
|
@@ -133,7 +177,8 @@ class ECIUtils:
|
|
|
133
177
|
"""
|
|
134
178
|
try:
|
|
135
179
|
describe_container_groups_request = DescribeContainerGroupsRequest(
|
|
136
|
-
|
|
180
|
+
container_group_ids=[container_group_id],
|
|
181
|
+
region_id=self.region_id,
|
|
137
182
|
)
|
|
138
183
|
runtime = util_models.RuntimeOptions()
|
|
139
184
|
response = self.client.describe_container_groups_with_options(
|
|
@@ -154,12 +199,38 @@ class ECIUtils:
|
|
|
154
199
|
dict: 查询结果
|
|
155
200
|
"""
|
|
156
201
|
try:
|
|
157
|
-
|
|
202
|
+
describe_container_groups_request = DescribeContainerGroupsRequest(
|
|
203
|
+
region_id=self.region_id
|
|
204
|
+
)
|
|
158
205
|
runtime = util_models.RuntimeOptions()
|
|
159
|
-
response = self.client.
|
|
160
|
-
|
|
206
|
+
response = self.client.describe_container_groups_with_options(
|
|
207
|
+
describe_container_groups_request, runtime
|
|
161
208
|
)
|
|
162
209
|
return response.body.to_map()
|
|
163
210
|
except Exception as error:
|
|
164
211
|
feishu_alert.send(f"查询容器组列表失败: {error}")
|
|
165
212
|
return {}
|
|
213
|
+
|
|
214
|
+
def delete_container_group(self, container_group_id: str):
|
|
215
|
+
"""
|
|
216
|
+
description:
|
|
217
|
+
删除容器组
|
|
218
|
+
parameters:
|
|
219
|
+
container_group_id(str): 容器组ID
|
|
220
|
+
return:
|
|
221
|
+
dict: 删除结果
|
|
222
|
+
success(bool): 是否成功
|
|
223
|
+
"""
|
|
224
|
+
try:
|
|
225
|
+
delete_container_group_request = DeleteContainerGroupRequest(
|
|
226
|
+
container_group_id=container_group_id,
|
|
227
|
+
region_id=self.region_id,
|
|
228
|
+
)
|
|
229
|
+
runtime = util_models.RuntimeOptions()
|
|
230
|
+
response = self.client.delete_container_group_with_options(
|
|
231
|
+
delete_container_group_request, runtime
|
|
232
|
+
)
|
|
233
|
+
return response.body.to_map(), True
|
|
234
|
+
except Exception as error:
|
|
235
|
+
feishu_alert.send(f"删除容器组失败: {error}")
|
|
236
|
+
return {}, False
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from alibabacloud_vpc20160428.client import Client as Vpc20160428Client
|
|
7
|
+
from alibabacloud_tea_openapi import models as open_api_models
|
|
8
|
+
from alibabacloud_vpc20160428 import models as vpc_20160428_models
|
|
9
|
+
from alibabacloud_tea_util import models as util_models
|
|
10
|
+
from alibabacloud_tea_util.client import Client as UtilClient
|
|
11
|
+
from pixelarraylib.monitor.feishu import Feishu
|
|
12
|
+
|
|
13
|
+
feishu_alert = Feishu("devtoolkit服务报警")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EIPUtils:
|
|
17
|
+
def __init__(self, region_id: str, access_key_id: str, access_key_secret: str):
|
|
18
|
+
self.region_id = region_id
|
|
19
|
+
self.access_key_id = access_key_id
|
|
20
|
+
self.access_key_secret = access_key_secret
|
|
21
|
+
self.client = self._create_client()
|
|
22
|
+
|
|
23
|
+
def _create_client(self) -> Vpc20160428Client:
|
|
24
|
+
config = open_api_models.Config(
|
|
25
|
+
access_key_id=self.access_key_id,
|
|
26
|
+
access_key_secret=self.access_key_secret,
|
|
27
|
+
region_id=self.region_id,
|
|
28
|
+
endpoint=f"vpc.{self.region_id}.aliyuncs.com",
|
|
29
|
+
)
|
|
30
|
+
return Vpc20160428Client(config)
|
|
31
|
+
|
|
32
|
+
def allocate_eip(self):
|
|
33
|
+
"""
|
|
34
|
+
description:
|
|
35
|
+
分配EIP
|
|
36
|
+
return:
|
|
37
|
+
dict: 分配结果
|
|
38
|
+
success(bool): 是否成功
|
|
39
|
+
"""
|
|
40
|
+
allocate_eip_address_request = vpc_20160428_models.AllocateEipAddressRequest(
|
|
41
|
+
region_id=self.region_id
|
|
42
|
+
)
|
|
43
|
+
runtime = util_models.RuntimeOptions()
|
|
44
|
+
try:
|
|
45
|
+
# 复制代码运行请自行打印 API 的返回值
|
|
46
|
+
response = self.client.allocate_eip_address_with_options(
|
|
47
|
+
allocate_eip_address_request, runtime
|
|
48
|
+
)
|
|
49
|
+
return response.body.to_map(), True
|
|
50
|
+
except Exception as error:
|
|
51
|
+
feishu_alert.send(f"分配EIP失败: {error}")
|
|
52
|
+
return {}, False
|
|
53
|
+
|
|
54
|
+
def release_eip(self, allocation_id: str):
|
|
55
|
+
"""
|
|
56
|
+
description:
|
|
57
|
+
释放EIP
|
|
58
|
+
parameters:
|
|
59
|
+
allocation_id(str): 分配ID
|
|
60
|
+
return:
|
|
61
|
+
dict: 释放结果
|
|
62
|
+
success(bool): 是否成功
|
|
63
|
+
"""
|
|
64
|
+
release_eip_address_request = vpc_20160428_models.ReleaseEipAddressRequest(
|
|
65
|
+
region_id=self.region_id, allocation_id=allocation_id
|
|
66
|
+
)
|
|
67
|
+
runtime = util_models.RuntimeOptions()
|
|
68
|
+
try:
|
|
69
|
+
response = self.client.release_eip_address_with_options(
|
|
70
|
+
release_eip_address_request, runtime
|
|
71
|
+
)
|
|
72
|
+
return response.body.to_map(), True
|
|
73
|
+
except Exception as error:
|
|
74
|
+
feishu_alert.send(f"释放EIP失败: {error}")
|
|
75
|
+
return {}, False
|
|
76
|
+
|
|
77
|
+
def list_eips(self):
|
|
78
|
+
"""
|
|
79
|
+
description:
|
|
80
|
+
查询EIP列表
|
|
81
|
+
return:
|
|
82
|
+
dict: 查询结果
|
|
83
|
+
success(bool): 是否成功
|
|
84
|
+
"""
|
|
85
|
+
list_eip_addresses_request = vpc_20160428_models.DescribeEipAddressesRequest(
|
|
86
|
+
region_id=self.region_id
|
|
87
|
+
)
|
|
88
|
+
runtime = util_models.RuntimeOptions()
|
|
89
|
+
try:
|
|
90
|
+
response = self.client.describe_eip_addresses_with_options(
|
|
91
|
+
list_eip_addresses_request, runtime
|
|
92
|
+
)
|
|
93
|
+
return response.body.to_map(), True
|
|
94
|
+
except Exception as error:
|
|
95
|
+
feishu_alert.send(f"查询EIP列表失败: {error}")
|
|
96
|
+
return {}, False
|