Skip to content

Commit

Permalink
Merge pull request #1297 from withings-sas/legalhold_and_retention
Browse files Browse the repository at this point in the history
Add setobjectretention and setobjectlegalhold commands
  • Loading branch information
fviard authored Oct 20, 2023
2 parents 323fa07 + 3fa512d commit 7e7b325
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
27 changes: 27 additions & 0 deletions S3/S3.py
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,33 @@ def get_policy(self, uri):
response = self.send_request(request)
return decode_from_s3(response['data'])

def set_object_legal_hold(self, uri, legal_hold_status):
body = '<LegalHold xmlns="http://s3.amazonaws.com/doc/2006-03-01/">'
body += '<Status>%s</Status>' % legal_hold_status
body += '</LegalHold>'
headers = SortedDict(ignore_case = True)
headers['content-type'] = 'application/xml'
headers['content-md5'] = generate_content_md5(body)
request = self.create_request("OBJECT_PUT", uri = uri,
headers = headers, body = body,
uri_params = {'legal-hold': None})
response = self.send_request(request)
return response

def set_object_retention(self, uri, mode, retain_until_date):
body = '<Retention xmlns="http://s3.amazonaws.com/doc/2006-03-01/">'
body += '<Mode>%s</Mode>' % mode
body += '<RetainUntilDate>%s</RetainUntilDate>' % retain_until_date
body += '</Retention>'
headers = SortedDict(ignore_case = True)
headers['content-type'] = 'application/xml'
headers['content-md5'] = generate_content_md5(body)
request = self.create_request("OBJECT_PUT", uri = uri,
headers = headers, body = body,
uri_params = {'retention': None})
response = self.send_request(request)
return response

def set_policy(self, uri, policy):
headers = SortedDict(ignore_case = True)
# TODO check policy is proper json string
Expand Down
47 changes: 47 additions & 0 deletions s3cmd
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import shutil
import socket
import subprocess
import tempfile
import datetime
import time
import traceback

Expand Down Expand Up @@ -2197,6 +2198,49 @@ def cmd_setacl(args):
update_acl(s3, uri, seq_label)
return EX_OK

def cmd_setobjectlegalhold(args):
cfg = Config()
s3 = S3(cfg)
legal_hold_status = args[0]
uri = S3Uri(args[1])

if legal_hold_status not in ["ON", "OFF"]:
raise ParameterError("Incorrect status")

if cfg.dry_run:
return EX_OK

response = s3.set_object_legal_hold(uri, legal_hold_status)

debug(u"response - %s" % response['status'])
if response['status'] == 204:
output(u"%s: Legal Hold updated" % uri)
return EX_OK

def cmd_setobjectretention(args):
cfg = Config()
s3 = S3(cfg)
mode = args[0]
retain_until_date = args[1]
uri = S3Uri(args[2])

if mode not in ["COMPLIANCE", "GOVERNANCE"]:
raise ParameterError("Incorrect mode")

try:
datetime.datetime.strptime(retain_until_date, '%Y-%m-%dT%H:%M:%SZ')
except ValueError:
raise ParameterError("Incorrect data format, should be YYYY-MM-DDTHH:MM:SSZ")

if cfg.dry_run:
return EX_OK

response = s3.set_object_retention(uri, mode, retain_until_date)

debug(u"response - %s" % response['status'])
if response['status'] == 204:
output(u"%s: Retention updated" % uri)

def cmd_setversioning(args):
cfg = Config()
s3 = S3(cfg)
Expand Down Expand Up @@ -2821,6 +2865,9 @@ def get_commands_list():
{"cmd":"setacl", "label":"Modify Access control list for Bucket or Files", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1},
{"cmd":"setversioning", "label":"Modify Bucket Versioning", "param":"s3://BUCKET enable|disable", "func":cmd_setversioning, "argc":2},

{"cmd":"setobjectlegalhold", "label":"Modify Object Legal Hold", "param":"STATUS s3://BUCKET/OBJECT", "func":cmd_setobjectlegalhold, "argc":2},
{"cmd":"setobjectretention", "label":"Modify Object Retention", "param":"MODE RETAIN_UNTIL_DATE s3://BUCKET/OBJECT", "func":cmd_setobjectretention, "argc":3},

{"cmd":"setpolicy", "label":"Modify Bucket Policy", "param":"FILE s3://BUCKET", "func":cmd_setpolicy, "argc":2},
{"cmd":"delpolicy", "label":"Delete Bucket Policy", "param":"s3://BUCKET", "func":cmd_delpolicy, "argc":1},
{"cmd":"setcors", "label":"Modify Bucket CORS", "param":"FILE s3://BUCKET", "func":cmd_setcors, "argc":2},
Expand Down
6 changes: 6 additions & 0 deletions s3cmd.1
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ Move object
s3cmd \fBsetacl\fR \fIs3://BUCKET[/OBJECT]\fR
Modify Access control list for Bucket or Files
.TP
s3cmd \fBsetobjectlegalhold\fR \fISTATUS s3://BUCKET\fR
Modify Object Legal Hold
.TP
s3cmd \fBsetobjectretention\fR \fIMODE RETAIN_UNTIL_DATE s3://BUCKET\fR
Modify Object Retention
.TP
s3cmd \fBsetpolicy\fR \fIFILE s3://BUCKET\fR
Modify Bucket Policy
.TP
Expand Down

0 comments on commit 7e7b325

Please sign in to comment.