fix: harden tat ops scripts
This commit is contained in:
parent
c60a546246
commit
bfe41148d8
@ -6,8 +6,10 @@ import base64
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Callable, TypeVar
|
||||||
|
|
||||||
from tencentcloud.common import credential
|
from tencentcloud.common import credential
|
||||||
|
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
|
||||||
from tencentcloud.common.profile.client_profile import ClientProfile
|
from tencentcloud.common.profile.client_profile import ClientProfile
|
||||||
from tencentcloud.common.profile.http_profile import HttpProfile
|
from tencentcloud.common.profile.http_profile import HttpProfile
|
||||||
from tencentcloud.tat.v20201028 import models as tat_models, tat_client
|
from tencentcloud.tat.v20201028 import models as tat_models, tat_client
|
||||||
@ -19,6 +21,7 @@ DEFAULT_REPO_URL = os.environ.get("MONITOR_REPO_URL", "git@gitea.haiyihy.com:hy/
|
|||||||
DEFAULT_REPO_REF = os.environ.get("MONITOR_REPO_REF", "main")
|
DEFAULT_REPO_REF = os.environ.get("MONITOR_REPO_REF", "main")
|
||||||
DEFAULT_REMOTE_DIR = os.environ.get("MONITOR_REMOTE_DIR", "/opt/hy-app-monitor")
|
DEFAULT_REMOTE_DIR = os.environ.get("MONITOR_REMOTE_DIR", "/opt/hy-app-monitor")
|
||||||
DEFAULT_APP_PORT = os.environ.get("APP_PORT", "6666")
|
DEFAULT_APP_PORT = os.environ.get("APP_PORT", "6666")
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
def env_required(name: str) -> str:
|
def env_required(name: str) -> str:
|
||||||
@ -37,6 +40,21 @@ def build_tat(secret_id: str, secret_key: str, region: str) -> tat_client.TatCli
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(action: Callable[[], T], label: str, retries: int = 4, delay_seconds: int = 2) -> T:
|
||||||
|
last_error: Exception | None = None
|
||||||
|
for attempt in range(1, retries + 1):
|
||||||
|
try:
|
||||||
|
return action()
|
||||||
|
except TencentCloudSDKException as exc:
|
||||||
|
last_error = exc
|
||||||
|
if attempt == retries:
|
||||||
|
break
|
||||||
|
time.sleep(delay_seconds * attempt)
|
||||||
|
if last_error is not None:
|
||||||
|
raise last_error
|
||||||
|
raise RuntimeError(f"{label} failed without error")
|
||||||
|
|
||||||
|
|
||||||
def remote_script(repo_url: str, repo_ref: str, remote_dir: str, app_port: str) -> str:
|
def remote_script(repo_url: str, repo_ref: str, remote_dir: str, app_port: str) -> str:
|
||||||
return f"""set -euo pipefail
|
return f"""set -euo pipefail
|
||||||
|
|
||||||
@ -80,7 +98,7 @@ def run_tat_script(client: tat_client.TatClient, instance_id: str, script: str,
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
resp = json.loads(client.RunCommand(req).to_json_string())
|
resp = json.loads(invoke(lambda: client.RunCommand(req), "RunCommand").to_json_string())
|
||||||
invocation_id = resp["InvocationId"]
|
invocation_id = resp["InvocationId"]
|
||||||
deadline = time.time() + timeout_seconds + 120
|
deadline = time.time() + timeout_seconds + 120
|
||||||
|
|
||||||
@ -96,7 +114,7 @@ def run_tat_script(client: tat_client.TatClient, instance_id: str, script: str,
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
data = json.loads(client.DescribeInvocationTasks(query).to_json_string())
|
data = json.loads(invoke(lambda: client.DescribeInvocationTasks(query), "DescribeInvocationTasks").to_json_string())
|
||||||
tasks = data.get("InvocationTaskSet") or []
|
tasks = data.get("InvocationTaskSet") or []
|
||||||
if not tasks:
|
if not tasks:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@ -7,8 +7,10 @@ import json
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Callable, TypeVar
|
||||||
|
|
||||||
from tencentcloud.common import credential
|
from tencentcloud.common import credential
|
||||||
|
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
|
||||||
from tencentcloud.common.profile.client_profile import ClientProfile
|
from tencentcloud.common.profile.client_profile import ClientProfile
|
||||||
from tencentcloud.common.profile.http_profile import HttpProfile
|
from tencentcloud.common.profile.http_profile import HttpProfile
|
||||||
from tencentcloud.cvm.v20170312 import cvm_client, models as cvm_models
|
from tencentcloud.cvm.v20170312 import cvm_client, models as cvm_models
|
||||||
@ -20,6 +22,7 @@ DEFAULT_INSTANCE_ID = os.environ.get("DEPLOY_INSTANCE_ID", "ins-ntmpcd3a")
|
|||||||
DEFAULT_REGION = os.environ.get("DEPLOY_REGION", "me-saudi-arabia")
|
DEFAULT_REGION = os.environ.get("DEPLOY_REGION", "me-saudi-arabia")
|
||||||
DEFAULT_PORT = int(os.environ.get("OPEN_PORT", "6666"))
|
DEFAULT_PORT = int(os.environ.get("OPEN_PORT", "6666"))
|
||||||
DEFAULT_CIDR = os.environ.get("OPEN_CIDR", "0.0.0.0/0")
|
DEFAULT_CIDR = os.environ.get("OPEN_CIDR", "0.0.0.0/0")
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
def env_required(name: str) -> str:
|
def env_required(name: str) -> str:
|
||||||
@ -47,10 +50,25 @@ def build_tat(secret_id: str, secret_key: str, region: str) -> tat_client.TatCli
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(action: Callable[[], T], label: str, retries: int = 4, delay_seconds: int = 2) -> T:
|
||||||
|
last_error: Exception | None = None
|
||||||
|
for attempt in range(1, retries + 1):
|
||||||
|
try:
|
||||||
|
return action()
|
||||||
|
except TencentCloudSDKException as exc:
|
||||||
|
last_error = exc
|
||||||
|
if attempt == retries:
|
||||||
|
break
|
||||||
|
time.sleep(delay_seconds * attempt)
|
||||||
|
if last_error is not None:
|
||||||
|
raise last_error
|
||||||
|
raise RuntimeError(f"{label} failed without error")
|
||||||
|
|
||||||
|
|
||||||
def resolve_security_group_id(client: cvm_client.CvmClient, instance_id: str) -> str:
|
def resolve_security_group_id(client: cvm_client.CvmClient, instance_id: str) -> str:
|
||||||
req = cvm_models.DescribeInstancesRequest()
|
req = cvm_models.DescribeInstancesRequest()
|
||||||
req.from_json_string(json.dumps({"InstanceIds": [instance_id]}))
|
req.from_json_string(json.dumps({"InstanceIds": [instance_id]}))
|
||||||
resp = json.loads(client.DescribeInstances(req).to_json_string())
|
resp = json.loads(invoke(lambda: client.DescribeInstances(req), "DescribeInstances").to_json_string())
|
||||||
instances = resp.get("InstanceSet") or []
|
instances = resp.get("InstanceSet") or []
|
||||||
if not instances:
|
if not instances:
|
||||||
raise SystemExit(f"instance not found: {instance_id}")
|
raise SystemExit(f"instance not found: {instance_id}")
|
||||||
@ -105,7 +123,7 @@ client = vpc_client.VpcClient(
|
|||||||
ClientProfile(httpProfile=HttpProfile(endpoint='vpc.tencentcloudapi.com')),
|
ClientProfile(httpProfile=HttpProfile(endpoint='vpc.tencentcloudapi.com')),
|
||||||
)
|
)
|
||||||
|
|
||||||
req = models.AuthorizeSecurityGroupPoliciesRequest()
|
req = models.CreateSecurityGroupPoliciesRequest()
|
||||||
req.from_json_string(json.dumps({{
|
req.from_json_string(json.dumps({{
|
||||||
'SecurityGroupId': payload['security_group_id'],
|
'SecurityGroupId': payload['security_group_id'],
|
||||||
'SecurityGroupPolicySet': {{
|
'SecurityGroupPolicySet': {{
|
||||||
@ -120,7 +138,7 @@ req.from_json_string(json.dumps({{
|
|||||||
}}))
|
}}))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.AuthorizeSecurityGroupPolicies(req)
|
client.CreateSecurityGroupPolicies(req)
|
||||||
print('security_group_rule=created')
|
print('security_group_rule=created')
|
||||||
except TencentCloudSDKException as exc:
|
except TencentCloudSDKException as exc:
|
||||||
if 'Duplicate' in str(exc) or 'already exists' in str(exc):
|
if 'Duplicate' in str(exc) or 'already exists' in str(exc):
|
||||||
@ -147,7 +165,7 @@ def run_tat_script(client: tat_client.TatClient, instance_id: str, script: str,
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
resp = json.loads(client.RunCommand(req).to_json_string())
|
resp = json.loads(invoke(lambda: client.RunCommand(req), "RunCommand").to_json_string())
|
||||||
invocation_id = resp["InvocationId"]
|
invocation_id = resp["InvocationId"]
|
||||||
deadline = time.time() + timeout_seconds + 120
|
deadline = time.time() + timeout_seconds + 120
|
||||||
|
|
||||||
@ -163,7 +181,7 @@ def run_tat_script(client: tat_client.TatClient, instance_id: str, script: str,
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
data = json.loads(client.DescribeInvocationTasks(query).to_json_string())
|
data = json.loads(invoke(lambda: client.DescribeInvocationTasks(query), "DescribeInvocationTasks").to_json_string())
|
||||||
tasks = data.get("InvocationTaskSet") or []
|
tasks = data.get("InvocationTaskSet") or []
|
||||||
if not tasks:
|
if not tasks:
|
||||||
continue
|
continue
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user