バケットを保護するための Immutable Object Storage の使用
Immutable Object Storage は、電子レコードを保存してデータの保全性を保ちます。 保存ポリシーは、消去も再書き込みもできない WORM (Write-Once-Read-Many) という方法でデータを確実に保管するためのものです。 このポリシーは、保存期間が終了し、かつ、訴訟ホールドがすべて解除されるまで、適用されます。
この機能は現在、 Object Storage for Satelliteではサポートされていません。 詳細はこちらをご覧ください。
ポリシーは保存期間の終了まで適用され、保存期間が満了するまで変更することはできません。 IBM Cloud Object Storage はほとんどの操作で S3 API を使用しますが、保存ポリシーの構成に使用される API は S3 API と同じではありません。ただし、一部の用語は共有される場合があります。 IBM Cloud 管理者であっても、組織内のすべてのユーザーが削除できないオブジェクトを作成できないようにするために、この資料をよくお読みください。
この機能は、以下の業界の組織 (以下に限定されるわけではありません) など、環境で長期間のデータ保存を必要とするユーザーであれば誰でも使用できます。
- 金融
- ヘルスケア
- メディア・コンテンツ・アーカイブ
- オブジェクトまたは文書に対する特権のある変更または削除を防止しようとしているユーザー
保存ポリシーは、ブローカー・ディーラー取引などの金融レコード管理を扱っていて、再書き込みも消去もできない形式でデータを保管する必要がある組織で使用されることもあります。
Immutable Object Storage は、特定の地域でのみ使用可能です。詳しくは、統合サービスを参照してください。 また、「標準」価格プランが必要です。 詳しくは、料金設定を参照してください。
保存ポリシーが設定されたバケットで Aspera 高速転送を使用することはできません。
用語および使用法
保存期間
オブジェクトがIBM Cloud Object Storageバケットに格納されていなければならない時間。
保存ポリシー
保持ポリシーはIBM Cloud Object Storageバケットレベルで有効です。 このポリシーは、最大、最小、およびデフォルトの保存期間を定義し、バケット内のすべてのオブジェクトに適用されます。
最小保存期間は、オブジェクトをバケット内で変更せずに保持しなければならない最小期間です。
最大保存期間は、オブジェクトをバケット内で変更せずに保持できる最大期間です。
カスタム保存期間を指定せずにオブジェクトをバケットに保管すると、デフォルトの保存期間が使用されます。 最小保存期間はデフォルト保存期間以下でなければならず、デフォルト保存期間は最大保存期間以下でなければなりません
オブジェクトに指定できる最大保存期間は 1000 年です。
バケットに保存ポリシーを作成するには、「管理者」役割が必要です。 詳しくは、バケット許可を参照してください。
訴訟ホールド
オブジェクトによっては、保存期間が切れた後も変更を防止する必要があります。 例として、法的審査が未完了であり、最初に設定された保存期間を超えてもさらに長期にわたってレコードがアクセス可能である必要がある場合などが考えられます。 この場合、訴訟ホールドのフラグをオブジェクト・レベルで適用できます。 訴訟ホールドは、初期アップロード時またはオブジェクトが書き込まれた後に、オブジェクトに適用できます。 注: オブジェクト当たり最大 100 個の訴訟ホールドを適用できます。
無期限保存
ユーザーは、新しい保存期間が適用されるまでオブジェクトが無期限に保管されるように設定できます。 これはオブジェクト・レベルで設定されます。
無期限保持を使用して保持されているオブジェクトは、そのオブジェクトの保持が-1からある正の有限値に変換されるまでは、完全に不変ではありません。 -1 (Indefinite Retention) で書かれたオブジェクトは、DELETE object
または上書きリクエストで削除することはできませんが、-1 から現在の日付/時刻に更新することはできます。
ユーザーは、ストレージのニーズに対する実行可能性を評価する際に、この動作を考慮する必要がある。 無期限リテンションの一般的な使用例は、イベントベースのリテンション で説明されています。 イベント ベースの保持を使用したい場合、Immutable Object Storage では、オブジェクトが最初にシステムにアップロードされたときに保持の必要性がわからない場合、ユーザーがオブジェクトに無期限の保持を設定することができます。 いったん無期限に設定されると、ユーザー・アプリケーションは、特定のイベントが発生したときに、オブジェクトの保持を有限の値に変更することができる。
例 ある企業が、従業員の記録を退職後3年間保存するという方針を持っているとします。
- 従業員が入社して会社で働き始めると、その従業員に関連する記録は無期限に保持することができる。
- そして、同じ従業員が退職した場合、無期限の保有は、会社の方針で定められた現在から3年という有限の価値に変換される。
ユーザー・アプリケーションまたはサード・パーティー・アプリケーションは、SDK または REST API を使用して、保存期間を無限から有限に変更できます。
バケット所有者と許可されたユーザは、現在無期限保持を使用して保持されているオブジェクトに対して設定できる新しい保持を制限できます。 これは、バケット保持の最小許容値と最大許容値を利用することによって行われる。 そうすることで、ユーザーは、無期限保持で保持されているオブジェクトの保持が現在時刻に更新され、すぐに削除可能になってしまうケースを防ぐことができます。
イベント・ベースの保存
ユーザーは、保存期間の最終的な長さがはっきり分からない場合や、イベント・ベースの保存を使用したい場合に、Immutable Object Storage を使用してオブジェクトに無期限の保存を設定できます。 無期限に設定した後で、ユーザー・アプリケーションでオブジェクト保存期間を有限の値に変更することができます。 例えば、ある会社で従業員の退職後 3 年間は従業員レコードを保持するという方針があるとします。 従業員が入社した時点では、その従業員に関連付けられたレコードを無期限に保持するようにできます。 従業員が退職すると、この無期限の保存は、会社の方針に定義されているように、その時点から 3 年間の有限値に変換されます。 そうすると、保存期間が変更された後の 3 年間、オブジェクトは保護されることになります。 ユーザー・アプリケーションまたはサード・パーティー・アプリケーションは、SDK または REST API を使用して、保存期間を無限から有限に変更できます。
永久保存
永続保存により、誰でもデータを削除できないようにすることができます。 永続 データ・ストレージの必要性がやむを得ない場合を除き、資料を注意深く読み、永久保存を使用しないでください。
永久保存は、IBM Cloud Object Storageバケットレベルで、保存ポリシーが有効で、ユーザがオブジェクトのアップロード時に永久保存期間オプションを選択できる場合にのみ有効にできます。 一度有効にした後でこのプロセスを元に戻すことはできず、永久保存期間を使用してアップロードされたオブジェクトは削除できません。 Object Storageバケットを使用し、オブジェクトを保持ポリシーで永続的に保存する正当な必要性があるかどうかを確認するのは、ユーザーの責任です
Immutable Object Storage を使用する場合、データが保存ポリシーの対象である間はずっと、ご使用の IBM Cloud アカウントが IBM Cloud の方針およびガイドラインに照らして良好な状態であり続けるようにするのはお客様の責任です。 詳しくは、IBM Cloud サービスの用語を参照してください。
Immutable Object Storage と各種規則に関する考慮事項
Immutable Object Storage を使用する場合、ここで説明されている機能のいずれについても、一般的に以下によって管理されている電子記録保管および保存に関する主要な規則に準拠するように使用できるかどうかを確認するのは、お客様の責任です。
- 証券取引委員会(SEC)規則 17a-4(f)、
- Financial Industry Regulatory Authority(FINRA)Rule 4511(c)、および
- 商品先物取引委員会(CFTC)ルール 1.31(c)-(d)
お客様が十分な情報に基づいて意思決定を行うのを支援するため、IBM は、Immutable Object Storage の独立した査定を行うように Cohasset Associates Inc. に依頼しました。 IBM Cloud Object Storage の Immutable Object Storage 機能の評価に関する詳細を提供する、Cohasset Associates Inc.のレポートをご覧ください
アクセスおよびトランザクションの監査
Immutable Object Storage のログ・データにアクセスして、保存パラメーター、オブジェクト保存期間、および訴訟ホールドの適用の変更を検討することができます。これは、カスタマー・サービス・チケットをオープンすることで事例ごとに確認できます。
コンソールの使用
保存ポリシーは新規または既存の空のバケットに追加することができ、削除することはできません。 新規バケットの場合、サポートされる地域のいずれかでバケットを作成し、次に、**「保存ポリシーの追加」オプションを選択します。 既存バケットの場合、オブジェクトがないことを確認してから、構成設定に移動し、「バケット保存ポリシー」セクションの「ポリシーの作成」**ボタンをクリックします。 いずれの場合も、最小、最大、およびデフォルトの保存期間を設定してください。
REST API、ライブラリー、および SDK の使用
いくつかの新しいAPIがIBM Cloud Object Storage SDKに導入され、保持ポリシーで動作するアプリケーションをサポートするようになりました。 適切なObject StorageSDKを使ったサンプルを見るには、このページの最初にある言語(HTTP、Java、JavaScript,、Python)を選択してください。
すべてのコード例で、さまざまなメソッドを呼び出すことができる cos
という名前のクライアント・オブジェクトが存在することを前提としています。 クライアントの作成について詳しくは、特定の SDK ガイドを参照してください。
保存期間の設定に使用されるすべての日付値はグリニッジ標準時です。 Content-MD5
ヘッダーは、データ保全性を確保するために必須であり、SDK を使用する場合は自動的に送信されます。
既存バケットへの保存ポリシーの追加
PUT
操作のこの実装では、protection
照会パラメーターを使用して、既存のバケットに保存パラメーターを設定します。 この操作により、保存期間の最小、デフォルト、および最大を設定または変更できます。 また、この操作により、バケットの保護状態を変更することもできます。
保護対象のバケットに書き込まれたオブジェクトは、保護期間が満了し、オブジェクトに対するすべての法的保留が解除されるまで削除できません。 オブジェクトの作成時にオブジェクト固有の値が指定されない限り、バケットのデフォルトの保存期間値がオブジェクトにも適用されます。 保全の対象でなくなった保護対象バケット内のオブジェクト (保存期間が満了し、オブジェクトに法的保留が課せられていない) が上書きされた場合、そのオブジェクトは再度保全の対象になります。 新しい保存期間は、オブジェクト上書き要求の一部として指定できます。そうしない場合は、バケットのデフォルトの保存期間がオブジェクトに適用されます。
保存期間設定 MinimumRetention
、DefaultRetention
、MaximumRetention
の最小値と最大値は、最小0日、最大365243日(1000年)です。
Content-MD5
ヘッダーは必須です。 この操作では、追加の照会パラメーターは使用されません。
エンドポイントについて詳しくは、エンドポイントおよびストレージ・ロケーションを参照してください。
構文
PUT https://{endpoint}/{bucket-name}?protection= # path style
PUT https://{bucket-name}.{endpoint}?protection= # virtual host style
要求の例
PUT /example-bucket?protection= HTTP/1.1
Authorization: {authorization-string}
x-amz-date: 20181011T190354Z
x-amz-content-sha256: 2938f51643d63c864fdbea618fe71b13579570a86f39da2837c922bae68d72df
Content-MD5: GQmpTNpruOyK6YrxHnpj7g==
Content-Type: text/plain
Host: 67.228.254.193
Content-Length: 299
<ProtectionConfiguration>
<Status>Retention</Status>
<MinimumRetention>
<Days>100</Days>
</MinimumRetention>
<MaximumRetention>
<Days>10000</Days>
</MaximumRetention>
<DefaultRetention>
<Days>2555</Days>
</DefaultRetention>
</ProtectionConfiguration>
応答の例
HTTP/1.1 200 OK
Date: Wed, 5 Oct 2018 15:39:38 GMT
X-Clv-Request-Id: 7afca6d8-e209-4519-8f2c-1af3f1540b42
Accept-Ranges: bytes
Server: Cleversafe/3.14.1
X-Clv-S3-Version: 2.5
x-amz-request-id: 7afca6d8-e209-4519-8f2c-1af3f1540b42
Content-Length: 0
def add_protection_configuration_to_bucket(bucket_name):
try:
new_protection_config = {
"Status": "Retention",
"MinimumRetention": {"Days": 10},
"DefaultRetention": {"Days": 100},
"MaximumRetention": {"Days": 1000}
}
cos.put_bucket_protection_configuration(Bucket=bucket_name, ProtectionConfiguration=new_protection_config)
print("Protection added to bucket {0}\n".format(bucket_name))
except ClientError as be:
print("CLIENT ERROR: {0}\n".format(be))
except Exception as e:
print("Unable to set bucket protection config: {0}".format(e))
function addProtectionConfigurationToBucket(bucketName) {
console.log(`Adding protection to bucket ${bucketName}`);
return cos.putBucketProtectionConfiguration({
Bucket: bucketName,
ProtectionConfiguration: {
'Status': 'Retention',
'MinimumRetention': {'Days': 10},
'DefaultRetention': {'Days': 100},
'MaximumRetention': {'Days': 1000}
}
}).promise()
.then(() => {
console.log(`Protection added to bucket ${bucketName}!`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void addProtectionConfigurationToBucket(String bucketName) {
System.out.printf("Adding protection to bucket: %s\n", bucketName);
BucketProtectionConfiguration newConfig = new BucketProtectionConfiguration()
.withStatus(BucketProtectionStatus.Retention)
.withMinimumRetentionInDays(10)
.withDefaultRetentionInDays(100)
.withMaximumRetentionInDays(1000);
cos.setBucketProtection(bucketName, newConfig);
System.out.printf("Protection added to bucket %s\n", bucketName);
}
public static void addProtectionConfigurationToBucketWithRequest(String bucketName) {
System.out.printf("Adding protection to bucket: %s\n", bucketName);
BucketProtectionConfiguration newConfig = new BucketProtectionConfiguration()
.withStatus(BucketProtectionStatus.Retention)
.withMinimumRetentionInDays(10)
.withDefaultRetentionInDays(100)
.withMaximumRetentionInDays(1000);
SetBucketProtectionConfigurationRequest newRequest = new SetBucketProtectionConfigurationRequest()
.withBucketName(bucketName)
.withProtectionConfiguration(newConfig);
cos.setBucketProtectionConfiguration(newRequest);
System.out.printf("Protection added to bucket %s\n", bucketName);
}
バケットの保存ポリシーの確認
GET 操作のこの実装は、既存バケットの保存パラメーターを取り出します。
構文
GET https://{endpoint}/{bucket-name}?protection= # path style
GET https://{bucket-name}.{endpoint}?protection= # virtual host style
要求の例
GET /example-bucket?protection= HTTP/1.1
Authorization: {authorization-string}
x-amz-date: 20181011T190354Z
Content-Type: text/plain
Host: 67.228.254.193
応答の例
HTTP/1.1 200 OK
Date: Wed, 5 Oct 2018 15:39:38 GMT
X-Clv-Request-Id: 7afca6d8-e209-4519-8f2c-1af3f1540b42
Accept-Ranges: bytes
Server: Cleversafe/3.13.1
X-Clv-S3-Version: 2.5
x-amz-request-id: 7afca6d8-e209-4519-8f2c-1af3f1540b42
Content-Length: 299
<ProtectionConfiguration>
<Status>Retention</Status>
<MinimumRetention>
<Days>100</Days>
</MinimumRetention>
<MaximumRetention>
<Days>10000</Days>
</MaximumRetention>
<DefaultRetention>
<Days>2555</Days>
</DefaultRetention>
</ProtectionConfiguration>
バケットに対する保存構成がない場合、サーバーは代わりに状況を Disabled として応答します。
<ProtectionConfiguration>
<Status>Disabled</Status>
</ProtectionConfiguration>
def get_protection_configuration_on_bucket(bucket_name):
try:
response = cos.get_bucket_protection_configuration(Bucket=bucket_name)
protection_config = response.get("ProtectionConfiguration")
print("Bucket protection config for {0}\n".format(bucket_name))
print(protection_config)
print("\n")
except ClientError as be:
print("CLIENT ERROR: {0}\n".format(be))
except Exception as e:
print("Unable to get bucket protection config: {0}".format(e))
function getProtectionConfigurationOnBucket(bucketName) {
console.log(`Retrieve the protection on bucket ${bucketName}`);
return cos.getBucketProtectionConfiguration({
Bucket: bucketName
}).promise()
.then((data) => {
console.log(`Configuration on bucket ${bucketName}:`);
console.log(data);
}
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void getProtectionConfigurationOnBucket(String bucketName) {
System.out.printf("Retrieving protection configuration from bucket: %s\n", bucketName;
BucketProtectionConfiguration config = cos.getBucketProtection(bucketName);
String status = config.getStatus();
System.out.printf("Status: %s\n", status);
if (!status.toUpperCase().equals("DISABLED")) {
System.out.printf("Minimum Retention (Days): %s\n", config.getMinimumRetentionInDays());
System.out.printf("Default Retention (Days): %s\n", config.getDefaultRetentionInDays());
System.out.printf("Maximum Retention (Days): %s\n", config.getMaximumRetentionInDays());
}
}
保存ポリシーのあるバケットへのオブジェクトのアップロード
PUT
操作のこの機能拡張では 3 つの新しい要求ヘッダーが追加されました。2 つは、異なる方法で保存期間を指定するためのものであり、1 つは新規オブジェクトに単一の訴訟ホールドを追加するためのものです。 これらの新しいヘッダーの値が正しくない場合のために新しいエラーが定義され、オブジェクトが保存されている場合は上書きは失敗します。
保存ポリシーのあるバケット内の保存されなくなったオブジェクト (保存期間が満了し、オブジェクトに訴訟ホールドがない) は、上書きされると再び保存されるようになります。 新しい保存期間は、オブジェクト上書き要求の一部として指定できます。そうしない場合は、バケットのデフォルトの保存期間がオブジェクトに適用されます。
Content-MD5
ヘッダーは必須です。
これらのヘッダーは、POST オブジェクトおよびマルチパート・アップロード要求にも適用されます。 1 つのオブジェクトを複数のパートにしてアップロードする場合、各パートに Content-MD5
ヘッダーが必要です。
値 | タイプ | 説明 |
---|---|---|
Retention-Period |
負でない整数 (秒数) | オブジェクトを保管する保存期間 (秒数)。 オブジェクトは、保存期間に指定された時間が経過するまで上書きも削除もできません。 このフィールドと Retention-Expiration-Date が指定された場合、400 エラーが返されます。 いずれも指定されない場合は、バケットの DefaultRetention 期間が使用されます。 ゼロ (0 ) は有効な値であり、バケットの最小保存期間も
0 であると想定されます。 |
Retention-expiration-date |
日付 (ISO 8601 フォーマット) | オブジェクトを合法的に削除または変更できるようになる日付。 これか Retention-Period ヘッダーのいずれかのみを指定できます。 両方が指定された場合は、400 エラーが返されます。 いずれも指定されない場合は、バケットの DefaultRetention 期間が使用されます。 サポートされる ISO 8601 フォーマットは [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z または [YYYY][MM][DD]T[hh][mm][ss]Z です (例えば、 2020-11-28T03:10:01Z または 20201128T031001Z はどちらも有効です)。 |
Retention-legal-hold-id |
ストリング | オブジェクトに適用される単一の法的保留。 法的保留とは、Y 文字の長さのストリングです。 オブジェクトに関連付けられたすべての法的保留が解除されるまで、オブジェクトは上書きも削除もできません。 |
def put_object_add_legal_hold(bucket_name, object_name, file_text, legal_hold_id):
print("Add legal hold {0} to {1} in bucket {2} with a putObject operation.\n".format(legal_hold_id, object_name, bucket_name))
cos.put_object(
Bucket=bucket_name,
Key=object_name,
Body=file_text,
RetentionLegalHoldId=legal_hold_id)
print("Legal hold {0} added to object {1} in bucket {2}\n".format(legal_hold_id, object_name, bucket_name))
def copy_protected_object(source_bucket_name, source_object_name, destination_bucket_name, new_object_name):
print("Copy protected object {0} from bucket {1} to {2}/{3}.\n".format(source_object_name, source_bucket_name, destination_bucket_name, new_object_name))
copy_source = {
"Bucket": source_bucket_name,
"Key": source_object_name
}
cos.copy_object(
Bucket=destination_bucket_name,
Key=new_object_name,
CopySource=copy_source,
RetentionDirective="Copy"
)
print("Protected object copied from {0}/{1} to {2}/{3}\n".format(source_bucket_name, source_object_name, destination_bucket_name, new_object_name));
def complete_multipart_upload_with_retention(bucket_name, object_name, upload_id, retention_period):
print("Completing multi-part upload for object {0} in bucket {1}\n".format(object_name, bucket_name))
cos.complete_multipart_upload(
Bucket=bucket_name,
Key=object_name,
MultipartUpload={
"Parts":[{
"ETag": part["ETag"],
"PartNumber": 1
}]
},
UploadId=upload_id,
RetentionPeriod=retention_period
)
print("Multi-part upload completed for object {0} in bucket {1}\n".format(object_name, bucket_name))
def upload_file_with_retention(bucket_name, object_name, path_to_file, retention_period):
print("Uploading file {0} to object {1} in bucket {2}\n".format(path_to_file, object_name, bucket_name))
args = {
"RetentionPeriod": retention_period
}
cos.upload_file(
Filename=path_to_file,
Bucket=bucket_name,
Key=object_name,
ExtraArgs=args
)
print("File upload complete to object {0} in bucket {1}\n".format(object_name, bucket_name))
function putObjectAddLegalHold(bucketName, objectName, legalHoldId) {
console.log(`Add legal hold ${legalHoldId} to ${objectName} in bucket ${bucketName} with a putObject operation.`);
return cos.putObject({
Bucket: bucketName,
Key: objectName,
Body: 'body',
RetentionLegalHoldId: legalHoldId
}).promise()
.then((data) => {
console.log(`Legal hold ${legalHoldId} added to object ${objectName} in bucket ${bucketName}`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
function copyProtectedObject(sourceBucketName, sourceObjectName, destinationBucketName, newObjectName, ) {
console.log(`Copy protected object ${sourceObjectName} from bucket ${sourceBucketName} to ${destinationBucketName}/${newObjectName}.`);
return cos.copyObject({
Bucket: destinationBucketName,
Key: newObjectName,
CopySource: sourceBucketName + '/' + sourceObjectName,
RetentionDirective: 'Copy'
}).promise()
.then((data) => {
console.log(`Protected object copied from ${sourceBucketName}/${sourceObjectName} to ${destinationBucketName}/${newObjectName}`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void putObjectAddLegalHold(String bucketName, String objectName, String fileText, String legalHoldId) {
System.out.printf("Add legal hold %s to %s in bucket %s with a putObject operation.\n", legalHoldId, objectName, bucketName);
InputStream newStream = new ByteArrayInputStream(fileText.getBytes(StandardCharsets.UTF_8));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(fileText.length());
PutObjectRequest req = new PutObjectRequest(
bucketName,
objectName,
newStream,
metadata
);
req.setRetentionLegalHoldId(legalHoldId);
cos.putObject(req);
System.out.printf("Legal hold %s added to object %s in bucket %s\n", legalHoldId, objectName, bucketName);
}
public static void copyProtectedObject(String sourceBucketName, String sourceObjectName, String destinationBucketName, String newObjectName) {
System.out.printf("Copy protected object %s from bucket %s to %s/%s.\n", sourceObjectName, sourceBucketName, destinationBucketName, newObjectName);
CopyObjectRequest req = new CopyObjectRequest(
sourceBucketName,
sourceObjectName,
destinationBucketName,
newObjectName
);
req.setRetentionDirective(RetentionDirective.COPY);
cos.copyObject(req);
System.out.printf("Protected object copied from %s/%s to %s/%s\n", sourceObjectName, sourceBucketName, destinationBucketName, newObjectName);
}
オブジェクトに対する訴訟ホールドの追加または削除
POST
操作のこの実装は、legalHold
照会パラメーターと、add
および remove
照会パラメーターを使用して、保護バケット内の保護オブジェクトに対して単一の訴訟ホールドを追加または削除します。
オブジェクトがサポートできる法的保留は 100 個です。
- 法的保留 ID は、最大長 64 文字かつ最小長 1 文字のストリングです。 有効な文字はアルファベット、数字、
!
,_
,.
,*
,(
,)
,-
,'
です。 - 指定された法的保留を追加することで、オブジェクトに対する法的保留の合計数が 100 個を超える場合、新しい法的保留は追加されず、
400
エラーが返されます。 - ID が長すぎる場合、ID はオブジェクトに追加されず、
400
エラーが返されます。 - ID に無効文字が含まれている場合、ID はオブジェクトに追加されず、
400
エラーが返されます。 - ID がオブジェクトで既に使用中の場合、既存の法的保留は変更されず、ID が既に使用中であることを示す応答と
409
エラーが返されます。 - オブジェクトに保存期間メタデータがない場合は、
400
エラーが返され、法的保留の追加または削除は許可されません。
保存期間ヘッダーが存在する必要があります。存在しない場合は、400
エラーが返されます。
構文
POST https://{endpoint}/{bucket-name}/{object-name}?legalHold # path style
POST https://{bucket-name}.{endpoint}/{object-name}?legalHold= # virtual host style
要求の例
POST /BucketName/ObjectName?legalHold&add=legalHoldID HTTP/1.1
Host: myBucket.mydsNet.corp.com
Date: Fri, 8 Dec 2018 17:50:00 GMT
Authorization: authorization string
Content-Type: text/plain
応答の例
HTTP/1.1 200 OK
Date: Fri, 8 Dec 2018 17:51:00 GMT
Connection: close
def add_legal_hold_to_object(bucket_name, object_name, legal_hold_id):
print("Adding legal hold {0} to object {1} in bucket {2}\n".format(legal_hold_id, object_name, bucket_name))
cos.add_legal_hold(
Bucket=bucket_name,
Key=object_name,
RetentionLegalHoldId=legal_hold_id
)
print("Legal hold {0} added to object {1} in bucket {2}!\n".format(legal_hold_id, object_name, bucket_name))
def delete_legal_hold_from_object(bucket_name, object_name, legal_hold_id):
print("Deleting legal hold {0} from object {1} in bucket {2}\n".format(legal_hold_id, object_name, bucket_name))
cos.delete_legal_hold(
Bucket=bucket_name,
Key=object_name,
RetentionLegalHoldId=legal_hold_id
)
print("Legal hold {0} deleted from object {1} in bucket {2}!\n".format(legal_hold_id, object_name, bucket_name))
function addLegalHoldToObject(bucketName, objectName, legalHoldId) {
console.log(`Adding legal hold ${legalHoldId} to object ${objectName} in bucket ${bucketName}`);
return cos.client.addLegalHold({
Bucket: bucketName,
Key: objectId,
RetentionLegalHoldId: legalHoldId
}).promise()
.then(() => {
console.log(`Legal hold ${legalHoldId} added to object ${objectName} in bucket ${bucketName}!`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
function deleteLegalHoldFromObject(bucketName, objectName, legalHoldId) {
console.log(`Deleting legal hold ${legalHoldId} from object ${objectName} in bucket ${bucketName}`);
return cos.client.deleteLegalHold({
Bucket: bucketName,
Key: objectId,
RetentionLegalHoldId: legalHoldId
}).promise()
.then(() => {
console.log(`Legal hold ${legalHoldId} deleted from object ${objectName} in bucket ${bucketName}!`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void addLegalHoldToObject(String bucketName, String objectName, String legalHoldId) {
System.out.printf("Adding legal hold %s to object %s in bucket %s\n", legalHoldId, objectName, bucketName);
cos.addLegalHold(
bucketName,
objectName,
legalHoldId
);
System.out.printf("Legal hold %s added to object %s in bucket %s!\n", legalHoldId, objectName, bucketName);
}
public static void deleteLegalHoldFromObject(String bucketName, String objectName, String legalHoldId) {
System.out.printf("Deleting legal hold %s from object %s in bucket %s\n", legalHoldId, objectName, bucketName);
cos.deleteLegalHold(
bucketName,
objectName,
legalHoldId
);
System.out.printf("Legal hold %s deleted from object %s in bucket %s!\n", legalHoldId, objectName, bucketName);
}
オブジェクトの保存期間の延長
POST
操作のこの実装は、extendRetention
照会パラメーターを使用して、保護バケット内の保護オブジェクトの保存期間を延長します。
オブジェクトの保存期間は延長のみが可能です。 現在構成されている値から減らすことはできません。
保存延長値は次の 3 つの方法のいずれかで設定されます。
- 現行値からの追加時間 (
Additional-Retention-Period
または同様のメソッド) - 新しい延長期間 (秒数) (
Extend-Retention-From-Current-Time
または同様のメソッド) - オブジェクトの新しい保存有効期限日付 (
New-Retention-Expiration-Date
または同様のメソッド)
オブジェクト・メタデータに保管されている現在の保存期間は、extendRetention
要求に設定されているパラメーターに応じて、指定された追加時間分増やされるか、新しい値に置き換えられます。 いずれの場合も、保存延長パラメーターは現在の保存期間に対して検査され、更新後の保存期間が現在の保存期間より大きい場合にのみ、延長パラメーターが受け入れられます。
New-Retention-Expiration-Date
でサポートされる ISO 8601 形式は、 [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z
または [YYYY][MM][DD]T[hh][mm][ss]Z
です (例えば、 2020-11-28T03:10:01Z
または 20201128T031001Z
はどちらも有効です)。
保全の対象でなくなった保護対象バケット内のオブジェクト (保存期間が満了し、オブジェクトに法的保留が課せられていない) が上書きされた場合、そのオブジェクトは再度保全の対象になります。 新しい保存期間は、オブジェクト上書き要求の一部として指定できます。そうしない場合は、バケットのデフォルトの保存期間がオブジェクトに適用されます。
構文
POST https://{endpoint}/{bucket-name}/{object-name}?extendRetention= # path style
POST https://{bucket-name}.{endpoint}/{object-name}?extendRetention= # virtual host style
要求の例
POST /BucketName/ObjectName?extendRetention HTTP/1.1
Host: myBucket.mydsNet.corp.com
Date: Fri, 8 Dec 2018 17:50:00GMT
Authorization: authorization string
Content-Type: text/plain
Additional-Retention-Period: 31470552
応答の例
HTTP/1.1 200 OK
Date: Fri, 8 Dec 2018 17:50:00GMT
Connection: close
def extend_retention_period_on_object(bucket_name, object_name, additional_seconds):
print("Extend the retention period on {0} in bucket {1} by {2} seconds.\n".format(object_name, bucket_name, additional_seconds))
cos.extend_object_retention(
Bucket=bucket_ame,
Key=object_name,
AdditionalRetentionPeriod=additional_seconds
)
print("New retention period on {0} is {1}\n".format(object_name, additional_seconds))
function extendRetentionPeriodOnObject(bucketName, objectName, additionalSeconds) {
console.log(`Extend the retention period on ${objectName} in bucket ${bucketName} by ${additionalSeconds} seconds.`);
return cos.extendObjectRetention({
Bucket: bucketName,
Key: objectName,
AdditionalRetentionPeriod: additionalSeconds
}).promise()
.then((data) => {
console.log(`New retention period on ${objectName} is ${data.RetentionPeriod}`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void extendRetentionPeriodOnObject(String bucketName, String objectName, Long additionalSeconds) {
System.out.printf("Extend the retention period on %s in bucket %s by %s seconds.\n", objectName, bucketName, additionalSeconds);
ExtendObjectRetentionRequest req = new ExtendObjectRetentionRequest(
bucketName,
objectName)
.withAdditionalRetentionPeriod(additionalSeconds);
cos.extendObjectRetention(req);
System.out.printf("New retention period on %s is %s\n", objectName, additionalSeconds);
}
オブジェクトの訴訟ホールドのリスト
GET
操作のこの実装は、legalHold
照会パラメーターを使用して、オブジェクトの訴訟ホールドのリストおよび関連する保存状況を XML 応答本体で返します。
この操作で返される内容は以下のとおりです。
- オブジェクト作成日
- オブジェクト保存期間 (秒数)
- 期間および作成日に基づいて計算された保存有効期限
- 法的保留のリスト
- 法的保留 ID
- 法的保留が適用されたときのタイム・スタンプ
オブジェクトに法的保留がない場合は、空の LegalHoldSet
が返されます。 オブジェクトに保存期間が指定されていない場合、
404
エラーが返されます。
構文
GET https://{endpoint}/{bucket-name}/{object-name}?legalHold= # path style
GET https://{bucket-name}.{endpoint}/{object-name}?legalHold= # virtual host style
要求の例
GET /BucketName/ObjectName?legalHold HTTP/1.1
Host: myBucket.mydsNet.corp.com
Date: Fri, 8 Dec 2018 17:50:00 GMT
Authorization: {authorization-string}
Content-Type: text/plain
応答の例
HTTP/1.1 200 OK
Date: Fri, 8 Dec 2018 17:51:00 GMT
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<RetentionState>
<CreateTime>Fri, 8 Sep 2018 21:33:08 GMT</CreateTime>
<RetentionPeriod>220752000</RetentionPeriod>
<RetentionPeriodExpirationDate>Fri, 1 Sep 2023 21:33:08
GMT</RetentionPeriodExpirationDate>
<LegalHoldSet>
<LegalHold>
<ID>SomeLegalHoldID</ID>
<Date>Fri, 8 Sep 2018 23:13:18 GMT</Date>
</LegalHold>
<LegalHold>
...
</LegalHold>
</LegalHoldSet>
</RetentionState>
def list_legal_holds_on_object(bucket_name, object_name):
print("List all legal holds on object {0} in bucket {1}\n".format(object_name, bucket_name));
response = cos.list_legal_holds(
Bucket=bucket_name,
Key=object_name
)
print("Legal holds on bucket {0}: {1}\n".format(bucket_name, response))
function listLegalHoldsOnObject(bucketName, objectName) {
console.log(`List all legal holds on object ${objectName} in bucket ${bucketName}`);
return cos.listLegalHolds({
Bucket: bucketName,
Key: objectId
}).promise()
.then((data) => {
console.log(`Legal holds on bucket ${bucketName}: ${data}`);
})
.catch((e) => {
console.log(`ERROR: ${e.code} - ${e.message}\n`);
});
}
public static void listLegalHoldsOnObject(String bucketName, String objectName) {
System.out.printf("List all legal holds on object %s in bucket %s\n", objectName, bucketName);
ListLegalHoldsResult result = cos.listLegalHolds(
bucketName,
objectName
);
System.out.printf("Legal holds on bucket %s: \n", bucketName);
List<LegalHold> holds = result.getLegalHolds();
for (LegalHold hold : holds) {
System.out.printf("Legal Hold: %s", hold);
}
}