Skip to content

Commit 0a1b6e8

Browse files
committed
add auto fetch nacos token
1 parent 5b099fb commit 0a1b6e8

File tree

5 files changed

+190
-27
lines changed

5 files changed

+190
-27
lines changed

config.yaml.full

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ database:
151151
region: cn-beijing # default Volcengine TOS Vector region
152152
bucket:
153153
account_id:
154-
154+
155+
# Dynamic config
156+
nacos:
157+
endpoint:
158+
password:
155159

156160

157161
# [optional] for prompt optimization in cli/app

veadk/auth/veauth/mse_veauth.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
from veadk.auth.veauth.utils import get_credential_from_vefaas_iam
18+
from veadk.configs.database_configs import MSENacosConfig
19+
from veadk.utils.logger import get_logger
20+
from veadk.utils.volcengine_sign import ve_request
21+
22+
logger = get_logger(__name__)
23+
24+
25+
def get_instance_id_by_name(instance_name: str, region: str, project_name: str) -> str:
26+
logger.info(f"Fetching MSE Nacos instance id by instance name {instance_name} ...")
27+
28+
access_key = os.getenv("VOLCENGINE_ACCESS_KEY")
29+
secret_key = os.getenv("VOLCENGINE_SECRET_KEY")
30+
session_token = ""
31+
32+
if not (access_key and secret_key):
33+
# try to get from vefaas iam
34+
cred = get_credential_from_vefaas_iam()
35+
access_key = cred.access_key_id
36+
secret_key = cred.secret_access_key
37+
session_token = cred.session_token
38+
39+
res = ve_request(
40+
request_body={
41+
"Filter": {"Status": [], "ProjectName": project_name},
42+
"PageNumber": 1,
43+
"PageSize": 10,
44+
"ProjectName": project_name,
45+
},
46+
header={"X-Security-Token": session_token},
47+
action="ListNacosRegistries",
48+
ak=access_key,
49+
sk=secret_key,
50+
service="mse",
51+
version="2022-01-01",
52+
region=region,
53+
host="open.volcengineapi.com",
54+
)
55+
56+
try:
57+
for item in res["Result"]["Items"]:
58+
if item["Name"] == instance_name:
59+
logger.info(
60+
f"Found MSE Nacos instance id {item['Id']} by instance name {instance_name}"
61+
)
62+
return item["Id"]
63+
raise ValueError(f"Id by instance name {instance_name} not found: {res}")
64+
except Exception as e:
65+
logger.error(
66+
f"Failed to get MSE Nacos instance id by name {instance_name}: {e}, response: {res}"
67+
)
68+
raise e
69+
70+
71+
def get_mse_cridential(
72+
instance_name: str,
73+
region: str = "cn-beijing",
74+
project_name: str = "default",
75+
) -> MSENacosConfig:
76+
logger.info("Fetching MSE Nacos token...")
77+
78+
access_key = os.getenv("VOLCENGINE_ACCESS_KEY")
79+
secret_key = os.getenv("VOLCENGINE_SECRET_KEY")
80+
session_token = ""
81+
82+
if not (access_key and secret_key):
83+
# try to get from vefaas iam
84+
cred = get_credential_from_vefaas_iam()
85+
access_key = cred.access_key_id
86+
secret_key = cred.secret_access_key
87+
session_token = cred.session_token
88+
89+
instance_id = get_instance_id_by_name(
90+
instance_name=instance_name, region=region, project_name=project_name
91+
)
92+
93+
res = ve_request(
94+
request_body={
95+
"Id": instance_id,
96+
"ProjectName": project_name,
97+
},
98+
header={"X-Security-Token": session_token},
99+
action="GetNacosRegistry",
100+
ak=access_key,
101+
sk=secret_key,
102+
service="mse",
103+
version="2022-01-01",
104+
region=region,
105+
host="open.volcengineapi.com",
106+
)
107+
108+
try:
109+
logger.info(
110+
f"Successfully fetched MSE Nacos endpoint {res['Result']['NacosRegistry']['PublicAddress']} and corresponding password."
111+
)
112+
return MSENacosConfig(
113+
endpoint=res["Result"]["NacosRegistry"]["PublicAddress"],
114+
password=res["Result"]["NacosRegistry"]["InitialPassword"],
115+
)
116+
except Exception as e:
117+
logger.error(f"Failed to get MSE Nacos token: {e}, response: {res}")
118+
raise e

veadk/configs/database_configs.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,13 @@ class TOSVectorConfig(BaseSettings):
178178
user_agent_soft_version: str | None = None
179179

180180
user_agent_customized_key_values: dict[str, str] | None = None
181+
182+
183+
class MSENacosConfig(BaseSettings):
184+
model_config = SettingsConfigDict(env_prefix="NACOS_")
185+
186+
endpoint: str
187+
port: str = "8848" # hard coding by Volcengine MSE Nacos service
188+
189+
username: str = "nacos" # hard coding by Volcengine MSE Nacos service
190+
password: str

veadk/configs/dynamic_config_manager.py

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from v2.nacos.config.model.config_param import ConfigParam
2020

2121
from veadk.agent import Agent
22-
from veadk.consts import DEFAULT_NACOS_GROUP
22+
from veadk.auth.veauth.mse_veauth import get_mse_cridential
23+
from veadk.consts import DEFAULT_NACOS_GROUP, DEFAULT_NACOS_INSTANCE_NAME
2324
from veadk.utils.logger import get_logger
2425

2526
logger = get_logger(__name__)
@@ -30,57 +31,86 @@ class DynamicConfigManager:
3031
DynamicConfigManager is responsible for creating and publishing dynamic config to nacos.
3132
"""
3233

33-
def __init__(self, agents: list[Agent] | Agent, app_name: str = ""):
34+
def __init__(
35+
self,
36+
agents: list[Agent] | Agent,
37+
):
3438
"""
3539
Initialize DynamicConfigManager with agents and app_name.
3640
3741
Args:
3842
agents (list[Agent] | Agent): The agent(s) to be included in the dynamic config.
39-
app_name (str): The name of the application, used as the Nacos group id. Defaults to DEFAULT_NACOS_GROUP.
4043
"""
4144
if isinstance(agents, list):
4245
self.agents = agents
4346
else:
4447
self.agents = [agents]
4548

46-
if not app_name:
49+
logger.debug(f"DynamicConfigManager init with {len(self.agents)} agent(s).")
50+
51+
async def create_config(
52+
self,
53+
configs: dict = {},
54+
instance_name: str = "",
55+
group_id: str = "",
56+
):
57+
if not instance_name:
4758
logger.warning(
48-
f"app_name is not provided, use default value {DEFAULT_NACOS_GROUP}. This may lead to unexpected behavior such as configuration override."
59+
f"instance_name is not provided, use default value `{DEFAULT_NACOS_INSTANCE_NAME}`. This may lead to unexpected behavior such as configuration override."
4960
)
50-
self.app_name = app_name or DEFAULT_NACOS_GROUP
61+
instance_name = DEFAULT_NACOS_INSTANCE_NAME
5162

52-
logger.debug(
53-
f"DynamicConfigManager init with {len(self.agents)} agent(s) for app {self.app_name}"
54-
)
63+
if not group_id:
64+
logger.warning(
65+
f"group_id is not provided, use default value `{DEFAULT_NACOS_GROUP}`. This may lead to unexpected behavior such as configuration override."
66+
)
67+
group_id = group_id or DEFAULT_NACOS_GROUP
68+
69+
nacos_endpoint = os.getenv("NACOS_ENDPOINT")
70+
nacos_port = os.getenv("NACOS_PORT", "8848")
71+
nacos_username = os.getenv("NACOS_USERNAME", "nacos")
72+
nacos_password = os.getenv("NACOS_PASSWORD")
73+
74+
if not all([nacos_endpoint, nacos_port, nacos_username, nacos_password]):
75+
logger.warning(
76+
"fetch NACOS_ENDPOINT, NACOS_PORT, NACOS_USERNAME, and NACOS_PASSWORD from env failed, try to get by volcengine AK/SK."
77+
)
78+
79+
nacos_credentials = get_mse_cridential(instance_name=instance_name)
80+
nacos_endpoint = nacos_credentials.endpoint
81+
nacos_port = nacos_credentials.port
82+
nacos_username = nacos_credentials.username
83+
nacos_password = nacos_credentials.password
5584

56-
async def create_config(self, config: dict = {}):
5785
client_config = ClientConfig(
58-
server_addresses=os.getenv("NACOS_SERVER_ADDRESSES"),
86+
server_addresses=f"{nacos_endpoint}:{nacos_port}",
5987
namespace_id="",
60-
username=os.getenv("NACOS_USERNAME"),
61-
password=os.getenv("NACOS_PASSWORD"),
88+
username=nacos_username,
89+
password=nacos_password,
6290
)
6391

6492
config_client = await NacosConfigService.create_config_service(
6593
client_config=client_config
6694
)
6795

68-
configs = {
69-
"agent": [
70-
{
71-
"id": agent.id,
72-
"name": agent.name,
73-
"description": agent.description,
74-
"model_name": agent.model_name,
75-
"instruction": agent.instruction,
76-
}
77-
for agent in self.agents
78-
]
79-
}
96+
if not configs:
97+
logger.info("user config_dict is empty, use default config instead.")
98+
configs = {
99+
"agent": [
100+
{
101+
"id": agent.id,
102+
"name": agent.name,
103+
"description": agent.description,
104+
"model_name": agent.model_name,
105+
"instruction": agent.instruction,
106+
}
107+
for agent in self.agents
108+
]
109+
}
80110
response = await config_client.publish_config(
81111
param=ConfigParam(
82112
data_id="veadk",
83-
group=self.app_name,
113+
group=group_id,
84114
type="json",
85115
content=json.dumps(configs),
86116
)

veadk/consts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@
7474
VEFAAS_IAM_CRIDENTIAL_PATH = "/var/run/secrets/iam/credential"
7575

7676
DEFAULT_NACOS_GROUP = "VEADK_GROUP"
77+
DEFAULT_NACOS_INSTANCE_NAME = "veadk"

0 commit comments

Comments
 (0)