摘要
腾讯云对象存储的API非常诡异, 缺胳膊少腿的, 而且会有一些没有文档说明的隐式行为, 很容易把用户逼疯.
下面是一个例子:
你启用COS bucket的多AZ特性的时候, 腾讯云会默认启用版本控制.
启用版本控制有可能大幅度增加你的成本.
你很难找出版本控制开启的真正原因, 因为腾讯云不提供get bucket API
你如果强行关闭版本控制, 你会得到一个异常.
腾讯云COS的抛给你的错误信息基本是自言自语, 就没想让你读懂.
如果您有兴趣, 可以阅读和运行我下面的示例代码.
顺便说一句, 腾讯的SDK范例里把secret_id和secret_id硬编码到代码中, 这是非常不规范的做法, 请大家不要学习他们, 不然很容易被人拖库.
被拖库的范例:
https://cloud.tencent.com/document/product/436/12269
从入门到放弃的范例:
#!/usr/bin/env python3
# -*- coding=utf-8
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import os
secret_id = os.getenv('COS_SECRET_ID') # 从环境变量读取 secretId, 不要硬编码
secret_key = os.getenv('COS_SECRET_KEY') # 从环境变量读取 secretKey, 不要硬编码
config = CosConfig(Region='ap-beijing', SecretId=secret_id, SecretKey=secret_key)
client = CosS3Client(config)
bucket_name = "multiple-azs-test-1314392898"
# 这个创建bucket的函数是瑞典马工写的, 他坚持所有bucket都要多AZ.
# 因为他害怕出现2022年12月18日阿里云香港那种故障
# 参见 https://mp.weixin.qq.com/s/bRCDNpnikpexKyR7FBNXpA
def create_a_file_container(name, enabled_versioning):
client.create_bucket(
Bucket=name,
# 只要你开启了多AZ, 腾讯云会隐式的开启版本控制
# 但是腾讯云文档完全不提这个行为, 马工不知道, 你也不知道, 只有天知, 地知, 腾讯知
# 参见 https://cloud.tencent.com/document/product/436/40548
BucketAZConfig= 'MAZ'
)
# 你和马工都以为版本在这里控制, 但是你们都错了
if enabled_versioning:
client.put_bucket_versioning(
Bucket=bucket_name,
Status='Enabled'
)
def main():
try:
# 你调用了马工的函数, 指定enabled_versioning = False
# 你看了马工的代码, 确实不会调用put_bucket_versioning
# 你确信版本是关闭的
create_a_file_container(bucket_name, False)
# 程序运行过程中, 版本控制是开启的, 费用比你预计的高很多
# 你开始怀疑自己的智商
# 你检查到bucket确实开启了版本控制, 你开始怀疑马工的人品
response = client.get_bucket_versioning(
Bucket=bucket_name
)
print(response)
# 你和马工吵一架, 他又给你看了他的代码, 确实没有调用put_bucket_versioning, 你吵输了.
# 你花了三个小时Google到 https://registry.terraform.io/providers/tencentcloudstack/tencentcloud/latest/docs/resources/cos_bucket#multi_az
# 你怀疑你的bucket是多AZ的, 所以腾讯云默认打开了版本控制, 但是你没法确认
# 因为腾讯不提供一个查询bucket信息的API, head_bucket这个API返回一个None
response = client.head_bucket(
Bucket=bucket_name
)
print(response)
try:
# 你不管了, 打算强制关闭版本控制
response = client.put_bucket_versioning(
Bucket=bucket_name,
Status='Suspended'
)
except Exception as err:
# 但是腾讯云给你抛了个异常, 你很愤怒
# 你把错误信息打印出来, 只看到一句不知所云的 "The request is not valid with the current state of the bucket."
print(err)
except Exception as err:
print(err)
finally:
# 你崩溃了, 你删了bucket, 永远的离开了腾讯云
response = client.delete_bucket(
Bucket=bucket_name
)
print('全剧终')
main()