s3-secure 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/LICENSE.txt +201 -22
  4. data/README.md +39 -14
  5. data/lib/s3_secure/access_logs/base.rb +4 -0
  6. data/lib/s3_secure/access_logs/disable.rb +37 -0
  7. data/lib/s3_secure/access_logs/enable.rb +41 -0
  8. data/lib/s3_secure/access_logs/list.rb +25 -0
  9. data/lib/s3_secure/access_logs/show.rb +89 -0
  10. data/lib/s3_secure/aws_services/s3.rb +61 -0
  11. data/lib/s3_secure/aws_services.rb +4 -27
  12. data/lib/s3_secure/cli/access_logs.rb +32 -0
  13. data/lib/s3_secure/{abstract_base.rb → cli/base.rb} +4 -3
  14. data/lib/s3_secure/{batch.rb → cli/batch.rb} +1 -1
  15. data/lib/s3_secure/{encryption.rb → cli/encryption.rb} +10 -6
  16. data/lib/s3_secure/cli/help.rb +11 -0
  17. data/lib/s3_secure/cli/lifecycle.rb +33 -0
  18. data/lib/s3_secure/cli/policy.rb +31 -0
  19. data/lib/s3_secure/cli/public_access.rb +32 -0
  20. data/lib/s3_secure/cli/remediate_all.rb +12 -0
  21. data/lib/s3_secure/cli/say.rb +7 -0
  22. data/lib/s3_secure/{summary.rb → cli/summary.rb} +4 -4
  23. data/lib/s3_secure/cli/versioning.rb +31 -0
  24. data/lib/s3_secure/cli.rb +25 -3
  25. data/lib/s3_secure/command.rb +7 -0
  26. data/lib/s3_secure/encryption/base.rb +2 -2
  27. data/lib/s3_secure/encryption/disable.rb +6 -10
  28. data/lib/s3_secure/encryption/enable.rb +6 -12
  29. data/lib/s3_secure/encryption/list.rb +13 -17
  30. data/lib/s3_secure/encryption/show.rb +16 -10
  31. data/lib/s3_secure/help/batch.md +14 -0
  32. data/lib/s3_secure/help/encryption/list.md +5 -0
  33. data/lib/s3_secure/help/lifecycle/add.md +13 -0
  34. data/lib/s3_secure/help/lifecycle/list.md +22 -0
  35. data/lib/s3_secure/help/lifecycle/remove.md +5 -0
  36. data/lib/s3_secure/help/lifecycle/show.md +13 -0
  37. data/lib/s3_secure/help/policy/list.md +5 -0
  38. data/lib/s3_secure/lifecycle/add.rb +33 -0
  39. data/lib/s3_secure/lifecycle/base.rb +5 -0
  40. data/lib/s3_secure/lifecycle/builder.rb +47 -0
  41. data/lib/s3_secure/lifecycle/list.rb +24 -0
  42. data/lib/s3_secure/lifecycle/remove.rb +28 -0
  43. data/lib/s3_secure/lifecycle/show.rb +40 -0
  44. data/lib/s3_secure/policy/base.rb +2 -2
  45. data/lib/s3_secure/policy/checker.rb +1 -1
  46. data/lib/s3_secure/policy/document/base.rb +1 -1
  47. data/lib/s3_secure/policy/document/force_ssl_only_access.rb +1 -1
  48. data/lib/s3_secure/policy/document/force_ssl_only_access_remove.rb +1 -1
  49. data/lib/s3_secure/policy/document.rb +1 -1
  50. data/lib/s3_secure/policy/enforce.rb +7 -11
  51. data/lib/s3_secure/policy/list.rb +14 -18
  52. data/lib/s3_secure/policy/show.rb +12 -11
  53. data/lib/s3_secure/policy/unforce.rb +8 -11
  54. data/lib/s3_secure/public_access/base.rb +10 -0
  55. data/lib/s3_secure/public_access/block.rb +18 -0
  56. data/lib/s3_secure/public_access/list.rb +24 -0
  57. data/lib/s3_secure/public_access/show.rb +27 -0
  58. data/lib/s3_secure/public_access/unblock.rb +12 -0
  59. data/lib/s3_secure/summary/item.rb +1 -1
  60. data/lib/s3_secure/summary/items.rb +6 -9
  61. data/lib/s3_secure/version.rb +1 -1
  62. data/lib/s3_secure/versioning/base.rb +4 -0
  63. data/lib/s3_secure/versioning/disable.rb +19 -0
  64. data/lib/s3_secure/versioning/enable.rb +19 -0
  65. data/lib/s3_secure/versioning/list.rb +24 -0
  66. data/lib/s3_secure/versioning/show.rb +27 -0
  67. data/lib/s3_secure.rb +4 -2
  68. data/s3-secure.gemspec +6 -3
  69. data/spec/lib/lifecycle/builder_spec.rb +85 -0
  70. metadata +76 -11
  71. data/lib/s3_secure/help.rb +0 -9
  72. data/lib/s3_secure/policy.rb +0 -27
@@ -0,0 +1,32 @@
1
+ class S3Secure::CLI
2
+ class AccessLogs < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket access_logs setting"
6
+ long_desc Help.text("access_logs/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :access_logs, type: :boolean, desc: "Filter for access_logs: all, true, false"
9
+ def list
10
+ S3Secure::AccessLogs::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket access_logs"
14
+ long_desc Help.text("access_logs/show")
15
+ def show(bucket)
16
+ S3Secure::AccessLogs::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "enable BUCKET", "enable bucket access_logs"
20
+ long_desc Help.text("access_logs/enable")
21
+ option :target_bucket, desc: "Target s3 bucket"
22
+ def enable(bucket)
23
+ S3Secure::AccessLogs::Enable.new(options.merge(bucket: bucket)).run
24
+ end
25
+
26
+ desc "disable BUCKET", "disable bucket access_logs"
27
+ long_desc Help.text("access_logs/disable")
28
+ def disable(bucket)
29
+ S3Secure::AccessLogs::Disable.new(options.merge(bucket: bucket)).run
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,8 @@
1
- module S3Secure
2
- class AbstractBase
3
- include S3Secure::AwsServices
1
+ class S3Secure::CLI
2
+ class Base
4
3
  extend Memoist
4
+ include S3Secure::AwsServices
5
+ include Say
5
6
 
6
7
  def initialize(options={})
7
8
  @options = options
@@ -1,4 +1,4 @@
1
- module S3Secure
1
+ class S3Secure::CLI
2
2
  class Batch
3
3
  extend Memoist
4
4
 
@@ -1,28 +1,32 @@
1
- module S3Secure
2
- class Encryption < Command
1
+ class S3Secure::CLI
2
+ class Encryption < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
3
5
  desc "list", "List bucket encryptions"
4
6
  long_desc Help.text("encryption/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :encryption, type: :boolean, desc: "Filter for encryption: all, true, false"
5
9
  def list
6
- List.new(options).run
10
+ S3Secure::Encryption::List.new(options).run
7
11
  end
8
12
 
9
13
  desc "show BUCKET", "show bucket encryption"
10
14
  long_desc Help.text("encryption/show")
11
15
  def show(bucket)
12
- Show.new(options.merge(bucket: bucket)).run
16
+ S3Secure::Encryption::Show.new(options.merge(bucket: bucket)).run
13
17
  end
14
18
 
15
19
  desc "enable BUCKET", "enable bucket encryption"
16
20
  long_desc Help.text("encryption/enable")
17
21
  option :kms_key, desc: "KMS Key Id. If this is set will use sse_algorithm=aws:kms Otherwise will use sse_algorithm=AES256"
18
22
  def enable(bucket)
19
- Enable.new(options.merge(bucket: bucket)).run
23
+ S3Secure::Encryption::Enable.new(options.merge(bucket: bucket)).run
20
24
  end
21
25
 
22
26
  desc "disable BUCKET", "disable bucket encryption"
23
27
  long_desc Help.text("encryption/disable")
24
28
  def disable(bucket)
25
- Disable.new(options.merge(bucket: bucket)).run
29
+ S3Secure::Encryption::Disable.new(options.merge(bucket: bucket)).run
26
30
  end
27
31
  end
28
32
  end
@@ -0,0 +1,11 @@
1
+ class S3Secure::CLI
2
+ class Help
3
+ class << self
4
+ def text(namespaced_command)
5
+ path = namespaced_command.to_s.gsub(':','/')
6
+ path = File.expand_path("../help/#{path}.md", __FILE__)
7
+ IO.read(path) if File.exist?(path)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ class S3Secure::CLI
2
+ class Lifecycle < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket lifecycles"
6
+ long_desc Help.text("lifecycle/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :lifecycle, desc: "Filter for lifecycle: all, true, false"
9
+ def list
10
+ S3Secure::Lifecycle::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket lifecycle"
14
+ long_desc Help.text("lifecycle/show")
15
+ def show(bucket)
16
+ S3Secure::Lifecycle::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "add BUCKET", "add bucket lifecycle"
20
+ long_desc Help.text("lifecycle/add")
21
+ option :additive, type: :boolean, desc: "Force adding another lifecycle rule even if one exists. Note, may fail, need a different prefix filter"
22
+ option :prefix, desc: "Filter prefix. Used with additive mode."
23
+ def add(bucket)
24
+ S3Secure::Lifecycle::Add.new(options.merge(bucket: bucket)).run
25
+ end
26
+
27
+ desc "remove BUCKET", "remove bucket lifecycle"
28
+ long_desc Help.text("lifecycle/remove")
29
+ def remove(bucket)
30
+ S3Secure::Lifecycle::Remove.new(options.merge(bucket: bucket)).run
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ class S3Secure::CLI
2
+ class Policy < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket policies"
6
+ long_desc Help.text("policy/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :policy, type: :boolean, desc: "Filter for policy: all, true, false"
9
+ def list
10
+ S3Secure::Policy::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket policy"
14
+ long_desc Help.text("policy/show")
15
+ def show(bucket)
16
+ S3Secure::Policy::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "enforce_ssl BUCKET", "Add enforce ssl bucket policy"
20
+ long_desc Help.text("policy/enforce_ssl")
21
+ def enforce_ssl(bucket)
22
+ S3Secure::Policy::Enforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
23
+ end
24
+
25
+ desc "unforce_ssl BUCKET", "Remove enforce ssl bucket policy"
26
+ long_desc Help.text("policy/unforce_ssl")
27
+ def unforce_ssl(bucket)
28
+ S3Secure::Policy::Unforce.new(options.merge(bucket: bucket, sid: "ForceSSLOnlyAccess")).run
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ class S3Secure::CLI
2
+ class PublicAccess < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket public access policy"
6
+ long_desc Help.text("public_access/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :blocked, desc: "Filter for public_access: all, true, false"
9
+ def list
10
+ S3Secure::PublicAccess::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket public_access"
14
+ long_desc Help.text("public_access/show")
15
+ def show(bucket)
16
+ S3Secure::PublicAccess::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "block BUCKET", "block bucket public_access"
20
+ long_desc Help.text("public_access/block")
21
+ option :prefix, desc: "Filter prefix. Used with mode."
22
+ def block(bucket)
23
+ S3Secure::PublicAccess::Block.new(options.merge(bucket: bucket)).run
24
+ end
25
+
26
+ desc "unblock BUCKET", "unblock bucket public_access"
27
+ long_desc Help.text("public_access/unblock")
28
+ def unblock(bucket)
29
+ S3Secure::PublicAccess::Unblock.new(options.merge(bucket: bucket)).run
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ class S3Secure::CLI
2
+ class RemediateAll < Base
3
+ def run
4
+ o = @options.merge(bucket: @bucket)
5
+ Encryption::Enable.new(o).run
6
+ Policy::Enforce.new(o.merge(sid: "ForceSSLOnlyAccess")).run
7
+ Versioning::Enable.new(o).run
8
+ Lifecycle::Add.new(o).run
9
+ AccessLogs::Enable.new(o).run
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ class S3Secure::CLI
2
+ module Say
3
+ def say(msg)
4
+ puts msg unless @options[:quiet]
5
+ end
6
+ end
7
+ end
@@ -1,9 +1,9 @@
1
- module S3Secure
2
- class Summary < AbstractBase
1
+ class S3Secure::CLI
2
+ class Summary < Base
3
3
  def run
4
- $stderr.puts("Determining bucket security-related settings...")
4
+ $stderr.puts("Determining bucket security-related settings. Can take a while for lots of buckets...")
5
5
  data = [%w[Bucket SSL? Encrypted?]]
6
- items = Items.new(@options, buckets)
6
+ items = S3Secure::Summary::Items.new(@options, buckets)
7
7
  items.filtered_items.each do |i|
8
8
  data << [i.bucket, i.ssl, i.encrypted]
9
9
  end
@@ -0,0 +1,31 @@
1
+ class S3Secure::CLI
2
+ class Versioning < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
+
5
+ desc "list", "List bucket versionings"
6
+ long_desc Help.text("versioning/list")
7
+ option :format, desc: "Format options: #{CliFormat.formats.join(', ')}"
8
+ option :versioning, desc: "Filter for versioning: all, true, false"
9
+ def list
10
+ S3Secure::Versioning::List.new(options).run
11
+ end
12
+
13
+ desc "show BUCKET", "show bucket versioning"
14
+ long_desc Help.text("versioning/show")
15
+ def show(bucket)
16
+ S3Secure::Versioning::Show.new(options.merge(bucket: bucket)).run
17
+ end
18
+
19
+ desc "enable BUCKET", "enable bucket versioning"
20
+ long_desc Help.text("versioning/enable")
21
+ def enable(bucket)
22
+ S3Secure::Versioning::Enable.new(options.merge(bucket: bucket)).run
23
+ end
24
+
25
+ desc "disable BUCKET", "disable bucket versioning"
26
+ long_desc Help.text("versioning/disable")
27
+ def disable(bucket)
28
+ S3Secure::Versioning::Disable.new(options.merge(bucket: bucket)).run
29
+ end
30
+ end
31
+ end
data/lib/s3_secure/cli.rb CHANGED
@@ -1,8 +1,12 @@
1
1
  module S3Secure
2
- class CLI < Command
3
- class_option :verbose, type: :boolean
2
+ class CLI < S3Secure::Command
3
+ class_option :quiet, type: :boolean
4
4
  class_option :noop, type: :boolean
5
5
 
6
+ desc "access_logs SUBCOMMAND", "access_logs subcommands"
7
+ long_desc Help.text(:access_logs)
8
+ subcommand "access_logs", AccessLogs
9
+
6
10
  desc "encryption SUBCOMMAND", "encryption subcommands"
7
11
  long_desc Help.text(:encryption)
8
12
  subcommand "encryption", Encryption
@@ -11,10 +15,28 @@ module S3Secure
11
15
  long_desc Help.text(:policy)
12
16
  subcommand "policy", Policy
13
17
 
18
+ desc "versioning SUBCOMMAND", "versioning subcommands"
19
+ long_desc Help.text(:versioning)
20
+ subcommand "versioning", Versioning
21
+
22
+ desc "lifecycle SUBCOMMAND", "lifecycle subcommands"
23
+ long_desc Help.text(:lifecycle)
24
+ subcommand "lifecycle", Lifecycle
25
+
26
+ desc "public_access SUBCOMMAND", "public_access subcommands"
27
+ long_desc Help.text(:public_access)
28
+ subcommand "public_access", PublicAccess
29
+
30
+ desc "remediate_all BUCKET", "Remediate all. For more fine-grain control use each of the commands directly."
31
+ long_desc Help.text("remediate_all")
32
+ def remediate_all(bucket)
33
+ RemediateAll.new(options.merge(bucket: bucket)).run
34
+ end
35
+
14
36
  desc "summary", "Summarize buckets"
15
37
  long_desc Help.text("summary")
16
- option :ssl, default: "any", desc: "filter for ssl enforcement. Examples: any, yes, no"
17
38
  option :encrypted, default: "any", desc: "filter for encryption enabled. Examples: any, yes, no"
39
+ option :ssl, default: "any", desc: "filter for ssl enforcement. Examples: any, yes, no"
18
40
  def summary
19
41
  Summary.new(options).run
20
42
  end
@@ -77,6 +77,13 @@ module S3Secure
77
77
  def website
78
78
  ""
79
79
  end
80
+
81
+ # https://github.com/erikhuda/thor/issues/244
82
+ # Deprecation warning: Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `Lono::CLI`
83
+ # You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.
84
+ def exit_on_failure?
85
+ true
86
+ end
80
87
  end
81
88
  end
82
89
  end
@@ -1,4 +1,4 @@
1
- class S3Secure::Encryption
2
- class Base < S3Secure::AbstractBase
1
+ module S3Secure::Encryption
2
+ class Base < S3Secure::CLI::Base
3
3
  end
4
4
  end
@@ -1,17 +1,13 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Disable < Base
3
3
  def run
4
- @s3 = s3_regional_client(@bucket)
4
+ show = Show.new(@options)
5
5
 
6
- list = S3Secure::Encryption::List.new(@options)
7
- list.set_s3(@s3)
8
-
9
- rules = list.get_encryption_rules(@bucket)
10
- if rules
11
- @s3.delete_bucket_encryption(bucket: @bucket) # returns resp = #<struct Aws::EmptyStructure>
12
- puts "Bucket #{@bucket} encryption has been removed"
6
+ if show.enabled?
7
+ s3.delete_bucket_encryption(bucket: @bucket) # returns resp = #<struct Aws::EmptyStructure>
8
+ say "Bucket #{@bucket} encryption has been removed"
13
9
  else
14
- puts "WARN: Bucket #{@bucket} is not configured with encryption at the bucket level".color(:yellow)
10
+ say "Bucket #{@bucket} is not configured with encryption at the bucket level"
15
11
  end
16
12
  end
17
13
  end
@@ -1,16 +1,11 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Enable < Base
3
3
  def run
4
- @s3 = s3_regional_client(@bucket)
4
+ show = Show.new(@options)
5
5
 
6
- list = S3Secure::Encryption::List.new(@options)
7
- list.set_s3(@s3)
8
-
9
- rules = list.get_encryption_rules(@bucket)
10
- if rules
6
+ if show.enabled?
11
7
  # check rules to see if encryption is already set of some sort
12
- puts "Bucket #{@bucket} already has encryption rules:"
13
- puts rules.map(&:to_h)
8
+ say "Bucket #{@bucket} already has encryption rules:"
14
9
  else
15
10
  # Set encryption rules
16
11
  # Ruby docs: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_bucket_encryption-instance_method
@@ -18,12 +13,11 @@ class S3Secure::Encryption
18
13
  #
19
14
  # put_bucket_encryption returns #<struct Aws::EmptyStructure>
20
15
  #
21
- @s3.put_bucket_encryption(
16
+ s3.put_bucket_encryption(
22
17
  bucket: @bucket,
23
18
  server_side_encryption_configuration: {
24
19
  rules: [rule]})
25
- puts "Encyption enabled on bucket #{@bucket} with rules:"
26
- pp rule
20
+ say "Encyption enabled on bucket #{@bucket} with rules:"
27
21
  end
28
22
  end
29
23
 
@@ -1,28 +1,24 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class List < Base
3
3
  def run
4
+ presenter = CliFormat::Presenter.new(@options)
5
+ presenter.header = ["Bucket", "Has Encryption?"]
6
+
4
7
  buckets.each do |bucket|
5
- @s3 = s3_regional_client(bucket)
6
- puts "Policy for bucket #{bucket.color(:green)}"
7
- encryption_rules = get_encryption_rules(bucket)
8
+ $stderr.puts "Getting encryption for bucket #{bucket.color(:green)}"
9
+ show = Show.new(bucket: bucket)
8
10
 
9
- if encryption_rules
10
- puts encryption_rules
11
+ row = [bucket, show.enabled?]
12
+ if @options[:encryption].nil?
13
+ presenter.rows << row # always show policy
14
+ elsif @options[:encryption]
15
+ presenter.rows << row if show.enabled? # only show if bucket has some encryption rules
11
16
  else
12
- puts "Bucket does not have bucket encryption enabled"
17
+ presenter.rows << row unless show.enabled? # only show if bucket doesnt have any encryption rules
13
18
  end
14
19
  end
15
- end
16
-
17
- def get_encryption_rules(bucket)
18
- resp = @s3.get_bucket_encryption(bucket: bucket)
19
- resp.server_side_encryption_configuration.rules # Aws::Xml::DefaultList object
20
- rescue Aws::S3::Errors::ServerSideEncryptionConfigurationNotFoundError
21
- end
22
20
 
23
- # Useful when calling List outside of the list CLI
24
- def set_s3(client)
25
- @s3 = client
21
+ presenter.show
26
22
  end
27
23
  end
28
24
  end
@@ -1,18 +1,24 @@
1
- class S3Secure::Encryption
1
+ module S3Secure::Encryption
2
2
  class Show < Base
3
3
  def run
4
- @s3 = s3_regional_client(@bucket)
5
-
6
- list = S3Secure::Encryption::List.new(@options)
7
- list.set_s3(@s3)
8
-
9
- rules = list.get_encryption_rules(@bucket)
10
4
  if rules
11
- puts "Bucket #{@bucket} is configured with these encryption rules:"
12
- puts rules.map(&:to_h)
5
+ say "Bucket #{@bucket} is configured with these encryption rules:"
6
+ say rules.map(&:to_h)
13
7
  else
14
- puts "Bucket #{@bucket} is not configured with encryption at the bucket level"
8
+ say "Bucket #{@bucket} is not configured with encryption at the bucket level"
15
9
  end
10
+ rules
11
+ end
12
+
13
+ def enabled?
14
+ !!(rules && !rules.empty?)
15
+ end
16
+
17
+ def rules
18
+ resp = s3.get_bucket_encryption(bucket: @bucket)
19
+ resp.server_side_encryption_configuration.rules # Aws::Xml::DefaultList object
20
+ rescue Aws::S3::Errors::ServerSideEncryptionConfigurationNotFoundError
16
21
  end
22
+ memoize :rules
17
23
  end
18
24
  end
@@ -0,0 +1,14 @@
1
+ There are some supported batch commands:
2
+
3
+ s3-secure batch encryption enable FILE.txt
4
+ s3-secure batch encryption disable FILE.txt
5
+ s3-secure batch policy enforce_ssl FILE.txt
6
+ s3-secure batch policy unforce_ssl FILE.txt
7
+
8
+ The format of FILE.txt is a list of bucket names separated by newlines. Example:
9
+
10
+ buckets.txt:
11
+
12
+ my-bucket-1
13
+ my-bucket-2
14
+
@@ -0,0 +1,5 @@
1
+ ## Examples
2
+
3
+ s3-secure encryption list # shows all buckets with and without polices
4
+ s3-secure encryption list --encryption # only shows buckets with encryption
5
+ s3-secure encryption list --no-encryption # only shows buckets without encryption
@@ -0,0 +1,13 @@
1
+ ## Example
2
+
3
+ $ s3-secure lifecycle add a-test-bucket-in-us-east-1
4
+ Added lifecycle policy to bucket a-test-bucket-in-us-east-1
5
+ $
6
+
7
+ By default, the add command will only add a lifecycle policy if you none exists.
8
+
9
+ It may be useful to test adding an additional lifecycle policy, for this you can use both the `--additive` and `--prefix` options. Note, you must make sure that the lifecycle policies can work together. For example, they must have different prefixes.
10
+
11
+ $ s3-secure lifecycle add a-test-bucket-in-us-east-1 --additive --prefix /foo
12
+ Added lifecycle policy to bucket a-test-bucket-in-us-east-1
13
+ $
@@ -0,0 +1,22 @@
1
+ ## Examples
2
+
3
+ $ s3-secure lifecycle list
4
+ +----------------------------+----------------------+
5
+ | Bucket | Has Lifecycle Rules? |
6
+ +----------------------------+----------------------+
7
+ | a-test-bucket-in-us-east-1 | false |
8
+ | a-test-bucket-in-us-west-1 | true |
9
+ +----------------------------+----------------------+
10
+ $ s3-secure lifecycle list --lifecycle true
11
+ +----------------------------+----------------------+
12
+ | Bucket | Has Lifecycle Rules? |
13
+ +----------------------------+----------------------+
14
+ | a-test-bucket-in-us-west-1 | true |
15
+ +----------------------------+----------------------+
16
+ $ s3-secure lifecycle list --lifecycle false
17
+ +----------------------------+----------------------+
18
+ | Bucket | Has Lifecycle Rules? |
19
+ +----------------------------+----------------------+
20
+ | a-test-bucket-in-us-east-1 | false |
21
+ +----------------------------+----------------------+
22
+ $
@@ -0,0 +1,5 @@
1
+ ## Examples
2
+
3
+ $ s3-secure lifecycle remove a-test-bucket-in-us-east-1
4
+ Removed the s3-secure-automated-cleanup lifecycle rule on bucket a-test-bucket-in-us-east-1
5
+ $
@@ -0,0 +1,13 @@
1
+ ## Examples
2
+
3
+ $ s3-secure lifecycle show a-test-bucket-in-us-east-1
4
+ This S3 bucket has lifecycle rules
5
+ Bucket lifecycle details:
6
+ {:rules=>
7
+ [{:expiration=>{:expired_object_delete_marker=>true},
8
+ :id=>"s3-secure-automated-cleanup",
9
+ :prefix=>"/bar",
10
+ :status=>"Enabled",
11
+ :noncurrent_version_expiration=>{:noncurrent_days=>365},
12
+ :abort_incomplete_multipart_upload=>{:days_after_initiation=>30}}]}
13
+ $
@@ -0,0 +1,5 @@
1
+ ## Examples
2
+
3
+ s3-secure policy list # shows all buckets with and without polices
4
+ s3-secure policy list --policy # only shows buckets with policy
5
+ s3-secure policy list --no-policy # only shows buckets without policy
@@ -0,0 +1,33 @@
1
+ module S3Secure::Lifecycle
2
+ class Add < Base
3
+ RULE_ID = Base::RULE_ID
4
+
5
+ def run
6
+ show = Show.new(@options)
7
+ if @options[:additive]
8
+ current_rules = show.get_lifecycle_rules(@bucket)
9
+ builder = Builder.new(current_rules)
10
+ rules = builder.rules_with_addition(@options[:prefix])
11
+ if current_rules.size == rules.size
12
+ say "WARN: rule wasnt added because a #{RULE_ID} already exists".color(:yellow)
13
+ else
14
+ s3.put_bucket_lifecycle_configuration(
15
+ bucket: @bucket, # required
16
+ lifecycle_configuration: {rules: rules}
17
+ )
18
+ end
19
+ elsif show.any?
20
+ say "Bucket #{@bucket} is has a lifecycle policy already."
21
+ return
22
+ else
23
+ options = {
24
+ bucket: @bucket, # required
25
+ lifecycle_configuration: {rules: [Builder::DEFAULT_RULE]}
26
+ }
27
+ s3.put_bucket_lifecycle_configuration(options)
28
+ end
29
+
30
+ say "Added lifecycle policy to bucket #{@bucket}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module S3Secure::Lifecycle
2
+ class Base < S3Secure::CLI::Base
3
+ RULE_ID = "s3-secure-automated-cleanup"
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ module S3Secure::Lifecycle
2
+ class Builder
3
+ # Note: put_bucket_lifecycle_configuration and put_bucket_lifecycle understand different payloads.
4
+ # put_bucket_lifecycle is old and shouldnt be used
5
+ RULE_ID = Base::RULE_ID
6
+ DEFAULT_RULE = {
7
+ expiration: {expired_object_delete_marker: true},
8
+ id: RULE_ID,
9
+ status: "Enabled",
10
+ prefix: "",
11
+ noncurrent_version_expiration: {noncurrent_days: 365},
12
+ abort_incomplete_multipart_upload: {days_after_initiation: 30}
13
+ }
14
+
15
+ def initialize(rules)
16
+ @rules = rules || []
17
+ end
18
+
19
+ def has?(id)
20
+ !!@rules.detect { |rule| rule[:id] == id }
21
+ end
22
+
23
+ def rules_with_addition(prefix=nil)
24
+ rules = @rules.dup
25
+ unless has?(RULE_ID)
26
+ rule = DEFAULT_RULE
27
+ rule[:prefix] = prefix if prefix
28
+ rules << rule
29
+ end
30
+ rules
31
+ end
32
+
33
+ def rules_with_removal
34
+ rules = @rules.dup
35
+ rules.delete_if { |rule| rule[:id] == RULE_ID }
36
+ rules
37
+ end
38
+
39
+ def build(type)
40
+ if type == :remove
41
+ remove_lifecycle
42
+ else
43
+ add_lifecycle
44
+ end
45
+ end
46
+ end
47
+ end