Utilisation de Object Storage non modifiable pour protéger les compartiments
La fonction Immutable Object Storage conserve les enregistrements électroniques et assure l'intégrité des données. Les règles de conservation permettent de garantir que les données sont stockées de manière non réinscriptible (WORM), c'est-à-dire qu'elles ne peuvent pas être effacées ou modifiées. Cette règle est appliquée jusqu'à la fin d'une durée de conservation et de la suppression de toute règle de conservation légale.
Cette fonction n'est actuellement pas prise en charge dans Object Storage pour Satellite. En savoir plus.
Les règles sont appliquées jusqu'à la fin d'une période de conservation et ne peuvent pas être modifiées tant que la période de conservation n'est pas arrivée à expiration. Alors que IBM Cloud Object Storage utilise l'API S3 pour la plupart des opérations, les API utilisées pour la configuration des règles de conservation ne sont pas les mêmes que celles de l'API S3, bien qu'une certaine terminologie puisse être partagée. Lisez attentivement cette documentation pour empêcher les utilisateurs de votre organisation de créer des objets qui ne peuvent pas être supprimés, même par les administrateurs IBM Cloud.
Cette fonction peut être utilisée par tous les utilisateurs ayant besoin de conserver les données à long terme dans leur environnement. Elle concerne, entre autres, les organisations dans les secteurs d'activité suivants :
- Finances
- Santé
- Archivage de contenu multimédia
- Toute personne cherchant à empêcher la modification ou la suppression privilégiée d'objets ou de documents
Des règles de conservation peuvent également être utilisées par des organisations spécialisées dans la gestion de documents financiers, tels que les transactions de courtier, et qui ont éventuellement besoin de stocker leurs données dans un format non réinscriptible et non effaçable.
La fonction Immutable Object Storage est disponible uniquement dans certaines régions, voir Services intégrés pour obtenir des détails. De plus, elle requiert un plan de tarification standard. Pour plus d'informations, voir la section sur la tarification.
Il est impossible d'utiliser Aspera High-Speed Transfer avec les compartiments dotés d'une règle de conservation.
Terminologie et utilisation
Durée de conservation
La durée pendant laquelle un objet doit être stocké dans le seau IBM Cloud Object Storage.
Stratégie de conservation
Une politique de conservation est activée au niveau du seau IBM Cloud Object Storage. Les durées de conservation minimum, maximum et par défaut sont définies par cette règle et s'appliquent à tous les objets contenus dans le compartiment.
La durée de conservation minimum est la durée minimale pendant laquelle un objet doit être conservé sans être modifié dans le compartiment.
La durée de conservation maximum est la durée maximale pendant laquelle un objet peut être conservé sans être modifié dans le compartiment.
Si un objet est stocké dans le compartiment sans qu'aucune durée de conservation personnalisée ne soit spécifiée, la durée de conservation par défaut est utilisée. La durée de conservation minimum doit être inférieure ou égale à la durée de conservation par défaut, laquelle doit être inférieure ou égale à la durée de conservation maximum.
Une durée de conservation maximum de 1000 ans peut être spécifiée pour les objets.
Pour créer une règle de conservation pour un compartiment, vous devez disposer du rôle Responsable. Pour plus d'informations, voir Droits des compartiments.
Conservation légale
Il peut s'avérer nécessaire d'empêcher la mise à jour de certains objets à l'issue d'une durée de conservation. Par exemple, suite à un examen juridique incomplet, où l'accès aux enregistrements doit être prolongé au-delà de la durée de conservation définie à l'origine. Un indicateur de conservation légale peut alors être appliqué au niveau de l'objet. Des durées de conservation légale peuvent être appliquées aux objets lors de téléchargements initiaux ou après l'écriture d'un objet. Remarque : un maximum de 100 conservations légales peut être appliqué par objet.
Conservation indéfinie
Permet à l'utilisateur de définir l'objet de telle manière qu'il soit stocké indéfiniment jusqu'à ce qu'une nouvelle durée de conservation soit appliquée. Cette valeur est définie au niveau des objets.
Un objet dont la conservation est indéfinie n'est pas entièrement immuable tant que la conservation de l'objet n'a pas été convertie de -1 en une valeur positive finie. Bien qu'un objet écrit avec -1 (rétention indéfinie) ne puisse pas être
supprimé à l'aide de la requête DELETE object ou écrasé, la rétention de l'objet peut toujours être mise à jour de -1 à la date/heure actuelle, ce qui rendrait l'objet immédiatement supprimable.
Les utilisateurs doivent tenir compte de ce comportement lorsqu'ils évaluent la viabilité du système pour leurs besoins de stockage. Un cas d'utilisation courant de la conservation indéfinie est décrit dans La conservation basée sur des événements. Si vous souhaitez utiliser la conservation basée sur les événements, Immutable Object Storage permet aux utilisateurs de définir une conservation indéfinie sur l'objet s'ils ne sont pas sûrs des besoins en matière de conservation lorsque l'objet est téléchargé pour la première fois dans le système. Une fois qu'elle est réglée sur une valeur indéfinie, les applications utilisateur peuvent alors modifier la rétention de l'objet pour lui donner une valeur finie lorsqu'un certain événement s'est produit.
Exemple Une entreprise a pour politique de conserver les dossiers de ses employés pendant trois ans après leur départ de l'entreprise.
- Lorsqu'un employé entre au service d'une entreprise, les documents qui lui sont associés peuvent être conservés indéfiniment.
- Et lorsque ce même salarié quitte l'entreprise, la conservation indéfinie est alors convertie en une valeur finie de trois ans à compter de la date actuelle, qui est définie par la politique de l'entreprise.
Un utilisateur ou une application tierce peut remplacer la conservation indéfinie par une conservation avec limite de durée en utilisant un kit SDK ou une API REST.
Les propriétaires de bacs et les utilisateurs autorisés peuvent limiter la nouvelle durée de conservation qui peut être configurée pour un objet actuellement conservé à l'aide de la conservation indéfinie. Pour ce faire, on utilise les valeurs minimales et maximales autorisées de la rétention du seau. Ce faisant, les utilisateurs peuvent éviter qu'un objet dont la durée de conservation est indéterminée ne soit mis à jour à l'heure actuelle, de sorte qu'il soit immédiatement supprimable.
Conservation en fonction d'un événement
La fonction Immutable Object Storage permet aux utilisateurs de définir une conservation indéfinie de l'objet s'ils ont un doute sur la durée de conservation finale ou s'ils souhaitent utiliser une conservation en fonction d'un événement. Lorsque la conservation de l'objet est indéfinie, les applications utilisateur pourront la remplacer par une valeur finie par la suite. Par exemple, une société a établi une règle qui prévoit de conserver des dossiers d'employés pendant trois années après le départ de ceux-ci. Lorsqu'un employé est embauché dans l'entreprise, les dossiers qui le concernent peuvent être conservés sans limite de durée. Lorsque l'employé quitte l'entreprise, la conservation sans limite de durée est convertie en une conservation avec une durée limitée de trois ans à partir du moment présent, comme stipulé par la règle de la société. L'objet est ensuite protégé pendant trois ans après la modification de la durée de conservation. Un utilisateur ou une application tierce peut remplacer la conservation indéfinie par une conservation avec limite de durée en utilisant un kit SDK ou une API REST.
Conservation permanente
La conservation permanente garantit que les données ne peuvent être supprimées, jamais, par quiconque. Lisez attentivement la documentation et n'utilisez pas la conservation permanente sauf s'il existe un besoin impérieux en matière de réglementation ou de conformité pour le stockage de données permanent.
La conservation permanente ne peut être activée qu'au niveau d'un godet IBM Cloud Object Storage lorsque la politique de conservation est activée et que les utilisateurs peuvent sélectionner l'option de période de conservation permanente lors du téléchargement d'objets. Une fois activé, ce processus est irréversible et les objets téléchargés qui ont une durée de conservation permanente ne peuvent plus être supprimés. Il incombe aux utilisateurs de valider de leur côté s'il existe un besoin légitime de stocker des objets de manière permanente en utilisant les buckets Object Storage avec une politique de rétention.
Lorsque vous utilisez Immutable Object Storage, il vous appartient de veiller à ce que votre compte IBM Cloud soit conforme à chacune des règles et instructions IBM Cloud tant que les données sont soumises à une règle de conservation. Pour plus d'informations, voir les conditions du service IBM Cloud.
Immutable Object Storage et remarques relatives à diverses réglementations
Lorsqu'Immutable Object Storage est utilisé, il incombe au client de s'assurer que les fonctionnalités présentées peuvent être utilisées pour respecter les principales règles relatives au stockage et à la conservation d'enregistrements électroniques régies en principe par :
- Securities and Exchange Commission(SEC)Rule 17a-4(f),
- Financial Industry Regulatory Authority(FINRA)Rule 4511(c), et
- Règle de la Commodity Futures Trading Commission(CFTC)1.31(c)-(d)
Pour aider les clients à prendre des décisions réfléchies, IBM a engagé la société Cohasset Associates Inc. pour effectuer une évaluation indépendante d'Immutable Object Storage d'IBM. Consultez le rapport de Cohasset Associates Inc. qui fournit des détails sur l'évaluation de la fonctionnalité Immutable Object Storage de IBM Cloud Object Storage.
Audit de l'accès et des transactions
Les données de journal d'accès d'Immutable Object Storage permettant d'examiner les modifications des paramètres de conservation, de la durée de conservation des objets et de l'application de conservations légales sont disponibles au cas par cas en ouvrant un ticket de service client.
Utilisation de la console
Des règles de conservation peuvent être ajoutées à des compartiments vides nouveaux ou existants, et ne peuvent pas être retirées. Dans le cas d'un nouveau compartiment, vérifiez bien que vous créez le compartiment dans une région prise en charge, puis sélectionnez l'option Ajouter une règle de conservation. Dans le cas d'un compartiment existant, vérifiez que celui-ci ne comporte pas d'objet, puis accédez aux paramètres de configuration et cliquez sur le bouton Créer une règle au-dessous de la section Règle de conservation du compartiment. Dans les deux cas, définissez les durées de conservation minimum, maximum et par défaut.
Utilisation de l'API REST, de bibliothèques et de SDK
Plusieurs nouvelles API ont été introduites dans les SDK IBM Cloud Object Storage afin de fournir un support aux applications travaillant avec des politiques de conservation. Sélectionnez une langue ( HTTP, Java, JavaScript, ou Python ) au début de cette page pour voir les exemples qui utilisent le SDK Object Storage approprié.
Tous les exemples de code partent du principe qu'il existe un objet client appelé cos pouvant appeler les différentes méthodes. Pour plus de détails sur la création de clients, voir les guides SDK spécifiques.
Toutes les valeurs de date utilisées pour définir des durées de conservation sont exprimées au format GMT (Greenwich Mean Time). Un en-tête Content-MD5 ou un en-tête checksum (y compris x-amz-checksum-crc32,
x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1 ou x-amz-checksum-sha256) est nécessaire pour garantir l'intégrité des données. Notez qu'une valeur de hachage ou de somme
de contrôle est automatiquement envoyée lors de l'utilisation d'un SDK.
Ajout d'une règle de conservation à un compartiment existant
Cette implémentation de l'opération PUT utilise le paramètre de requête protection pour définir les paramètres de conservation d'un compartiment existant. Cette opération vous permet de définir ou modifier la période
de conservation minimale, par défaut et maximale. Cette opération vous permet également de modifier l'état de protection du compartiment.
Les objets écrits dans un compartiment protégé ne peuvent pas être supprimés tant que la période de protection n'est pas arrivée à expiration et que les conservations légales associées à l'objet n'ont pas toutes été retirées. La valeur de conservation par défaut du compartiment est attribuée à un objet, sauf si une valeur spécifique à l'objet est fournie lors de la création de l'objet. Lorsqu'ils sont écrasés, les objets des compartiments protégés auxquels plus aucune règle de conservation ne s'applique (la durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
Les valeurs minimales et maximales prises en charge pour les paramètres de la période de conservation MinimumRetention, DefaultRetention et MaximumRetention sont un minimum de 0 jour et un maximum de
365243 jours (1000 ans).
Un en-tête Content-MD5 ou un en-tête checksum (y compris x-amz-checksum-crc32, x-amz-checksum-crc32c,x-amz-checksum-crc64nvme, x-amz-checksum-sha1 ou x-amz-checksum-sha256)
est requis. Cette opération n'utilise pas d'autres paramètres de requête.
Pour plus d'informations sur les noeuds finaux, voir Noeuds finaux et emplacements de stockage.
Syntaxe
PUT https://{endpoint}/{bucket-name}?protection= # path style
PUT https://{bucket-name}.{endpoint}?protection= # virtual host style
Exemple de demande
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>
Exemple de réponse
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);
}
Vérification de la règle de conservation d'un compartiment
Cette implémentation d'une opération GET extrait les paramètres de conservation pour un compartiment existant.
Syntaxe
GET https://{endpoint}/{bucket-name}?protection= # path style
GET https://{bucket-name}.{endpoint}?protection= # virtual host style
Exemple de demande
GET /example-bucket?protection= HTTP/1.1
Authorization: {authorization-string}
x-amz-date: 20181011T190354Z
Content-Type: text/plain
Host: 67.228.254.193
Exemple de réponse
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>
Si aucune configuration de protection n'est associée au compartiment, le serveur répond en émettant un statut désactivé.
<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());
}
}
Téléchargement d'un objet dans un compartiment avec une règle de conservation
Cette amélioration de l'opération PUT permet d'ajouter trois nouveaux en-têtes de demande, deux pour spécifier la durée de conservation de différentes manières, et un pour ajouter une conservation légale au nouvel objet. De nouvelles
erreurs sont définies pour signaler les valeurs non admises contenues dans les nouveaux en-têtes, et si un objet est soumis à une durée de conservation, toute tentative d'écrasement échoue.
Lorsqu'ils sont écrasés, les objets des compartiments qui étaient soumis à une règle de conservation mais ne le sont plus (leur durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
Un en-tête Content-MD5 ou un en-tête checksum (y compris x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1 ou x-amz-checksum-sha256)
est nécessaire pour vérifier l'intégrité de la charge utile de tout type de demande de téléchargement d'objet vers un panier doté d'une politique de conservation.
| Valeur | Type | Description |
|---|---|---|
Retention-Period |
Entier non négatif (secondes) | Durée de conservation, exprimée en secondes, pendant laquelle stocker l'objet. L'objet ne peut être ni écrasé, ni supprimé tant que la durée de conservation n'est pas écoulée. Si cette zone et la zone Retention-Expiration-Date sont spécifiées, un code d'erreur 400 est renvoyé. Si aucune de ces deux zones n'est spécifiée, la période DefaultRetention du compartiment est utilisée. Zéro (0) est une valeur légale qui part
du principe que la durée de conservation minimale du compartiment est également fixée à 0. |
Retention-expiration-date |
Date (format ISO 8601) | Date à laquelle la suppression ou la modification de l'objet devient légale. Vous pouvez uniquement spécifier cette zone ou bien la zone d'en-tête Retention-Period. Si ces deux zones sont spécifiées, un code d'erreur 400 est renvoyé. Si aucune de ces deux zones n'est spécifiée, la période DefaultRetention du compartiment est utilisée. Le format ISO 8601 pris en charge est [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z ou [YYYY][MM][DD]T[hh][mm][ss]Z (par exemple, 2020-11-28T03:10:01Z ou 20201128T031001Z sont tous deux valides). |
Retention-legal-hold-id |
Chaîne | Conservation légale unique à appliquer à l'objet. Une conservation légale est une chaîne comportant Y caractères. L'objet ne peut être ni écrasé ni supprimé tant que les conservations légales associées à l'objet n'ont pas toutes été retirées. |
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);
}
Ajout ou retrait d'une conservation légale dans un objet
Cette implémentation de l'opération POST utilise le paramètre de requête legalHold ainsi que les paramètres de requête add et remove pour ajouter ou retirer une conservation légale d'un objet
protégé dans un compartiment protégé.
L'objet peut prendre en charge 100 conservations légales :
- L'identificateur d'une conservation légale est une chaîne comprise entre 1 et 64 caractères maximum. Les caractères valables sont les lettres, les chiffres,
!,_,.,*,(,),-, et'. - Si la tentative d'ajout de la conservation légale spécifiée dépasse le seuil de 100 conservations légales affectées à l'objet, l'opération d'ajout échoue et un code d'erreur
400est renvoyé. - Si un identificateur est trop long, il n'est pas ajouté à l'objet et un code d'erreur
400est renvoyé. - Si un identificateur contient des caractères non valides, il n'est pas ajouté à l'objet et un code d'erreur
400est renvoyé. - Si un identificateur est déjà en cours d'utilisation sur un objet, la conservation légale existante n'est pas modifiée et la réponse indique que l'identificateur était déjà utilisé et renvoie un code d'erreur
409. - Si un objet ne comporte pas de métadonnées de durée de conservation, un code d'erreur
400est renvoyé et l'ajout ou le retrait d'une conservation légale ne sont pas autorisés.
La présence d'un en-tête de durée de conservation est obligatoire, sinon, une erreur 400 est renvoyée.
Syntaxe
POST https://{endpoint}/{bucket-name}/{object-name}?legalHold # path style
POST https://{bucket-name}.{endpoint}/{object-name}?legalHold= # virtual host style
Exemple de demande
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
Exemple de réponse
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);
}
Prolongement de la durée de conservation d'un objet
Cette implémentation de l'opération POST utilise le paramètre de requête extendRetention pour prolonger la durée de conservation d'un objet protégé dans un compartiment protégé.
La durée de conservation d'un objet ne peut être que prolongée. La valeur actuellement configurée ne peut pas être diminuée.
La valeur de prolongement de la conservation est définie de l'une des trois façons suivantes :
- En ajoutant une durée supplémentaire par rapport à la valeur en cours (
Additional-Retention-Periodou méthode similaire) - En définissant une nouvelle période de prolongement, exprimée en secondes (
Extend-Retention-From-Current-Timeou méthode similaire) - En définissant une nouvelle date d'expiration de la conservation de l'objet (
New-Retention-Expiration-Dateou méthode similaire)
La durée de conservation en cours qui est stockée dans les métadonnées de l'objet est soit augmentée de la durée prolongée indiquée, soit remplacée par la nouvelle valeur, en fonction du paramètre défini dans la demande extendRetention.
Dans tous les cas, le paramètre de prolongement de la conservation est vérifié par rapport à la durée de conservation en cours et le paramètre de prolongement n'est accepté que si la durée de conservation mise à jour est supérieure à la
durée de conservation en cours.
Le format ISO 8601 pris en charge pour New-Retention-Expiration-Date est [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z ou [YYYY][MM][DD]T[hh][mm][ss]Z (par exemple, 2020-11-28T03:10:01Z ou 20201128T031001Z sont tous deux valides).
Lorsqu'ils sont écrasés, les objets des compartiments protégés auxquels plus aucune règle de conservation ne s'applique (la durée de conservation est arrivée à expiration et aucune conservation légale n'est associée à l'objet) sont de nouveau soumis à une durée de conservation. La nouvelle durée de conservation peut être fournie dans la demande d'écrasement de l'objet ou bien la durée de conservation par défaut du compartiment est attribuée à l'objet.
Syntaxe
POST https://{endpoint}/{bucket-name}/{object-name}?extendRetention= # path style
POST https://{bucket-name}.{endpoint}/{object-name}?extendRetention= # virtual host style
Exemple de demande
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
Exemple de réponse
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);
}
Création de la liste des conservations légales associées à un objet
Cette implémentation de l'opération GET utilise le paramètre de requête legalHold pour renvoyer la liste des conservations légales associées à un objet et l'état de conservation connexe dans un corps de réponse XML.
Cette opération renvoie les éléments suivants :
- La date de création de l'objet
- La durée de conservation, exprimée en secondes
- La date d'expiration de la conservation, calculée sur la base de la durée de conservation et de la date de création
- La liste des conservations légales
- L'identificateur de conservation légale
- L'horodatage correspondant à l'application de la conservation légale
Si aucune conservation légale n'est associée à l'objet, un élément LegalHoldSet vide est renvoyé. Si aucune durée de conservation n'est spécifiée pour l'objet, un code d'erreur 404 est renvoyé.
Syntaxe
GET https://{endpoint}/{bucket-name}/{object-name}?legalHold= # path style
GET https://{bucket-name}.{endpoint}/{object-name}?legalHold= # virtual host style
Exemple de demande
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
Exemple de réponse
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);
}
}