class Ec2SecurityCzar::SecurityGroup

Attributes

config[RW]
diff[RW]
name[RW]

Public Class Methods

from_aws() click to toggle source

Private: Gets all security groups from AWS

Returns - SecurityGroupCollection

# File lib/ec2-security-czar/security_group.rb, line 58
def self.from_aws
  @security_groups = ec2.security_groups
end
lookup(query) click to toggle source

Public: Creates a hash mapping security_group.name to security_group, and looks up security_group by name or id

name: the name of the security group to lookup

Returns - SecurityGroup object

# File lib/ec2-security-czar/security_group.rb, line 46
def self.lookup(query)
  @security_group_hash ||= security_groups.inject({}) do |hash, security_group|
    hash[security_group.name] = security_group
    hash[security_group.id] = security_group
    hash
  end
  @security_group_hash[query] 
end
new(name, environment) click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 15
def initialize(name, environment)
  @name = name
  @environment = environment
  load_rules
end
update_rules() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 34
def self.update_rules
  security_groups.each do |sg|
    security_group = SecurityGroup.new(sg.name, @environment)
    security_group.update_rules
  end
end
update_security_groups(ec2, environment, region) click to toggle source

Public: Creates missing security groups, updates all security groups

ec2: ec2 instance created in base.rb environment: environment passed in from commandline region: the region loaded in from aws_keys.yml, defaults to ‘us-east-1’

# File lib/ec2-security-czar/security_group.rb, line 26
def self.update_security_groups(ec2, environment, region)
  @ec2 = ec2
  @environment = environment
  @region = region
  create_missing_security_groups(environment)
  update_rules
end

Private Class Methods

config_security_groups() click to toggle source

Private: Gets all the security groups with YAML files

Returns - Array of all security group names

# File lib/ec2-security-czar/security_group.rb, line 65
def self.config_security_groups
  security_group_definition_files
    .reject { |file| get_security_group_region(file) != region}
    .map { |file| File.basename(file,File.extname(file)) }
end
create_missing_security_groups(environment) click to toggle source

Public: Creates missing security groups

Returns - nil

# File lib/ec2-security-czar/security_group.rb, line 96
def self.create_missing_security_groups(environment)
  unless (missing_groups = missing_security_groups).empty?
    say "================================================="
    say "Creating security groups for #{environment}:"
    say "================================================="
    missing_groups.each do |name|
      security_group = SecurityGroup.new(name, environment)
      config = security_group.config
      ec2.security_groups.create(name, vpc: config[:vpc], description: config[:description]) 
      say "<%= color('#{name}', :green) %>"
    end
    say "\n"
  end
end
ec2() click to toggle source

Private: @ec2 accessor

Returns - @ec2

# File lib/ec2-security-czar/security_group.rb, line 123
def self.ec2
  @ec2 
end
environment() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 128
def self.environment
  @environment
end
get_security_group_region(file) click to toggle source

Private: Gets the security group region

Returns - The region in which the security group should be made

# File lib/ec2-security-czar/security_group.rb, line 80
def self.get_security_group_region(file)
  SecurityGroupConfig[YAML.load(ERB.new(File.read(file)).result(binding))][:region] || 'us-east-1'
end
missing_security_groups() click to toggle source

Public: Finds security groups with YAML files not on AWS

Returns - Array of all security group names not on AWS

# File lib/ec2-security-czar/security_group.rb, line 88
def self.missing_security_groups
  config_security_groups - from_aws.map(&:name)
end
region() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 133
def self.region
  @region
end
security_group_definition_files() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 72
def self.security_group_definition_files
  Dir["config/*.yml"].reject!{ |file| file == "config/aws_keys.yml" }
end
security_groups() click to toggle source

Private: @security_groups accessor

Returns - @security_groups

# File lib/ec2-security-czar/security_group.rb, line 115
def self.security_groups
  @security_groups
end

Public Instance Methods

load_rules() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 179
def load_rules
  if File.exists? config_filename
    environment = @environment
    @config = SecurityGroupConfig[YAML.load(ERB.new(File.read(config_filename)).result(binding))]
  end
end
rule_exists?(direction, current_rule) click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 191
def rule_exists?(direction, current_rule)
  @diff[:additions][direction].reject!{ |rule| rule.equal?(current_rule) }
end
update_rules() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 138
def update_rules
  if config
    say "================================================="
    say "Applying changes for #{name}:"
    say "================================================="

    # Apply deletions first
    rules_diff
    [:outbound, :inbound].each do |direction|
      diff[:deletions][direction].each{ |rule| rule.revoke! }
    end

    # Re-calculate the diff after performing deletions to make sure we add
    # back any that got removed because of the way AWS groups rules together.
    rules_diff
    [:outbound, :inbound].each do |direction|
      diff[:additions][direction].each{ |rule| rule.authorize!(self.class.lookup(name)) }
    end
    say "\n"
  else
    say "No config file for #{name}, skipping...\n\n"
  end
end

Private Instance Methods

config_filename() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 186
def config_filename
  "config/#{name}.yml"
end
current_rules(direction) click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 196
def current_rules(direction)
  security_group = self.class.lookup(name)
  aws_security_group_rules = direction == :outbound ? security_group.egress_ip_permissions : security_group.ingress_ip_permissions
  Rule.rules_from_api(aws_security_group_rules, direction)
end
new_rules(direction) click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 203
def new_rules(direction)
  Rule.rules_from_config(config, direction)
end
rules_diff() click to toggle source
# File lib/ec2-security-czar/security_group.rb, line 162
def rules_diff
  @diff = { deletions: {}, additions: {} }

  [:outbound, :inbound].each do |direction|
    @diff[:deletions][direction] = []
    @diff[:additions][direction] = new_rules(direction)

    current_rules(direction).each do |current_rule|
      unless rule_exists?(direction, current_rule)
        @diff[:deletions][direction] << current_rule
      end
    end
  end
  diff
end