class Awsom::SecurityGroup

Constants

DiffStruct

Public Class Methods

id(name, vpc_id) click to toggle source
# File lib/awsom/security_group.rb, line 11
def self.id(name, vpc_id)
  sg = new(name, vpc_id: vpc_id)
  sg.id
end
new(name, vpc_id:) click to toggle source
# File lib/awsom/security_group.rb, line 16
def initialize(name, vpc_id:)
  @name = name
  @vpc_id = vpc_id
end

Public Instance Methods

created(&block) click to toggle source
# File lib/awsom/security_group.rb, line 31
def created(&block)
  @desired_rules = Set.new
  instance_eval &block
  @id = find_id || create
  sync
  @id
end
description(description) click to toggle source
# File lib/awsom/security_group.rb, line 27
def description(description)
  @description = description
end
id() click to toggle source
# File lib/awsom/security_group.rb, line 21
def id
  id = find_id
  raise Error, "specified security_group #{@name} doesn't exist in vpc #{@vpc_id}" if not id
  id
end

Private Instance Methods

authorize_ingress(rule) click to toggle source
# File lib/awsom/security_group.rb, line 132
def authorize_ingress(rule)
  sg.authorize_ingress rule if not @dry_run
  logger.info "(#{@name}) #{"+".green.bold} allow #{rule[:cidr_ip]} #{rule[:from_port]}-#{rule[:to_port]}"
rescue Aws::Errors::ServiceError
  error "error authorizing rule #{rule}"
end
create() click to toggle source
# File lib/awsom/security_group.rb, line 59
def create
  resp = Ec2.create_security_group(
    group_name: @name, 
    description: @description,
    vpc_id: @vpc_id
  )
  logger.info "(#{@name}) created security group" 
  resp.group_id
rescue Aws::Errors::ServiceError, ArgumentError
  error "while creating security_group #{@name}"
end
current_rules() click to toggle source
# File lib/awsom/security_group.rb, line 110
def current_rules
  current_rules = Set.new 
  sg.ip_permissions.each do |permission|
    rules = permission_to_rules(permission)
    rules.each { |r| current_rules << r }
  end
  current_rules
end
diff(current, desired) click to toggle source
# File lib/awsom/security_group.rb, line 119
def diff(current, desired)
  to_add = desired - current
  to_remove = current - desired
  DiffStruct.new(to_add: to_add, to_remove: to_remove)
end
find_id() click to toggle source
# File lib/awsom/security_group.rb, line 45
def find_id
  filters = [
    { name: "group-name", values: [@name] },
    { name: "vpc-id", values: [@vpc_id] }
  ]
  result = Ec2.describe_security_groups(filters: filters)
  num_results = result.security_groups.size
  if num_results == 1
    result.security_groups.first.group_id
  else
    false
  end
end
icmp(cidr_ip) click to toggle source
# File lib/awsom/security_group.rb, line 96
def icmp(cidr_ip)
  rule(ip_protocol: "icmp", from_port: -1, to_port: -1, cidr_ip: cidr_ip)
end
parse_ports(port) click to toggle source
# File lib/awsom/security_group.rb, line 71
def parse_ports(port)
  case port
  when Integer
    [port, port]
  when Range
    [port.first, port.last]
  when /\A([0-9]+)\z/
    [$1.to_i, $1.to_i]
  when /\A([0-9]+)\-([0-9]+)\z/
    [$1.to_i, $2.to_i]
  else
    raise Error, "invalid port specified #{port}"
  end
end
permission_to_rules(permission) click to toggle source
# File lib/awsom/security_group.rb, line 144
def permission_to_rules(permission)
  rules = Set.new
  permission.ip_ranges.each do |r|
    rule = {
      ip_protocol: permission.ip_protocol,
      from_port: permission.from_port,
      to_port: permission.to_port,
      cidr_ip: r.cidr_ip
    }
    rules << rule
  end
  rules
end
revoke_ingress(rule) click to toggle source
# File lib/awsom/security_group.rb, line 139
def revoke_ingress(rule)
  sg.revoke_ingress rule if not @dry_run
  logger.info "(#{@name}) #{"-".red.bold} allow #{rule[:cidr_ip]} #{rule[:from_port]}-#{rule[:to_port]}"
end
rule(ip_protocol:, from_port:, to_port:, cidr_ip:) click to toggle source
# File lib/awsom/security_group.rb, line 100
def rule(ip_protocol:, from_port:, to_port:, cidr_ip:)
  rule = {
    ip_protocol: ip_protocol,
    from_port: from_port,
    to_port: to_port,
    cidr_ip: cidr_ip
  }
  @desired_rules << rule
end
sg() click to toggle source
# File lib/awsom/security_group.rb, line 41
def sg
  @sg ||= Aws::EC2::SecurityGroup.new(id)
end
sync() click to toggle source
# File lib/awsom/security_group.rb, line 125
def sync
  current = current_rules
  ingress_diff = diff(current, @desired_rules)
  ingress_diff.to_add.each { |r| authorize_ingress r }
  ingress_diff.to_remove.each { |r| revoke_ingress r }
end
tcp(port, cidr_ip:) click to toggle source
# File lib/awsom/security_group.rb, line 86
def tcp(port, cidr_ip:)
  (from_port, to_port) = parse_ports(port)
  rule(ip_protocol: "tcp", from_port: from_port, to_port: to_port, cidr_ip: cidr_ip)
end
udp(port, cidr_ip:) click to toggle source
# File lib/awsom/security_group.rb, line 91
def udp(port, cidr_ip:)
  (from_port, to_port) = parse_ports(port)
  rule(ip_protocol: "udp", from_port: from_port, to_port: to_port, cidr_ip: cidr_ip)
end