对象锁定
对象锁定通过确保以 WORM (Write-Once-Read-many),不可擦除和不可重写的方式存储各个对象版本来保留电子记录并维护数据完整性。 在指定日期或除去任何合法保留之前,将实施此策略。
为何使用对象锁定?
对象锁定通过对客户的备份,灾难恢复和网络安全永续工作负载实施数据不可变性,帮助客户管理数据保留和保留需求。
对象锁定可确保任何人都无法删除 数据,并且 无法暂挂对象上的保留时间。 在锁定具有保留期的对象之前,请仔细阅读文档。
使用对象锁定时,您有责任确保遵守您 (您的组织) 在保存和存储数据以进行长期保留时可能遵守的任何法规。
使用 Object Lock 时,您有责任确保您的 IBM Cloud 帐户按照 IBM Cloud 的政策和指导方针保持良好状态,直至数据进入保留期。 有关更多信息,请参阅 IBM Cloud 服务条款。
术语
有两种方法使用“对象锁定”来保护数据: 保留期 和 合法保留。
- 保留期 定义无法修改或删除对象的时间范围。
- 合法保留 还会阻止更改对象,但只有在显式解除该对象之前才会保留该对象。
可以使用这些参数的任何组合-对象版本可以有一个,也可以有两个,也可以没有一个。
保留截止日期 (保留期)
如果需要在固定时间内保护对象版本,那么需要指定 保留截止日期,以确定无法变更对象版本的时间段。 通过此日期后,可以删除对象版本 (假定对象版本上没有合法保留)。
可以从存储区上设置的缺省值继承新对象的保留期,也可以在写入对象时通过指定 保留截止日期来显式定义新对象的保留期。
使用存储区缺省设置时,不会指定“保留截止日期”。 而是指定在存储区中放置的每个对象版本都应保护的持续时间 (以天或年为单位)。 在存储区中放置对象时,将通过将指定的持续时间与对象写入时间相加来计算对象版本的“保留截止日期”。
如果在存储区中放置对象版本的请求包含显式保留方式和“保留截止日期”,那么这些设置将覆盖该对象版本的任何存储区缺省设置。
与所有其他对象锁定设置一样,“保留截止日期”适用于各个对象版本。 单个对象的不同版本可以具有不同的保留方式和周期。
想象一个 60 天进入 90 天保留期的对象,你用相同的名称和两年的保留期覆盖那个对象。 操作将成功,并且将创建具有两年保留期的新对象版本。 同时,再过 30 天,原版才有资格删除。
延长保留期
要延长对象的保留期,只需发送请求以设置新的,较长的保留期。 旧值将被新值覆盖,假定请求者具有 cloud-object-storage.object.put_object_lock_retention
和 cloud-object-storage.object.put_object_lock_retention_version
操作。
合法保留
合法保留 类似于保留期,因为它可防止对象版本被覆盖或删除。 但是,法律保留更灵活,并且没有定义的时间部分。 相反,它们只是保持有效,直到移除为止。 具有 cloud-object-storage.object.put_object_lock_legal_hold
和 cloud-object-storage.object.put_object_lock_legal_hold_version
操作的任何用户都可以自由放置和除去合法保留。
法律保留具有作为对对象应用无限期保留的方法的额外好处。
法律保留期和保留期独立运作。 法律保留对保留期没有影响,反之亦然。
想象一个既有合法持有又有保留期的对象。 当保留期结束时,对象版本将保持受保护状态,直到除去合法保留为止。 如果在对象版本受保留期约束时除去合法保留,那么该保留期将一直受保护,直到保留期完成为止。
在保留期到期并除去任何关联的合法保留之前,无法删除使用保留期锁定和存储的对象。
不支持使用“监管方式”锁定对象。
开始使用对象锁定
首先,需要满足一些先决条件:
- 您将需要存储区上的
Writer
或Manager
平台角色,或者需要分配了相应操作 (例如cloud-object-storage.bucket.put_object_lock_configuration
) 的定制角色。 - 必须启用对象版本控制
- 您将需要使用标准定价套餐,请参阅 定价 以获取详细信息。
- 您将需要选取支持对象锁定的区域,请参阅 集成服务 以获取详细信息。
- 支持最大缺省保留期 100 年 (或 36500 天)。
- 使用控制台时,除了天数或年数外,还可以设置“保留截止日期”(以月计)。
无法减少对象 的保留期。 如果要使用缺省保留时间进行验证测试,请使用较短的持续时间 (例如 1 天) 作为缺省保留时间,根据需要将其增大到所需的设置。
创建和设置新存储区以用于对象锁定
- 浏览至所需的 Object Storage 实例,并使用 创建存储区 和 定制存储区选项
- 根据您的用例需求输入所需的存储区配置详细信息
- 浏览至 对象版本控制 部分,并将其设置为 已启用
- 查找 不变性,然后在“对象锁定”下单击 添加
- 将对象锁定设置为 已启用
- (可选) 设置缺省保留期。
- 单击“保存”
- 继续执行其余配置设置,然后单击 创建存储区
对现有存储区启用对象锁定:
可以设置存储区以供对象锁定使用,如下所示:
- 浏览至存储区 配置 部分
- 单击 对象版本控制
- 在 对象版本控制 部分单击 编辑,将配置选项设置为 已启用 并 保存
- 浏览至 对象锁定 部分,单击 添加
- 将 对象锁定 设置为 已启用
- (可选) 设置缺省保留期。
- 点击保存
向对象添加“保留截止日期”或“法律保留”
- 使用目标对象浏览到存储区
- 切换 显示版本
- 转至目标版本的详细信息
- 添加保留期和/或对法律保留进行切换。
使用对象锁定实现业务连续性和灾难恢复
对象锁定可用于在发生勒索软件攻击时提供服务的连续性,因为受保护的数据无法修改或销毁。
一致性和数据完整性
虽然 IBM Cloud Object Storage 为所有数据 IO 操作提供了强大的一致性,但数据桶配置最终是一致的。 在存储区上启用,修改或删除缺省保留期之后,配置可能需要一些时间才能在系统中传播。 对对象的操作 (例如,添加合法保留) 立即一致。
使用情况和会计
锁定的对象 (及其版本) 与任何其他数据一样提供使用情况,只要对象在保留期内保持锁定状态,您将负责 使用成本。
交互
根据您的用例需求,对象锁定可与多个对象存储功能组合使用。
版本控制
启用版本控制 是启用对象锁定的先决条件。 如果使用 x-amz-bucket-object-lock-enabled
头创建存储区,那么将自动启用版本控制。
删除版本化对象将创建 删除标记。 该对象可能看起来已被删除,但如果该对象受保护,那么无法删除受保护的版本。 删除标记本身不受保护。
复制
对象锁定 不能在源存储区 上用于复制,只能在目标上使用。 将为对象分配缺省保留期。
密钥管理系统
将使用存储区的根密钥对受保护对象进行加密。 在存储区上启用对象锁定时,只要关联的存储区启用了对象锁定,就会保护 Key Protect 或 Hyper Protect Crypto Services 所托管的根密钥不被删除。 这将防止加密粉碎受保护对象。
生命周期配置
可以启用 归档锁定对象 的生命周期策略,但自然不会启用保留或合法保留下的 到期对象 (存储区中未受保护的对象仍可能到期) 的生命周期策略。
不可变对象存储器
对象锁定是使用不可变 Object Storage时可用的保留时间策略的替代方法。 由于对象锁定需要启用版本控制,并且不可变 Object Storage 与版本控制不兼容,因此无法在同一存储区上同时启用这两个 WORM 解决方案。 可以在服务实例中混用存储区,每个存储区都使用不可变的 Object Storage 或对象锁定。
对象标记
在受保护对象上添加或修改标记没有任何限制。
其他交互
将对象锁定与其他 Object Storage 功能 (例如,设置 CORS 策略,设置 IP 防火墙或基于条件的限制,存储区配额或 Code Engine) 配合使用时,不应存在任何不利的交互。
IAM 操作
存在与对象锁定关联的新 IAM 操作。
IAM 操作 | 角色 |
---|---|
cloud-object-storage.bucket.get_object_lock_configuration |
管理者、写入者和读取者 |
cloud-object-storage.bucket.put_object_lock_configuration |
管理者和写入者 |
cloud-object-storage.object.get_object_lock_retention |
管理者、写入者和读取者 |
cloud-object-storage.object.put_object_lock_retention |
管理者和写入者 |
cloud-object-storage.object.get_object_lock_retention_version |
管理者、写入者和读取者 |
cloud-object-storage.object.put_object_lock_retention_version |
管理者和写入者 |
cloud-object-storage.object.get_object_lock_legal_hold |
管理者、写入者和读取者 |
cloud-object-storage.object.put_object_lock_legal_hold |
管理者和写入者 |
cloud-object-storage.object.get_object_lock_legal_hold_version |
管理者、写入者和读取者 |
cloud-object-storage.object.put_object_lock_legal_hold_version |
管理者和写入者 |
请注意,具有“写入者”角色的用户能够使对象在许多年 (可能是数千年) 内不可删除。 请小心,并考虑创建不允许大多数用户设置“保留截止日期”的定制角色。
Activity Tracker 事件
对象锁定将生成其他事件。
cloud-object-storage.bucket-object-lock.create
cloud-object-storage.bucket-object-lock.read
cloud-object-storage.object-object-lock-legal-hold.create
cloud-object-storage.object-object-lock-legal-hold.read
cloud-object-storage.object-object-lock-retention.create
cloud-object-storage.object-object-lock-retention.read
对于 cloud-object-storage.bucket-object-lock.create
事件,以下字段提供额外的信息:
字段 | 描述 |
---|---|
requestData.object_lock_configuration.enabled |
指示已在存储区上启用对象锁定 |
requestData.object_lock_configuration.defaultRetention.mode |
指示 COMPLIANCE 方式处于活动状态-尚不支持 GOVERNANCE 方式。 |
object_lock_configuration.defaultRetention.years |
缺省保留期 (年)。 |
object_lock_configuration.defaultRetention.days |
缺省保留期 (以天计)。 |
将仅显示 object_lock_configuration.defaultRetention.years
或 object_lock_configuration.defaultRetention.days
,但不能同时显示两者。
对于对受保护对象的操作,可能存在以下字段:
字段 | 描述 |
---|---|
requestData.object_lock_protection.legal_hold |
指示对象版本上存在有效的法律保留。 |
requestData.object_lock_protection.retention.mode |
指示 COMPLIANCE 方式在对象版本上处于活动状态-尚不支持 GOVERNANCE 方式。 |
requestData.object_lock_protection.retention.retain_until_date |
指示对象版本适合删除的日期。 在此日期之后,将不再根据保留日期删除受保护对象。 |
REST API 示例
使用 cURL 显示了以下示例以方便使用。 环境变量用于表示特定于用户的元素,例如 $BUCKET
,$TOKEN
和 $REGION
。 请注意,$REGION
还将包含任何网络类型规范,因此使用专用网络向 us-south
中的存储区发送请求将需要将变量设置为 private.us-south
。
在存储区上启用对象锁定
对象锁定配置在请求主体中以 XML 形式提供。 新请求将覆盖存储区上存在的任何现有复制规则。
对象锁定配置必须包含一条规则。
头 | Type | 描述 |
---|---|---|
Content-MD5 |
字符串 | 必需:有效内容的 Base64 编码的 128 位 MD5 散列,用作完整性检查,可确保有效内容在传输中未变更。 |
请求主体必须包含具有以下模式的 XML 块:
元素 | Type | 子代 | 祖代 | 约束 |
---|---|---|---|---|
ObjectLockConfiguration |
容器 | ObjectLockEnabled , Rule |
无 | 必需 限制 1。 |
ObjectLockEnabled |
字符串 | 无 | ObjectLockConfiguration |
必需 唯一有效值为 Enabled (区分大小写)。 |
Rule |
容器 | DefaultRetention |
ObjectLockConfiguration |
限制 1 |
DefaultRetention |
容器 | Days , Mode , Years |
Rule |
限制为 1。 |
Days |
整数 | 无 | DefaultRetention |
要为缺省保留期指定的天数。 无法与 Years 组合。 |
Mode |
字符串 | 无 | DefaultRetention |
目前只支持 COMPLIANCE (区分大小写)。 |
Years |
整数 | 无 | DefaultRetention |
要为缺省保留期指定的年数。 无法与 Days 组合。 |
此示例将保留任何新对象至少 30 天。
curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?object-lock" \
-H 'Authorization: bearer $TOKEN' \
-H 'Content-MD5: exuBoz2kFBykNwqu64JZuA==' \
-H 'Content-Type: text/plain; charset=utf-8' \
-d $'<ObjectLockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<ObjectLockEnabled>Enabled</ObjectLockEnabled>
<Rule>
<DefaultRetention>
<Days>30</Days>
<Mode>COMPLIANCE</Mode>
</DefaultRetention>
</Rule>
</ObjectLockConfiguration>'
成功的请求返回 200
响应。
查看水桶的对象锁配置
curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?object-lock" \
-H 'Authorization: bearer $TOKEN'
这将返回具有相应模式的 XML 响应主体:
<ObjectLockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<ObjectLockEnabled>string</ObjectLockEnabled>
<Rule>
<DefaultRetention>
<Days>30</Days>
<Mode>COMPLIANCE</Mode>
</DefaultRetention>
</Rule>
</ObjectLockConfiguration>
添加或延长对象的保留期
对象锁定配置在请求主体中以 XML 形式提供。 新请求将覆盖对象上存在的任何现有复制规则,前提是 RetainUntilDate
将来比当前值更远。
头 | Type | 描述 |
---|---|---|
Content-MD5 |
字符串 | 必需:有效内容的 Base64 编码的 128 位 MD5 散列,用作完整性检查,可确保有效内容在传输中未变更。 |
(可选) 可以指定要对其应用 RetainUntilDate
的版本。
可选查询参数
参数 | 必需? | Type | 描述 |
---|---|---|---|
versionID |
可选 | 字符串 | 版本标识。 |
请求主体必须包含具有以下模式的 XML 块:
元素 | Type | 子代 | 祖代 | 约束 |
---|---|---|---|---|
Retention |
容器 | Mode , RetainUntilDate |
无 | 必需 限制 1。 |
Mode |
字符串 | 无 | Retention |
此时仅支持必需 COMPLIANCE (区分大小写)。 |
RetainUntilDate |
字符串 | 无 | Retention |
必需 对象在 ISO8601 日期-时间格式中符合删除条件的日期。 |
此示例将至少在 2023 年 3 月 12 日之前保留任何新对象。
curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?retention" \
-H 'Authorization: Bearer $TOKEN' \
-H 'Content-MD5: fT0hYstki6zUvEh7abhcTA==' \
-H 'Content-Type: text/plain; charset=utf-8' \
-d $'<Retention>
<Mode>COMPLIANCE</Mode>
<RetainUntilDate>2023-03-12T23:01:00.000Z</RetainUntilDate>
</Retention>'
成功的请求返回 200
响应。
如果 RetainUntilDate
值未超出任何现有值,那么操作将失败并返回 403 Access Denied
。
添加或除去对象的合法保留
对象锁定配置在请求主体中以 XML 形式提供。 新请求将覆盖对象上存在的任何现有复制规则,前提是 RetainUntilDate
将来比当前值更远。
头 | Type | 描述 |
---|---|---|
Content-MD5 |
字符串 | 必需:有效内容的 Base64 编码的 128 位 MD5 散列,用作完整性检查,可确保有效内容在传输中未变更。 |
请求主体必须包含具有以下模式的 XML 块:
元素 | Type | 子代 | 祖代 | 约束 |
---|---|---|---|---|
legal-hold |
容器 | Status |
无 | 限制为 1。 |
Status |
字符串 | 无 | legal-hold |
受支持的值为 ON 或 OFF (区分大小写) |
此示例将至少在 2023 年 3 月 12 日之前保留任何新对象。
curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?legal-hold&versionId=$VERSION_ID" \
-H 'Authorization: Bearer $TOKEN' \
-H 'Content-MD5: FMh6GxizXUBRaiDuB0vtgQ==' \
-H 'Content-Type: text/plain; charset=utf-8' \
-d $'<legal-hold>
<Status>ON</Status>
</legal-hold>'
成功的请求返回 200
响应。
SDK 示例
以下示例使用 IBM COS SDK for Python,Node.js和 Go 以及 Terraform 脚本,尽管对象版本控制的实现应该与允许设置定制端点的任何 S3-compatible 库或工具完全兼容。 使用第三方工具需要 HMAC 凭证 来计算 AWS V4 签名。
Python
可以使用 低级客户机 语法来启用使用 IBM COS SDK for Python 的对象锁定。
使用客户机:
import ibm_boto3
from ibm_botocore.client import Config
from ibm_botocore.exceptions import ClientError
from datetime import datetime, timedelta
import time
# Create new bucket with Object Lock enabled.
def create_bucket_with_objectlock(bucket_name):
cos_cli.create_bucket(
Bucket=bucket_name,
ObjectLockEnabledForBucket=True,
)
print("Bucket: {0} created with objectlock enabled".format(bucket_name))
def objectlock_configuration_on_bucket(bucket_name):
# Putting default retenion on the COS bucket.
default_retention_rule = {'DefaultRetention': {'Mode': 'COMPLIANCE', 'Years': 1}}
object_lock_config = {'ObjectLockEnabled': 'Enabled', 'Rule': default_retention_rule}
cos_cli.put_object_lock_configuration(Bucket=bucket_name, ObjectLockConfiguration=object_lock_config)
# Reading the objectlock configuration set on the bucket.
response = cos_cli.get_object_lock_configuration(Bucket=bucket_name)
print("Objectlock Configuration for {0} =>".format(bucket_name))
print(response.ObjectLockConfiguration)
def upload_object(bucket_name,object_name,object_content):
cos_cli.put_object(
Bucket=bucket_name,
Key=object_name,
Body=object_content
)
print("Object: {0} uploaded!".format(object_name))
def objectlock_retention(bucket_name,object_name):
# Put objectlock retenion on the object uploaded to the bucket.
date = datetime.now()+timedelta(seconds=5)
retention_rule = {'Mode': 'COMPLIANCE', 'RetainUntilDate': date}
cos_cli.put_object_retention(Bucket=bucket_name, Key=object_name, Retention=retention_rule)
# Get objectlock retention of the above object.
response = cos_cli.get_object_retention(Bucket=bucket_name, Key=object_name)
print("Objectlock Retention for {0}=>".format(object_name))
print(response.Retention)
def objectlock_legal-hold(bucket_name,object_name):
# Setting the objectlock legal-hold status to ON.
cos_cli.put_object_legal_hold(Bucket=bucket_name, Key=object_name, legal-hold={'Status': 'ON'})
# Get objectlock retention of the above object.
response = cos_cli.get_object_legal_hold(Bucket=bucket_name, Key=object_name)
print("Objectlock legal-hold for {0}=>".format(object_name))
print(response.legal-hold)
COS_ENDPOINT = "" #Current list avaiable at https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints -> Ex:https://s3.us-south.cloud-object-storage.appdomain.cloud
COS_API_KEY_ID = "" #API Key of the cos instance created Ex: W00YixxxxxxxxxxMB-odB-2ySfTrFBIQQWanc--P3byk
COS_RESOURCE_INSTANCE_CRN = "" #API key of cos instance example: xxxd12V2QHXbjaM99G9tWyYDgF_0gYdlQ8aWALIQxXx4
# Create client connection
cos_cli = ibm_boto3.client("s3",
ibm_api_key_id=COS_API_KEY_ID,
config=Config(signature_version="oauth"),
endpoint_url=COS_ENDPOINT,
ibm_service_instance_id=COS_RESOURCE_INSTANCE_CRN,
ibm_auth_endpoint="https://iam.test.cloud.ibm.com/identity/token"
)
new_bucket_name = "create-example-python12345" # bucket name should be unique gloablly, or else it will throw an error.
new_text_file_name = "cos_object.txt"
new_text_file_contents = "This is a test file from Python code sample!!!"
# *** Main Program ***
def main():
create_bucket_with_objectlock(new_bucket_name) # Create a new cos bucket with object lock enabled.
objectlock_configuration_on_bucket(new_bucket_name) # Put objectlock configuration(i.e. default retention) on COS bucket and get the configuration.
upload_object(new_bucket_name,new_text_file_name,new_text_file_contents) # Upload an object to cos bucket.
objectlock_retention(new_bucket_name,new_text_file_name) # Put objectlock retention(i.e. retain until date) on the object and get the configured retention.
objectlock_legal-hold(new_bucket_name,new_text_file_name) # Put objectlock legal-hold on the object and get the legal-hold status.
if __name__ == "__main__":
main()
Node.js
使用 IBM COS SDK for Node.js 启用版本控制:
'use strict';
// Required libraries
const ibm = require('ibm-cos-sdk');
const fs = require('fs');
const crypto = require('crypto');
function logError(e) {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
}
function logDone() {
console.log('DONE!\n');
}
const COS_ENDPOINT = ""; //Choose endpoint from https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints. Ex: https://s3.us-south.cloud-object-storage.appdomain.cloud
const COS_API_KEY_ID = ""; // API key of cos instance example: xxxd12V2QHXbjaM99G9tWyYDgF_0gYdlQ8aWALIQxXx4
const COS_AUTH_ENDPOINT = "";
const COS_RESOURCE_INSTANCE_CRN = ""; // example: crn:v1:bluemix:public:cloud-object-storage:global:a <CREDENTIAL_ID_AS_GENERATED>:<SERVICE_ID_AS_GENERATED>::
// Client Creation.
var config = {
endpoint: COS_ENDPOINT,
apiKeyId: COS_API_KEY_ID,
ibmAuthEndpoint: COS_AUTH_ENDPOINT,
serviceInstanceId: COS_RESOURCE_INSTANCE_CRN,
signatureVersion: 'iam'
};
var cos = new ibm.S3(config);
// Create new bucket with objectlock enabled.
function createBucket(bucketName) {
console.log(`Creating new bucket: ${bucketName}`);
return cos.createBucket({
Bucket: bucketName,
ObjectLockEnabledForBucket: true,
CreateBucketConfiguration: {
LocationConstraint: ''
},
}).promise()
.then((() => {
console.log(`Bucket: ${bucketName} created!`);
}))
.catch((e) => {
console.error(`ERROR: ${e.code} - ${e.message}\n`);
});
}
// Create new text file and upload the object to COS bucket.
function createTextFile(bucketName, itemName, fileText) {
console.log(`Creating new item: ${itemName}`);
return cos.putObject({
Bucket: bucketName,
Key: itemName,
Body: fileText
}).promise()
.then(() => {
console.log(`Item: ${itemName} created!`);
logDone();
})
.catch(logError);
}
function putObjectLockConfigurationonBucket(bucketName) {
console.log(`Putting Objectlock Configuration on : ${bucketName}`);
// Putting objectlock configuration
var defaultRetention = {Mode: 'COMPLIANCE', Days: 1}
var objectLockRule = {DefaultRetention : defaultRetention}
var param = {ObjectLockEnabled: 'Enabled', Rule: objectLockRule}
return cos.putObjectLockConfiguration({
Bucket: bucketName,
ObjectLockConfiguration: param
}).promise()
.then(() => {
console.log(`Object lock Configurtion added!!`);
logDone();
})
.catch(logError);
}
function getObjectLockConfigurationonBucket(bucketName) {
console.log(`Getting Objectlock Configuration for : ${bucketName}`);
// Getting objectlock configuration
return cos.getObjectLockConfiguration({
Bucket: bucketName,
}).promise()
.then((data) => {
console.log(`objectlock configuration`);
console.log( JSON.stringify(data.ObjectLockConfiguration, null, " ") );
logDone();
})
.catch(logError);
}
function putObjectLockRetention(bucketName,keyName) {
console.log(`Putting Objectlock Retention on : ${keyName}`);
var inFiveSecond = (new Date(Date.now() + (1000 * 5)))
var rule = {Mode: 'COMPLIANCE', RetainUntilDate: inFiveSecond}
// Putting objectlock retention
return cos.putObjectRetention({
Bucket: bucketName,
Key: keyName,
Retention: rule
}).promise()
.then(() => {
console.log(`Object lock Retention added!!`);
logDone();
})
.catch(logError);
}
function getObjectLockRetention(bucketName,keyName) {
console.log(`Getting Objectlock Retention for : ${keyName}`);
// Getting objectlock retention
return cos.getObjectRetention({
Bucket: bucketName,
Key: keyName
}).promise()
.then((data) => {
console.log(`Objectlock retention for : ${keyName} `);
console.log( JSON.stringify(data.Retention, null, " ") );
logDone();
})
.catch(logError);
}
function putObjectLocklegal-hold(bucketName,keyName) {
console.log(`Putting Objectlock legal-hold status ON for : ${keyName}`);
// Putting objectlock legal-hold status
return cos.putObjectlegal-hold({
Bucket: bucketName,
Key: keyName,
legal-hold: {Status: 'ON'}
}).promise()
.then(() => {
console.log(`Object lock legal-hold added!!`);
logDone();
})
.catch(logError);
}
function getObjectLocklegal-hold(bucketName,keyName) {
console.log(`Getting Objectlock legal-hold for : ${keyName}`);
// Getting objectlock legal-hold
return cos.getObjectlegal-hold({
Bucket: bucketName,
Key: keyName
}).promise()
.then((data) => {
console.log(`Objectlock legal-hold for : ${keyName} `);
console.log( JSON.stringify(data.legal-hold, null, " ") );
logDone();
})
.catch(logError);
}
// Main app
function main() {
try {
var newBucketName = "jscosbucket350";
var newTextFileName = "js_cos_bucket_file.txt";
var newTextFileContents = "This is a test file from Node.js code sample!!!";
createBucket(newBucketName) // Create a new cos bucket with object lock enabled.
.then(() => putObjectLockConfigurationonBucket(newBucketName)) // Put objectlock configuration(i.e. default retention) on COS bucket.
.then(() => getObjectLockConfigurationonBucket(newBucketName)) // Read objectlock configuration on COS bucket.
.then(() => createTextFile(newBucketName, newTextFileName, newTextFileContents)) // Upload an object to cos bucket.
.then(() => putObjectLockRetention(newBucketName, newTextFileName)) // Put objectlock retention(i.e. retain until date) on the object.
.then(() => getObjectLockRetention(newBucketName, newTextFileName)) // Get the configured retention.
.then(() => putObjectLocklegal-hold(newBucketName,newTextFileName)) // Put objectlock legal-hold on the object.
.then(() => getObjectLocklegal-hold(newBucketName,newTextFileName)); // Get the legal-hold status.
}
catch(ex) {
logError(ex);
}
}
main();
执行
package main
import (
"bytes"
"fmt"
"time"
"github.com/IBM/ibm-cos-sdk-go/aws"
"github.com/IBM/ibm-cos-sdk-go/aws/credentials/ibmiam"
"github.com/IBM/ibm-cos-sdk-go/aws/session"
"github.com/IBM/ibm-cos-sdk-go/service/s3"
)
const (
apiKey = "<apiKey>"
serviceInstanceID = "<serviceInstanceID>"
authEndpoint = "https://iam.cloud.ibm.com/identity/token"
serviceEndpoint = "https://<endpoint>.appdomain.cloud"
)
// Create new bucket with objectlock enabled.
func createBucket(bucketName string, client *s3.S3) {
createBucketInput := new(s3.CreateBucketInput)
createBucketInput.Bucket = aws.String(bucketName)
createBucketInput.ObjectLockEnabledForBucket = aws.Bool(true)
_, e := client.CreateBucket(createBucketInput)
if e != nil {
fmt.Println(e)
} else {
fmt.Println("Bucket Created !!! ")
}
}
func uploadObject(bucketName string, client *s3.S3, fileName string, fileContent string) {
putInput := &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(fileName),
Body: bytes.NewReader([]byte(fileContent)),
}
_, e := client.PutObject(putInput)
if e != nil {
fmt.Println(e)
} else {
fmt.Println("Object Uploaded!!! ")
}
}
func objectLockConfiguration(bucketName string, client *s3.S3) {
// Putting default retenion on the COS bucket.
putObjectLockConfigurationInput := &s3.PutObjectLockConfigurationInput{
Bucket: aws.String(bucketName),
ObjectLockConfiguration: &s3.ObjectLockConfiguration{
ObjectLockEnabled: aws.String(s3.ObjectLockEnabledEnabled),
Rule: &s3.ObjectLockRule{
DefaultRetention: &s3.DefaultRetention{
Mode: aws.String("COMPLIANCE"),
Days: aws.Int64(1),
},
},
},
}
_, e := client.PutObjectLockConfiguration(putObjectLockConfigurationInput)
// Reading the objectlock configuration set on the bucket.
getObjectLockConfigurationInput := new(s3.GetObjectLockConfigurationInput)
getObjectLockConfigurationInput.Bucket = aws.String(bucketName)
response, e := client.GetObjectLockConfiguration(getObjectLockConfigurationInput)
if e != nil {
fmt.Println(e)
} else {
fmt.Println("Object Lock Configuration =>", response.ObjectLockConfiguration)
}
}
func objectLockRetention(bucketName string, client *s3.S3, keyName string) {
// Put objectlock retenion on the object uploaded to the bucket.
retention_date := time.Now().Local().Add(time.Second * 5)
putObjectRetentionInput := &s3.PutObjectRetentionInput{
Bucket: aws.String(bucketName),
Key: aws.String(keyName),
Retention: &s3.ObjectLockRetention{
Mode: aws.String("COMPLIANCE"),
RetainUntilDate: aws.Time(retention_date),
},
}
_, e := client.PutObjectRetention(putObjectRetentionInput)
// Get objectlock retention of the above object.
getObjectRetentionInput := new(s3.GetObjectRetentionInput)
getObjectRetentionInput.Bucket = aws.String(bucketName)
getObjectRetentionInput.Key = aws.String(keyName)
response, e := client.GetObjectRetention(getObjectRetentionInput)
if e != nil {
fmt.Println(e)
} else {
fmt.Println("Object Lock Retention =>", response.Retention)
}
}
func objectLocklegal-hold(bucketName string, client *s3.S3, keyName string) {
// Setting the objectlock legal-hold status to ON.
putObjectlegal-holdInput := &s3.PutObjectlegal-holdInput{
Bucket: aws.String(bucketName),
Key: aws.String(keyName),
legal-hold: &s3.ObjectLocklegal-hold{
Status: aws.String("ON"),
},
}
_, e := client.PutObjectlegal-hold(putObjectlegal-holdInput)
// Get objectlock retention of the above object.
getObjectlegal-holdInput := new(s3.GetObjectlegal-holdInput)
getObjectlegal-holdInput.Bucket = aws.String(bucketName)
getObjectlegal-holdInput.Key = aws.String(keyName)
response, e := client.GetObjectlegal-hold(getObjectlegal-holdInput)
if e != nil {
fmt.Println(e)
} else {
fmt.Println("Object Lock legal-hold =>", response.legal-hold)
}
}
func main() {
bucketName := "gocosbucket353"
textFileName := "go_cos_bucket_file.txt"
textFileContents := "This is a test file from Node.js code sample!!!"
conf := aws.NewConfig().
WithEndpoint(serviceEndpoint).
WithCredentials(ibmiam.NewStaticCredentials(aws.NewConfig(),
authEndpoint, apiKey, serviceInstanceID)).
WithS3ForcePathStyle(true)
sess := session.Must(session.NewSession())
client := s3.New(sess, conf)
createBucket(bucketName, client) // Create a new cos bucket with object lock enabled.
objectLockConfiguration(bucketName, client) // Put objectlock configuration(i.e. default retention) on COS bucket and get the configuration.
uploadObject(bucketName, client, textFileName, textFileContents) // Upload an object to cos bucket.
objectLockRetention(bucketName, client, textFileName) // Put objectlock retention(i.e. retain until date) on the object and get the configured retention.
objectLocklegal-hold(bucketName, client, textFileName) // Put objectlock legal-hold on the object and get the legal-hold status.
}
Terraform
// Create COS instance.
resource "ibm_resource_instance" "cos_instance" {
name = "cos-instance"
resource_group_id = data.ibm_resource_group.cos_group.id
service = "cloud-object-storage"
plan = "standard"
location = "global"
}
// Create a new bucket with objectlock and object versioning enabled.
resource "ibm_cos_bucket" "bucket" {
bucket_name = var.bucket_name
resource_instance_id = ibm_resource_instance.cos_instance.id
region_location = var.regional_loc
storage_class = var.standard_storage_class
object_versioning {
enable = true
}
object_lock = true
}
// Set object lock configuration on the bucket by providing the crn of the new COS bucket.
resource ibm_cos_bucket_objectlock_configuration "objectlock" {
bucket_crn = ibm_cos_bucket.bucket.crn
bucket_location = var.regional_loc
object_lock_configuration{
objectlockenabled = "Enabled"
objectlockrule{
defaultretention{
mode = "COMPLIANCE"
days = 6
}
}
}
}
// Upload an object to the COS bucket with objectlock retention and objectlock legal-hold.
resource "ibm_cos_bucket_object" "object_object_lock" {
bucket_crn = ibm_cos_bucket.bucket.crn
bucket_location = ibm_cos_bucket.bucket.region_location
content = "Hello World 2"
key = "plaintext5.txt"
object_lock_mode = "COMPLIANCE"
object_lock_retain_until_date = "2023-02-15T18:00:00Z"
object_lock_legal_hold_status = "ON"
force_delete = true
}