#!/usr/bin/env python3
"""目标 OSS 桶的保护设置:读取状态,或开启版本控制 / 跨区域复制检查。
只处理目标环境的桶(secrets/release-sim 下的 key 文件),凭据不打印。
用法:
python3 scripts/oss_bucket_settings.py status # 版本控制 / 复制 / 生命周期
python3 scripts/oss_bucket_settings.py enable-versioning # 写操作:开启版本控制
"""
import base64
import hashlib
import hmac
import pathlib
import sys
import urllib.error
import urllib.request
from email.utils import formatdate
ROOT = pathlib.Path(__file__).resolve().parents[1]
SECRETS = ROOT / "secrets" / "release-sim"
BUCKET = "dobot-weknora-test"
ENDPOINT = "oss-cn-shenzhen.aliyuncs.com"
def read_secret(name):
return (SECRETS / name).read_text().strip()
def request(method, subresource, body=""):
access_key = read_secret("target_object_access_key")
secret_key = read_secret("target_object_secret_key")
date = formatdate(usegmt=True)
content_type = "application/xml" if body else ""
canonical = f"/{BUCKET}/?{subresource}"
string_to_sign = f"{method}\n\n{content_type}\n{date}\n{canonical}"
signature = base64.b64encode(
hmac.new(secret_key.encode(), string_to_sign.encode(), hashlib.sha1).digest()
).decode()
headers = {"Date": date, "Authorization": f"OSS {access_key}:{signature}"}
if content_type:
headers["Content-Type"] = content_type
http_request = urllib.request.Request(
f"https://{BUCKET}.{ENDPOINT}/?{subresource}",
data=body.encode() if body else None, headers=headers, method=method)
try:
with urllib.request.urlopen(http_request, timeout=20) as response:
return response.status, response.read().decode("utf-8", "replace")
except urllib.error.HTTPError as error:
return error.code, error.read().decode("utf-8", "replace")
def versioning_state():
status, body = request("GET", "versioning")
if status != 200:
return f"HTTP {status}"
return "Enabled" if "Enabled" in body else "Disabled(未开启)"
def main():
action = sys.argv[1] if len(sys.argv) > 1 else "status"
if action == "status":
print("versioning:", versioning_state())
for name in ("replication", "lifecycle"):
status, body = request("GET", name)
summary = "none" if status == 404 else " ".join(body.split())[:120]
print(f"{name}: HTTP {status} {summary}")
return
if action == "enable-versioning":
print("before:", versioning_state())
body = "Enabled"
status, response = request("PUT", "versioning", body)
print("PUT versioning:", f"HTTP {status}", " ".join(response.split())[:160])
print("after:", versioning_state())
return
print("unknown action:", action, file=sys.stderr)
sys.exit(2)
if __name__ == "__main__":
main()