class UpdateBucketPolicy

Constants

KNOWN

Attributes

accounts[R]
clients[R]
environments[R]
logger[RW]
stacks[R]

Public Class Methods

new(args = [], local_options = {}, config = {}) click to toggle source
Calls superclass method
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 312
def initialize(args = [], local_options = {}, config = {})
  super(args,local_options,config)
end

Public Instance Methods

get_eips() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 150
def get_eips
  logger.step 'Get EIPs ...'

  @eips         = []
  @accounts.each do |acc|
    @options.merge!(acc.get_options())
    parse_options
    get_eips_for_account
  end
  @eips.uniq!
  logger.info "EIPs:\n"+@eips.sort_by { |ip| ip.split(%r'[\./]').map{ |octet| octet.to_i} }.ai

end
get_eips_for_account() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 136
def get_eips_for_account
  logger.step "Get EIPs for #{@options[:inifile]} ..."

  # noinspection RubyArgCount
  ec2 = Aws::EC2::Client.new(retry_limit: 10)

  resp = ec2.describe_addresses()

  @eips << resp[:addresses].map{ |a| a[:public_ip] }
  @eips.flatten!
  logger.debug @eips.ai

end
get_environments(strict=false) click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 57
def get_environments(strict=false)
  logger.step 'Get environments ...'

  @environments = {}
  @nats         = {}
  @accounts.each do |acc|
    @options.merge!(acc.get_options())
    parse_options
    get_environments_for_account(strict)
  end
  logger.info "Environments:\n"+@environments.ai
  logger.info "NATs:\n"+@nats.ai

end
get_environments_for_account(strict=false) click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 72
def get_environments_for_account(strict=false)
  logger.step "Get environments for #{@options[:account]} ..."

  config = @options

  # noinspection RubyArgCount
  cfn = Aws::CloudFormation::Client.new(retry_limit: 10)

  stacks = []
  resp = cfn.list_stacks()

  stacks << resp[:stack_summaries]
  while resp[:next_token]
    resp = cfn.list_stacks(next_token: resp[:next_token])
    logger.debug resp.size
    stacks << resp[:stack_summaries]
  end
  stacks.flatten!
  stacks = stacks.select{ |stack| stack[:stack_status].match(%r'^(UPDATE|CREATE).*?_COMPLETE$')}
  logger.debug stacks.ai

  stacks.each do |stack|
    env = nil
    resp = cfn.describe_stacks(stack_name: stack[:stack_id])
    stck = resp[:stacks].shift
    tags = stck[:tags]
    tags.each do |tag|
      if tag[:key] == 'EnvironmentName'
        env = tag[:value]
        break
      end
    end
    unless env or strict
      env = stack[:stack_name]
    end
    if env
      @environments[env] ||= []
      @environments[env] << stack[:stack_name]
      @stacks ||= {}
      @stacks[env] ||= []
      @stacks[env] << stack
      @clients ||= {}
      @clients[env] ||= cfn

      # @resources ||= {}
      # @resources[env] ||= []
      resources = []
      resp = cfn.describe_stack_resources(stack_name: stack[:stack_id], logical_resource_id: 'NATIPAddress')
      resources << resp[:stack_resources]
      resp = cfn.describe_stack_resources(stack_name: stack[:stack_id], logical_resource_id: 'BastionIPAddress')
      resources << resp[:stack_resources]
      resources.flatten!
      logger.debug resources.ai

      _nats = resources.map{ |r|
        r.to_h[:physical_resource_id]
      }

      @nats[env] = @nats[env] ? [ @nats[env], _nats ].flatten : _nats
    end
  end

end
inspect() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 331
def inspect()
  prepare_accounts()

  inspect_bucket_policy()

  @policies.each do |pol|
    logger.debug JSON.pretty_generate(pol, { indent: "\t", space: ' '})
  end
  0
end
inspect_bucket_policy() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 193
def inspect_bucket_policy

  parse_bucket_options(__method__, [ :policy, [:bucketini, :bucketprofile], :bucket ])

  logger.step "Inspect the policy for #{@options[:bucket]} ..."

  config = @options.dup
  tempfile =
  @options[:policy] = Tempfile.new('policy').path+'.json'
  read_bucket_policy()
  @options = config

  get_eips()

  get_environments()

  ips = [ @nats.values, @eips ].flatten.map{ |ip| "#{ip}/32"}
  ips = [ ips, KNOWN ].flatten.uniq.select{ |ip| not ip.nil? }
  ips = ips.sort_by { |ip| ip.split(%r'[\./]').map{ |octet| octet.to_i} }.uniq
  logger.info "Valid IPs: \n"+ips.ai

  json = ''
  @policies.each do |pol|
    unknown = 0
    missing = 0
    unadded = 0
    if pol['Statement']
      pol['Statement'].each do |smt|
        logger.debug smt.ai
        if smt['Condition'] and smt['Condition']['IpAddress'] and smt['Condition']['IpAddress']['aws:SourceIp']
          smt['Condition']['IpAddress']['aws:SourceIp'].sort_by { |ip| ip.split(%r'[\./]').map{ |octet| octet.to_i} }.each do |entry|
            unless ips.include?(entry)
              logger.warn "#{entry} unknown"
              unknown += 1
            end
          end
          ips.each do |entry|
            unless smt['Condition']['IpAddress']['aws:SourceIp'].include?(entry)
              logger.info "#{entry} missing"
              missing += 1
              smt['Condition']['IpAddress']['aws:SourceIp'] << entry
            end
          end
          if missing > 0
            ips.each do |entry|
              unless smt['Condition']['IpAddress']['aws:SourceIp'].include?(entry)
                logger.warn "#{entry} missing"
                unadded += 1
              end
            end
          end
          smt['Condition']['IpAddress']['aws:SourceIp'] = smt['Condition']['IpAddress']['aws:SourceIp'].sort_by { |ip| ip.split(%r'[\./]').map{ |octet| octet.to_i} }
        end
      end
    else
      logger.warn "Policy has no Statement: #{pol.ai}"
    end
    if missing+unknown > 0
      logger.warn "Policy needs to be updated for #{unknown} unknown IPs, #{missing} missing and #{unadded} IPs which failed to add"
    end
    # require 'date_time'
    logger.debug JSON.pretty_generate(pol, { indent: "\t", space: ' '})
    pol['Id'] = "Policy-#{DateTime.now.strftime('%Y%m%dT%H%M%S')}"
    json += JSON.pretty_generate(pol, { indent: "\t", space: ' '})
  end
  IO.write(options[:policy], json)

end
parse_bucket_options(method,optionset) click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 299
def parse_bucket_options(method,optionset)
  check_missing_options(method, optionset)

  if @options[:bucketini]
    @options[:inifile] = @options[:bucketini]
  else
    @options[:profile] = @options[:bucketprofile]
  end
  parse_options
  @logger.info options.ai
end
read() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 317
def read()
  prepare_accounts

  read_bucket_policy

  n = 1
  @policies.each do |pol|
    logger.step "#{n+=1}\n"+JSON.pretty_generate(pol, { indent: "\t", space: ' '})
  end

  0
end
read_bucket_policy() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 164
def read_bucket_policy

  parse_bucket_options(__method__, [ :policy, [:bucketini, :bucketprofile], :bucket ])

  logger.step "Read the current policy for #{@options[:bucket]} ..."

  # noinspection RubyArgCount
  s3 = Aws::S3::Client.new()

  resp = s3.get_bucket_policy(bucket: options[:bucket])
  logger.debug resp.size
  @policies = []
  resp.each do |item|
    json = item.policy.read
    @policies << JSON.load(json)

    logger.debug JSON.pretty_generate(@policies[-1], { indent: "\t", space: ' '})
  end

  logger.debug @policies.ai

  json = ''
  @policies.each do |pol|
    json += JSON.pretty_generate(pol, { indent: "\t", space: ' '})
  end
  IO.write("#{options[:policy]}", json)

end
update() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 343
def update()
  prepare_accounts()

  update_bucket_policy()

  0
end
update_bucket_policy() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 262
def update_bucket_policy

  parse_bucket_options(__method__, [ :policy, [:bucketini, :bucketprofile], :bucket ])

  logger.step "Update the current policy for #{@options[:bucket]} ..."

  inspect_bucket_policy

  write_bucket_policy

end
write() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 352
def write()
  prepare_accounts
  @options[:inifile] = @options[:bucketini]
  parse_options
  @logger.info options.ai

  write_bucket_policy

  0
end
write_bucket_policy() click to toggle source
# File lib/cicd/builder/environments-list/mixlib/lib/update_bucket_policy.rb, line 274
def write_bucket_policy

  parse_bucket_options(__method__, [ :policy, [:bucketini, :bucketprofile], :bucket ])

  logger.step "Write the new policy for #{@options[:bucket]} ..."

  @options[:inifile] = @options[:bucketini]
  parse_options
  @logger.info options.ai

  json = IO.read(options[:policy])

  # noinspection RubyArgCount
  s3 = Aws::S3::Client.new()

  resp = s3.put_bucket_policy(
                                bucket: options[:bucket],
                                policy: json
                              )
  logger.debug resp.ai
  if resp.error
    logger.error resp.error
  end
end