diff --git a/README.md b/README.md index 4b2c4c8..4ee00a9 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ object-holder --bucket [--prefix ] [--update-expires-within ] + [--lock-mode ] --lock-for [--threads ] ``` @@ -23,10 +24,14 @@ If you're using name-brand S3, you don't need to specify endpoint, just the regi The aws keys can be fed in via the cli flags, via the usual env variables (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`), via instance metadata, etc. -`--bucket`, obviously, specifies the bucket you'd like to renew object locks in, and `--prefix` can be used to limit operation to only the objects with a name starting with a given prefix in the bucket. +`--bucket`, obviously, specifies the bucket you'd like to renew object locks in -`--lock-for` specifies how many seconds the newly-made locks should last, counting from time of program start. +`--prefix` can be used to limit operation to only the objects with a name starting with a given prefix in the bucket. `--update-expires-within-seconds` can be used to limit operation to only objects whose existing lock expires within that many seconds. This might save you a bit depending on your s3 provider's API request pricing. For example, in name-brand S3, it costs about 10x more to set a lock than it does to check it, so this flag might save you a bit there. Meanwhile, in Backblaze B2, setting an object hold is free but checking an existing hold costs money, so there's no reason to do the extra check. -Lastly, `--threads` specifies how many concurrent threads we should have getting/setting object holds (default 1024). Some s3-compatible providers' APIs seem to misbehave when sequentially updating object metadata at high speeds like this script does, so here's a handy knob to adjust the speed in case you need it. +`--lock-mode` specifies the type of object lock to apply: `governance` or `compliance` (default: compliance). Governance mode allows users with specific permissions to remove or modify the lock, while compliance mode prevents anyone from removing the lock until the retention period expires. + +`--lock-for` specifies how many seconds the newly-made locks should last, counting from time of program start. + +`--threads` specifies how many concurrent threads we should have getting/setting object holds (default 1024). Some s3-compatible providers' APIs seem to misbehave when sequentially updating object metadata at high speeds like this script does, so here's a handy knob to adjust the speed in case you need it. diff --git a/main.go b/main.go index 5bdb346..80cf90d 100644 --- a/main.go +++ b/main.go @@ -28,20 +28,33 @@ var updateExpiresWithin = flag.Int("update-expires-within", 0, "only update obje var lockFor = flag.Int("lock-for", 90*24*3600, "how many seconds to renew the object lock for (default 90 days)") var threadCount = flag.Int("threads", 1024, "how many objects to operate on at a time") +var lockMode = flag.String("lock-mode", "compliance", "object lock mode (governance or compliance)") type objectLockOptions struct { CheckExistingHold bool UpdateExpiry time.Time LockExpiry time.Time + Mode types.ObjectLockRetentionMode } func main() { flag.Parse() + var mode types.ObjectLockRetentionMode + switch strings.ToLower(*lockMode) { + case "governance": + mode = types.ObjectLockRetentionModeGovernance + case "compliance": + mode = types.ObjectLockRetentionModeCompliance + default: + log.Fatalln("Invalid lock mode. Must be 'governance' or 'compliance'") + } + objectLockArguments := objectLockOptions{ CheckExistingHold: *updateExpiresWithin != 0, UpdateExpiry: time.Now().Add(time.Second * time.Duration(*updateExpiresWithin)), LockExpiry: time.Now().Add(time.Second * time.Duration(*lockFor)), + Mode: mode, } options := []func(*config.LoadOptions) error{} @@ -134,8 +147,7 @@ func checkAndRenewObjectLock(svc *s3.Client, options objectLockOptions, object s Bucket: bucket, Key: &object, Retention: &types.ObjectLockRetention{ - // TODO: add flag for governance mode - Mode: "COMPLIANCE", + Mode: options.Mode, RetainUntilDate: aws.Time(options.LockExpiry), }, })