class Lono::S3::Bucket

Constants

STACK_NAME

Public Class Methods

check_aws_setup!() click to toggle source
# File lib/lono/s3/bucket.rb, line 23
def check_aws_setup!
  AwsSetup.new.check!
end
name() click to toggle source
# File lib/lono/s3/bucket.rb, line 10
def name
  return @@name if @@name # only memoize once bucket has been created

  check_aws_setup!

  stack = new.find_stack
  return unless stack

  resp = cfn.describe_stack_resources(stack_name: STACK_NAME)
  bucket = resp.stack_resources.find { |r| r.logical_resource_id == "Bucket" }
  @@name = bucket.physical_resource_id # actual bucket name
end
new(options={}) click to toggle source
# File lib/lono/s3/bucket.rb, line 28
def initialize(options={})
  @options = options
end

Public Instance Methods

bucket_name() click to toggle source
# File lib/lono/s3/bucket.rb, line 53
def bucket_name
  self.class.name
end
create() click to toggle source

Launches a cloudformation to create an s3 bucket

# File lib/lono/s3/bucket.rb, line 66
def create
  puts "Creating #{STACK_NAME} stack with the s3 bucket"
  cfn.create_stack(
    stack_name: STACK_NAME,
    template_body: template_body,
    enable_termination_protection: true,
  )
  success = status.wait
  status.reset
  unless success
    puts "ERROR: Unable to create lono stack with managed s3 bucket".color(:red)
    exit 1
  end
end
delete() click to toggle source
# File lib/lono/s3/bucket.rb, line 88
def delete
  are_you_sure?

  puts "Deleting #{STACK_NAME} stack with the s3 bucket"
  disable_termination_protect
  empty_bucket!
  cfn.delete_stack(stack_name: STACK_NAME)
end
deploy() click to toggle source
# File lib/lono/s3/bucket.rb, line 32
def deploy
  stack = find_stack
  if rollback_complete?(stack)
    puts "Existing '#{STACK_NAME}' stack in ROLLBACK_COMPLETE state. Deleting stack before continuing."
    cfn.delete_stack(stack_name: STACK_NAME)
    status.wait
    status.reset
    stack = nil
  end

  if stack
    update
  else
    create
  end
end
disable_termination_protect() click to toggle source
# File lib/lono/s3/bucket.rb, line 97
def disable_termination_protect
  cfn.update_termination_protection(
    stack_name: STACK_NAME,
    enable_termination_protection: false,
  )
end
exist?() click to toggle source
# File lib/lono/s3/bucket.rb, line 49
def exist?
  !!bucket_name
end
find_stack() click to toggle source
# File lib/lono/s3/bucket.rb, line 104
def find_stack
  resp = cfn.describe_stacks(stack_name: STACK_NAME)
  resp.stacks.first
rescue Aws::CloudFormation::Errors::ValidationError
  nil
end
show() click to toggle source
# File lib/lono/s3/bucket.rb, line 57
def show
  if bucket_name
    puts "Lono bucket name: #{bucket_name}"
  else
    puts "Lono bucket does not exist yet."
  end
end
status() click to toggle source
# File lib/lono/s3/bucket.rb, line 111
def status
  CfnStatus.new(STACK_NAME)
end
update() click to toggle source
# File lib/lono/s3/bucket.rb, line 81
def update
  puts "Updating #{STACK_NAME} stack with the s3 bucket"
  cfn.update_stack(stack_name: STACK_NAME, template_body: template_body)
rescue Aws::CloudFormation::Errors::ValidationError => e
  raise unless e.message.include?("No updates are to be performed")
end

Private Instance Methods

are_you_sure?() click to toggle source
# File lib/lono/s3/bucket.rb, line 137
def are_you_sure?
  return true if @options[:sure]

  if bucket_name.nil?
    puts "The lono stack and s3 bucket does not exist."
    exit
  end

  puts "Are you sure you want the lono bucket #{bucket_name.color(:green)} to be emptied and deleted? (y/N)"
  sure = $stdin.gets.strip
  yes = sure =~ /^Y/i
  unless yes
    puts "Phew that was close."
    exit
  end
end
empty_bucket!() click to toggle source
# File lib/lono/s3/bucket.rb, line 118
def empty_bucket!
  return unless bucket_name # in case of lono stack ROLLBACK_COMPLETE from failed bucket creation

  resp = s3.list_objects(bucket: bucket_name)
  if resp.contents.size > 0
    # IE: objects = [{key: "objectkey1"}, {key: "objectkey2"}]
    objects = resp.contents.map { |item| {key: item.key} }
    s3.delete_objects(
      bucket: bucket_name,
      delete: {
        objects: objects,
        quiet: false,
      }
    )
    empty_bucket! # keep deleting objects until bucket is empty
  end
end
template_body() click to toggle source
# File lib/lono/s3/bucket.rb, line 154
    def template_body
      <<~YAML
        Description: Lono managed s3 bucket
        Resources:
          Bucket:
            Type: AWS::S3::Bucket
            Properties:
              BucketEncryption:
                 ServerSideEncryptionConfiguration:
                 - ServerSideEncryptionByDefault:
                    SSEAlgorithm: AES256
              Tags:
                - Key: Name
                  Value: lono
      YAML
    end