dts-dance 0.2.1__tar.gz → 0.2.2__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.
- {dts_dance-0.2.1 → dts_dance-0.2.2}/PKG-INFO +2 -2
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/bytecloud.py +20 -12
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/dflow.py +5 -5
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/dsyncer.py +7 -7
- dts_dance-0.2.1/dtsdance/spacex.py → dts_dance-0.2.2/dtsdance/spacex_bytedts.py +9 -4
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/tcc_inner.py +1 -1
- {dts_dance-0.2.1 → dts_dance-0.2.2}/pyproject.toml +2 -2
- dts_dance-0.2.2/tests/config.py +51 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_dflow.py +2 -4
- {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_spacex.py +5 -8
- {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_tcc.py +8 -6
- {dts_dance-0.2.1 → dts_dance-0.2.2}/uv.lock +8 -8
- dts_dance-0.2.1/tests/config.py +0 -30
- {dts_dance-0.2.1 → dts_dance-0.2.2}/.gitignore +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/.python-version +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/CLAUDE.md +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/DEV.md +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/README.md +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/config.yaml +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/__init__.py +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/feishu_base.py +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/feishu_table.py +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/metrics_fe.py +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/s3.py +0 -0
- {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/tcc_open.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dts-dance
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: dts dance lib
|
|
5
5
|
Keywords: observation,tools
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
|
-
Requires-Dist: boto3<2.0.0,>=1.42.
|
|
7
|
+
Requires-Dist: boto3<2.0.0,>=1.42.29
|
|
8
8
|
Requires-Dist: loguru<0.8.0,>=0.7.3
|
|
9
9
|
Requires-Dist: pyyaml<7.0.0,>=6.0.3
|
|
10
10
|
Requires-Dist: requests<3.0.0,>=2.32.5
|
|
@@ -22,13 +22,14 @@ class ByteCloudClient:
|
|
|
22
22
|
# 每小时刷新一次,单位为秒
|
|
23
23
|
_REFRESH_INTERVAL = 1 * 60 * 60
|
|
24
24
|
|
|
25
|
-
def __init__(self, sites: dict[str, SiteConfig]):
|
|
25
|
+
def __init__(self, enable_jwt_cache: bool, sites: dict[str, SiteConfig] | None = None) -> None:
|
|
26
26
|
"""
|
|
27
27
|
初始化 ByteCloud Client
|
|
28
28
|
从配置文件加载所有环境的信息,并为每个环境初始化 JWT 令牌
|
|
29
29
|
sites 中保存内容 list[(name, endpoint, svc_account, svc_secret)]
|
|
30
30
|
"""
|
|
31
|
-
self.
|
|
31
|
+
self.enable_jwt_cache = enable_jwt_cache
|
|
32
|
+
self.sites = sites if sites is not None else {}
|
|
32
33
|
|
|
33
34
|
# 初始化线程锁,用于保护 jwt_tokens 的并发访问
|
|
34
35
|
self.token_lock = threading.Lock()
|
|
@@ -36,11 +37,14 @@ class ByteCloudClient:
|
|
|
36
37
|
# 初始化 JWT 令牌缓存,按环境名称索引
|
|
37
38
|
self.jwt_tokens: Dict[str, str] = {}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
if enable_jwt_cache:
|
|
41
|
+
logger.info("启用 JWT 令牌缓存")
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
# 更新所有环境的 JWT 令牌
|
|
44
|
+
self._refresh_tokens()
|
|
45
|
+
|
|
46
|
+
# 启动 JWT 令牌刷新线程
|
|
47
|
+
self._start_refresh_thread()
|
|
44
48
|
|
|
45
49
|
def _start_refresh_thread(self):
|
|
46
50
|
"""
|
|
@@ -131,11 +135,15 @@ class ByteCloudClient:
|
|
|
131
135
|
"""
|
|
132
136
|
获取指定站点的 JWT 令牌
|
|
133
137
|
"""
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
if self.enable_jwt_cache:
|
|
139
|
+
# 使用线程锁保护并发访问
|
|
140
|
+
with self.token_lock:
|
|
141
|
+
if site not in self.jwt_tokens:
|
|
142
|
+
raise KeyError(f"站点 {site} 的 JWT 令牌不存在")
|
|
143
|
+
return self.jwt_tokens[site]
|
|
144
|
+
else:
|
|
145
|
+
site_config = self.get_site_config(site)
|
|
146
|
+
return self._acquire_jwt_token(site_config.endpoint, site_config.svc_secret)
|
|
139
147
|
|
|
140
148
|
def build_request_headers(self, site: str) -> dict[str, str]:
|
|
141
149
|
"""
|
|
@@ -150,7 +158,7 @@ class ByteCloudClient:
|
|
|
150
158
|
jwt_token = self.get_jwt_token(site)
|
|
151
159
|
return {"Content-Type": "application/json", "x-jwt-token": jwt_token}
|
|
152
160
|
|
|
153
|
-
def
|
|
161
|
+
def get_site_config(self, site: str) -> SiteConfig:
|
|
154
162
|
"""
|
|
155
163
|
获取指定环境的信息
|
|
156
164
|
|
|
@@ -64,7 +64,7 @@ class DFlowClient:
|
|
|
64
64
|
dict[str, Any]: DFlow 任务信息,包含 create_time 等字段
|
|
65
65
|
"""
|
|
66
66
|
# 构建 API URL
|
|
67
|
-
site_info = self.bytecloud_client.
|
|
67
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
68
68
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeTaskInfo"
|
|
69
69
|
|
|
70
70
|
# 构建请求数据
|
|
@@ -106,7 +106,7 @@ class DFlowClient:
|
|
|
106
106
|
dict[str, Any]: DFlow 进程信息,包含 create_time 等字段
|
|
107
107
|
"""
|
|
108
108
|
# 构建 API URL
|
|
109
|
-
site_info = self.bytecloud_client.
|
|
109
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
110
110
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeDFlowDetail"
|
|
111
111
|
|
|
112
112
|
# 构建请求数据
|
|
@@ -149,7 +149,7 @@ class DFlowClient:
|
|
|
149
149
|
str: DFlow 任务详情页面的 URL
|
|
150
150
|
"""
|
|
151
151
|
# 根据环境生成对应的 scope 参数
|
|
152
|
-
site_info = self.bytecloud_client.
|
|
152
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
153
153
|
return f"{site_info.endpoint}/bytedts/datasync/detail/{task_id}?scope={site}"
|
|
154
154
|
|
|
155
155
|
def init_resources(self, site: str, ctrl_env: str) -> bool:
|
|
@@ -164,7 +164,7 @@ class DFlowClient:
|
|
|
164
164
|
bool: CTRL 环境资源初始化结果
|
|
165
165
|
"""
|
|
166
166
|
# 构建 API URL
|
|
167
|
-
site_info = self.bytecloud_client.
|
|
167
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
168
168
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/InitSystemResource"
|
|
169
169
|
|
|
170
170
|
# 构建请求数据
|
|
@@ -189,7 +189,7 @@ class DFlowClient:
|
|
|
189
189
|
list[str]: CTRL 环境资源列表
|
|
190
190
|
"""
|
|
191
191
|
# 构建 API URL
|
|
192
|
-
site_info = self.bytecloud_client.
|
|
192
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
193
193
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeResources"
|
|
194
194
|
|
|
195
195
|
# 构建请求数据
|
|
@@ -89,7 +89,7 @@ class DSyncerClient:
|
|
|
89
89
|
dict[str, str]: DSyncer 任务的 rocket_mq_connection 信息,只包含 cluster、topic 和 group 字段
|
|
90
90
|
"""
|
|
91
91
|
# 构建 API URL
|
|
92
|
-
site_info = self.bytecloud_client.
|
|
92
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
93
93
|
url = f"{site_info.endpoint}/api/v1/dsyncer/openapi/taskinfo/{task_id}/"
|
|
94
94
|
|
|
95
95
|
# 准备请求头
|
|
@@ -102,7 +102,7 @@ class DSyncerClient:
|
|
|
102
102
|
获取迁移后的 DFlow 任务信息
|
|
103
103
|
"""
|
|
104
104
|
# 构建 API URL
|
|
105
|
-
site_info = self.bytecloud_client.
|
|
105
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
106
106
|
url = f"{site_info.endpoint}/api/v1/dsyncer/openapi/taskinfo/{task_id}/migrate/"
|
|
107
107
|
|
|
108
108
|
# 准备请求头
|
|
@@ -144,7 +144,7 @@ class DSyncerClient:
|
|
|
144
144
|
Returns:
|
|
145
145
|
str: DSyncer 任务详情页面的 URL
|
|
146
146
|
"""
|
|
147
|
-
site_info = self.bytecloud_client.
|
|
147
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
148
148
|
return DSyncer_Task_Detail_URL.format(endpoint=site_info.endpoint, task_id=task_id)
|
|
149
149
|
|
|
150
150
|
def generate_task_grafana_url(self, task_id: str, change_time: str) -> str:
|
|
@@ -208,7 +208,7 @@ class DSyncerClient:
|
|
|
208
208
|
bool: 如果任务正在迁移中,返回 True;否则返回 False
|
|
209
209
|
"""
|
|
210
210
|
# 构建 API URL
|
|
211
|
-
site_info = self.bytecloud_client.
|
|
211
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
212
212
|
url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/migrate/check"
|
|
213
213
|
|
|
214
214
|
# 准备请求头
|
|
@@ -230,7 +230,7 @@ class DSyncerClient:
|
|
|
230
230
|
执行回滚
|
|
231
231
|
"""
|
|
232
232
|
# 构建 API URL
|
|
233
|
-
site_info = self.bytecloud_client.
|
|
233
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
234
234
|
url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/rollback_migrate2dsyncer/"
|
|
235
235
|
|
|
236
236
|
# 准备请求头
|
|
@@ -249,7 +249,7 @@ class DSyncerClient:
|
|
|
249
249
|
标记迁移成功
|
|
250
250
|
"""
|
|
251
251
|
# 构建 API URL
|
|
252
|
-
site_info = self.bytecloud_client.
|
|
252
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
253
253
|
url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/mark_migrate_success/"
|
|
254
254
|
|
|
255
255
|
# 准备请求头
|
|
@@ -271,7 +271,7 @@ class DSyncerClient:
|
|
|
271
271
|
Optional[str]: 错误信息,成功时返回None,失败时返回错误信息
|
|
272
272
|
"""
|
|
273
273
|
# 构建 API URL
|
|
274
|
-
site_info = self.bytecloud_client.
|
|
274
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
275
275
|
url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/migrate2dflow/single"
|
|
276
276
|
|
|
277
277
|
# 准备请求头
|
|
@@ -5,7 +5,7 @@ from loguru import logger
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class GatewayInfo(NamedTuple):
|
|
8
|
-
|
|
8
|
+
mgr_name: str
|
|
9
9
|
ctrl_name: str
|
|
10
10
|
gateway_endpoint: str
|
|
11
11
|
auth_user: str
|
|
@@ -26,7 +26,7 @@ class SpaceXClient:
|
|
|
26
26
|
self.bytecloud_client = bytecloud_client
|
|
27
27
|
|
|
28
28
|
def list_mgr(self, site: str) -> list[Any]:
|
|
29
|
-
site_info = self.bytecloud_client.
|
|
29
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
30
30
|
url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/queryServerMeta"
|
|
31
31
|
|
|
32
32
|
try:
|
|
@@ -41,10 +41,11 @@ class SpaceXClient:
|
|
|
41
41
|
raise
|
|
42
42
|
|
|
43
43
|
def register_gateway(self, site: str, gateway_info: GatewayInfo) -> bool:
|
|
44
|
-
site_info = self.bytecloud_client.
|
|
44
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
45
45
|
url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/registryGateway"
|
|
46
46
|
data_raw = {
|
|
47
|
-
"
|
|
47
|
+
"region": gateway_info.mgr_name,
|
|
48
|
+
"server_region": gateway_info.mgr_name,
|
|
48
49
|
"cluster_region": gateway_info.ctrl_name,
|
|
49
50
|
"cluster_name": gateway_info.ctrl_name,
|
|
50
51
|
"server_domain": gateway_info.gateway_endpoint,
|
|
@@ -55,6 +56,10 @@ class SpaceXClient:
|
|
|
55
56
|
"frontend_password": gateway_info.auth_password,
|
|
56
57
|
"gw_meta_db": gateway_info.gw_meta_db,
|
|
57
58
|
"gateway_type": "psm",
|
|
59
|
+
"runtime_psm": "bytedts.dflow.rownott",
|
|
60
|
+
"tao_service_name": "inf.bytedts.agent",
|
|
61
|
+
"tao_service_node_id": 1071,
|
|
62
|
+
"unified_tao_service": 1,
|
|
58
63
|
}
|
|
59
64
|
try:
|
|
60
65
|
response = requests.post(url, json=data_raw, headers=self.bytecloud_client.build_request_headers(site))
|
|
@@ -24,7 +24,7 @@ class TCCInnerClient:
|
|
|
24
24
|
"""
|
|
25
25
|
List TCC configurations.
|
|
26
26
|
"""
|
|
27
|
-
site_info = self.bytecloud_client.
|
|
27
|
+
site_info = self.bytecloud_client.get_site_config(site)
|
|
28
28
|
url = f"{site_info.endpoint}/api/v3/tcc/bcc/config/list_v2"
|
|
29
29
|
|
|
30
30
|
data_raw = {
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dts-dance"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "dts dance lib"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = ["tools", "observation"]
|
|
@@ -12,7 +12,7 @@ requires-python = ">=3.12"
|
|
|
12
12
|
dependencies = [
|
|
13
13
|
"requests>=2.32.5,<3.0.0",
|
|
14
14
|
"loguru>=0.7.3,<0.8.0",
|
|
15
|
-
"boto3>=1.42.
|
|
15
|
+
"boto3>=1.42.29,<2.0.0",
|
|
16
16
|
"pyyaml>=6.0.3,<7.0.0",
|
|
17
17
|
]
|
|
18
18
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import yaml
|
|
3
|
+
from dtsdance.bytecloud import SiteConfig
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConfigLoader:
|
|
7
|
+
|
|
8
|
+
_instance: "ConfigLoader | None" = None
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
self._site_configs: dict[str, SiteConfig] = {}
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def get_instance(cls) -> "ConfigLoader":
|
|
15
|
+
"""获取单例实例"""
|
|
16
|
+
if cls._instance is None:
|
|
17
|
+
cls._instance = cls()
|
|
18
|
+
|
|
19
|
+
return cls._instance
|
|
20
|
+
|
|
21
|
+
def load_from_file(self, sites: list[str] | None = None) -> None:
|
|
22
|
+
"""从配置文件加载配置"""
|
|
23
|
+
config_path = os.environ.get("CONFIG_PATH", "config.yaml")
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
with open(config_path, "r", encoding="utf-8") as f:
|
|
27
|
+
configs = yaml.safe_load(f)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
raise ValueError(f"加载配置失败: {e}")
|
|
30
|
+
|
|
31
|
+
self._site_configs.update(
|
|
32
|
+
{
|
|
33
|
+
k: SiteConfig(k, v["endpoint"], v["svc_account"], v["svc_secret"], v.get("endpoint_bytedts_spacex", None))
|
|
34
|
+
for k, v in configs["sites"].items()
|
|
35
|
+
if sites is None or k in sites
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def get(self, site: str) -> SiteConfig:
|
|
40
|
+
"""获取指定站点的配置"""
|
|
41
|
+
if not self._site_configs:
|
|
42
|
+
raise RuntimeError("配置未加载,请先调用 load_from_file()")
|
|
43
|
+
|
|
44
|
+
if site not in self._site_configs:
|
|
45
|
+
raise KeyError(f"站点 {site} 不存在")
|
|
46
|
+
|
|
47
|
+
return self._site_configs[site]
|
|
48
|
+
|
|
49
|
+
def get_site_configs(self) -> dict[str, SiteConfig]:
|
|
50
|
+
"""获取所有配置"""
|
|
51
|
+
return self._site_configs
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
from dtsdance.dflow import DFlowClient
|
|
2
2
|
from dtsdance.bytecloud import ByteCloudClient
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
site_configs = load_site_configs(["boe", "cn"])
|
|
7
|
-
bytecloud_client = ByteCloudClient(site_configs)
|
|
4
|
+
bytecloud_client = ByteCloudClient(False)
|
|
8
5
|
dflow_client = DFlowClient(bytecloud_client)
|
|
9
6
|
|
|
10
7
|
|
|
@@ -13,6 +10,7 @@ def test_get_task_info():
|
|
|
13
10
|
info = dflow_client.get_task_info("cn", "106037095986690")
|
|
14
11
|
print(f"DFlow Info: {info}")
|
|
15
12
|
|
|
13
|
+
|
|
16
14
|
# pytest tests/test_dflow.py::test_get_dflow_info -s
|
|
17
15
|
def test_get_dflow_info():
|
|
18
16
|
info = dflow_client.get_dflow_info("cn", "106029334786818")
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from dtsdance.bytecloud import ByteCloudClient
|
|
3
|
-
from dtsdance.
|
|
4
|
-
from config import load_site_configs
|
|
3
|
+
from dtsdance.spacex_bytedts import GatewayInfo, SpaceXClient
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
site_configs = load_site_configs([site])
|
|
8
|
-
bytecloud_client = ByteCloudClient(site_configs)
|
|
5
|
+
bytecloud_client = ByteCloudClient(False)
|
|
9
6
|
spacex = SpaceXClient(bytecloud_client)
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
# pytest tests/test_spacex.py::test_list_mgr -s
|
|
13
10
|
def test_list_mgr():
|
|
14
|
-
mgr_list = spacex.list_mgr(
|
|
11
|
+
mgr_list = spacex.list_mgr("boe")
|
|
15
12
|
print(f"mgr_list: {json.dumps(mgr_list, indent=2, ensure_ascii=False)}")
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
# pytest tests/test_spacex.py::test_register_gateway -s
|
|
19
16
|
def test_register_gateway():
|
|
20
17
|
gateway_info = GatewayInfo(
|
|
21
|
-
|
|
18
|
+
mgr_name="boe",
|
|
22
19
|
ctrl_name="boe_halo_test",
|
|
23
20
|
gateway_endpoint="volc.dts.gateway.service.boe:cluster:boe_halo_test:family:v6",
|
|
24
21
|
auth_user="bytedts_backend",
|
|
@@ -26,5 +23,5 @@ def test_register_gateway():
|
|
|
26
23
|
root_secret_key="97oscH5k",
|
|
27
24
|
gw_meta_db="bytedts_sre_halo",
|
|
28
25
|
)
|
|
29
|
-
result = spacex.register_gateway(
|
|
26
|
+
result = spacex.register_gateway("boe", gateway_info)
|
|
30
27
|
print(f"result: {result}")
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
from config import load_site_configs
|
|
2
1
|
from dtsdance.bytecloud import ByteCloudClient
|
|
3
2
|
from dtsdance.tcc_open import TCCClient
|
|
4
3
|
from dtsdance.tcc_inner import TCCInnerClient
|
|
4
|
+
from config import ConfigLoader
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
loader = ConfigLoader.get_instance()
|
|
7
|
+
loader.load_from_file(["boe"])
|
|
8
|
+
site_configs = loader.get_site_configs()
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
# pytest tests/test_tcc.py::test_get_config -s
|
|
12
12
|
def test_get_config():
|
|
13
13
|
site_info = site_configs["boe"]
|
|
14
14
|
client_open = TCCClient(site_info.svc_account, site_info.svc_secret, endpoint=site_info.endpoint)
|
|
15
|
-
config_ctrl_env = client_open.get_config(ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="
|
|
15
|
+
config_ctrl_env = client_open.get_config(ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="ctrl_env")
|
|
16
16
|
print(f"ctrl_env: {config_ctrl_env}")
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
# pytest tests/test_tcc.py::test_list_configs -s
|
|
20
20
|
def test_list_configs():
|
|
21
|
-
|
|
21
|
+
bytecloud_client = ByteCloudClient(False, site_configs)
|
|
22
|
+
client_inner = TCCInnerClient(bytecloud_client)
|
|
23
|
+
configs = client_inner.list_configs(site="boe", ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="ctrl_env")
|
|
22
24
|
print(f"configs: {configs}")
|
|
@@ -4,30 +4,30 @@ requires-python = ">=3.12"
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "boto3"
|
|
7
|
-
version = "1.42.
|
|
7
|
+
version = "1.42.29"
|
|
8
8
|
source = { registry = "https://pypi.org/simple" }
|
|
9
9
|
dependencies = [
|
|
10
10
|
{ name = "botocore" },
|
|
11
11
|
{ name = "jmespath" },
|
|
12
12
|
{ name = "s3transfer" },
|
|
13
13
|
]
|
|
14
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
14
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5c/24/1dd85b64004103c2e60476d0fa8d78435f5fed9db1129cd2cd332784037a/boto3-1.42.29.tar.gz", hash = "sha256:247e54f24116ad6792cfc14b274288383af3ec3433b0547da8a14a8bd6e81950", size = 112810, upload-time = "2026-01-15T20:36:39.404Z" }
|
|
15
15
|
wheels = [
|
|
16
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
16
|
+
{ url = "https://files.pythonhosted.org/packages/51/30/2c25d7be8418e7f137ffece6097c68199dbd6996da645ec9b5a5a9647123/boto3-1.42.29-py3-none-any.whl", hash = "sha256:6c9c4dece67bf72d82ba7dff48e33a56a87cdf9b16c8887f88ca7789a95d3317", size = 140574, upload-time = "2026-01-15T20:36:37.206Z" },
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
[[package]]
|
|
20
20
|
name = "botocore"
|
|
21
|
-
version = "1.42.
|
|
21
|
+
version = "1.42.29"
|
|
22
22
|
source = { registry = "https://pypi.org/simple" }
|
|
23
23
|
dependencies = [
|
|
24
24
|
{ name = "jmespath" },
|
|
25
25
|
{ name = "python-dateutil" },
|
|
26
26
|
{ name = "urllib3" },
|
|
27
27
|
]
|
|
28
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
28
|
+
sdist = { url = "https://files.pythonhosted.org/packages/70/08/8a8e0255949845f764c5126f97b1bc09a6484077f124c2177b979ecfbbff/botocore-1.42.29.tar.gz", hash = "sha256:0fe869227a1dfe818f691a31b8c1693e39be8056a6dff5d6d4b3fc5b3a5e7d42", size = 14890916, upload-time = "2026-01-15T20:36:28.241Z" }
|
|
29
29
|
wheels = [
|
|
30
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
30
|
+
{ url = "https://files.pythonhosted.org/packages/94/76/cfa6a934ee5a8a87f626b38275193a046da894d2f9021e001587fc2e8c7d/botocore-1.42.29-py3-none-any.whl", hash = "sha256:b45f8dfc1de5106a9d040c5612f267582e68b2b2c5237477dff85c707c1c5d11", size = 14563947, upload-time = "2026-01-15T20:36:23.828Z" },
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[[package]]
|
|
@@ -107,7 +107,7 @@ wheels = [
|
|
|
107
107
|
|
|
108
108
|
[[package]]
|
|
109
109
|
name = "dts-dance"
|
|
110
|
-
version = "0.2.
|
|
110
|
+
version = "0.2.2"
|
|
111
111
|
source = { editable = "." }
|
|
112
112
|
dependencies = [
|
|
113
113
|
{ name = "boto3" },
|
|
@@ -118,7 +118,7 @@ dependencies = [
|
|
|
118
118
|
|
|
119
119
|
[package.metadata]
|
|
120
120
|
requires-dist = [
|
|
121
|
-
{ name = "boto3", specifier = ">=1.42.
|
|
121
|
+
{ name = "boto3", specifier = ">=1.42.29,<2.0.0" },
|
|
122
122
|
{ name = "loguru", specifier = ">=0.7.3,<0.8.0" },
|
|
123
123
|
{ name = "pyyaml", specifier = ">=6.0.3,<7.0.0" },
|
|
124
124
|
{ name = "requests", specifier = ">=2.32.5,<3.0.0" },
|
dts_dance-0.2.1/tests/config.py
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Any
|
|
3
|
-
import yaml
|
|
4
|
-
from dtsdance.bytecloud import SiteConfig
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def load_site_configs(sites: list[str] | None = None) -> dict[str, SiteConfig]:
|
|
8
|
-
"""从配置文件加载配置
|
|
9
|
-
|
|
10
|
-
Returns:
|
|
11
|
-
dict[str, Any]: 应用配置字典
|
|
12
|
-
|
|
13
|
-
Raises:
|
|
14
|
-
ValueError: 配置文件加载错误
|
|
15
|
-
"""
|
|
16
|
-
config_path = os.environ.get("CONFIG_PATH", "config.yaml")
|
|
17
|
-
|
|
18
|
-
configs: dict[str, Any] = {}
|
|
19
|
-
try:
|
|
20
|
-
with open(config_path, "r", encoding="utf-8") as f:
|
|
21
|
-
configs = yaml.safe_load(f)
|
|
22
|
-
|
|
23
|
-
except Exception as e:
|
|
24
|
-
raise ValueError(f"加载配置失败: {e}")
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
k: SiteConfig(k, v["endpoint"], v["svc_account"], v["svc_secret"], v.get("endpoint_bytedts_spacex", None))
|
|
28
|
-
for k, v in configs["sites"].items()
|
|
29
|
-
if k in sites
|
|
30
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|