class S3BucketBasedRuleRepo

Attributes

aws_profile[R]
index_life_time[R]
prefix[R]
s3_bucket_name[R]

Public Class Methods

new(s3_bucket_name:, prefix:, index_lifetime: '1h', aws_profile: nil) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 28
def initialize(s3_bucket_name:, prefix:, index_lifetime: '1h', aws_profile: nil)
  @s3_bucket_name = s3_bucket_name
  @prefix = remove_leading_slash(prefix)
  @index_cache = Lightly.new(
    dir: cache_path('cfn_nag_s3_index_cache', s3_bucket_name),
    life: index_lifetime,
    hash: true
  )

  # except in dev mode, rules are immutable so once we have it don't worry about it changing
  @rule_cache = Lightly.new(
    dir: cache_path('cfn_nag_s3_rule_cache', s3_bucket_name),
    life: '1000d',
    hash: true
  )
  @aws_profile = aws_profile
  @s3_resource = nil
end

Public Instance Methods

discover_rules() click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 47
def discover_rules
  Logging.logger['log'].debug "S3BucketBasedRuleRepo.discover_rules in #{@s3_bucket_name}, #{@prefix}"

  rule_registry = RuleRegistry.new

  index = index(@s3_bucket_name, @prefix)
  Logging.logger['log'].debug "index: #{index}"

  index.each do |rule_object_key|
    rule_code = @rule_cache.get(rule_object_key) do
      cache_miss(rule_object_key)
    end

    rule_class_name = select_class_name_from_object_key(rule_object_key)

    eval_code_in_object_scope rule_code

    rule_registry.definition(Object.const_get(rule_class_name))
  end

  rule_registry
end
nuke_cache() click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 70
def nuke_cache
  cached_dirs = [
    cache_path('cfn_nag_s3_index_cache', @s3_bucket_name),
    cache_path('cfn_nag_s3_rule_cache', @s3_bucket_name)
  ]
  FileUtils.rm_rf(cached_dirs)
end

Private Instance Methods

cache_miss(key) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 80
def cache_miss(key)
  Logging.logger['log'].debug "cache_miss: #{key}"

  rule_code_record = s3_object_content(@s3_bucket_name, key)
  rule_code_record.body.read
end
cache_path(cache_name, s3_bucket_name) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 87
def cache_path(cache_name, s3_bucket_name)
  "/tmp/#{cache_name}/#{s3_bucket_name}"
end
discover_rule_s3_objects(s3_bucket_name, prefix) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 117
def discover_rule_s3_objects(s3_bucket_name, prefix)
  rule_bucket = s3_resource.bucket(s3_bucket_name)
  objects = rule_bucket.objects(prefix: prefix)
  rule_objects = objects.select do |object|
    object.key.match(/.*Rule\.rb/)
  end
  Logging.logger['log'].debug "Found rule objects: #{rule_objects}"
  rule_objects.map(&:key)
rescue Aws::S3::Errors::NoSuchBucket
  raise RuleRepoException.new(msg: "Rule bucket not found: #{s3_bucket_name}")
end
index(s3_bucket_name, prefix) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 101
def index(s3_bucket_name, prefix)
  index_json_str = @index_cache.get('index_cfn_nag') do
    discover_rule_s3_objects(s3_bucket_name, prefix).to_json
  end
  JSON.parse(index_json_str)
end
remove_leading_slash(s3_key) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 129
def remove_leading_slash(s3_key)
  s3_key.start_with?('/') ? s3_key[1..-1] : s3_key
end
s3_object(s3_bucket_name, key) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 108
def s3_object(s3_bucket_name, key)
  rule_bucket = s3_resource.bucket(s3_bucket_name)
  rule_bucket.object key
end
s3_object_content(s3_bucket_name, key) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 113
def s3_object_content(s3_bucket_name, key)
  s3_object(s3_bucket_name, key).get
end
s3_resource() click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 91
def s3_resource
  return @s3_resource unless @s3_resource.nil?

  @s3_resource = @aws_profile ? Aws::S3::Resource.new(profile: @aws_profile) : Aws::S3::Resource.new
end
select_class_name_from_object_key(key) click to toggle source
# File lib/cfn-nag/rule_repos/s3_based_rule_repo.rb, line 97
def select_class_name_from_object_key(key)
  key.split('/')[-1].gsub('.rb', '')
end