lib/terraforming/resource/security_group.rb in terraforming-0.0.5 vs lib/terraforming/resource/security_group.rb in terraforming-0.1.0
- old
+ new
@@ -1,37 +1,40 @@
module Terraforming
module Resource
class SecurityGroup
include Terraforming::Util
- def self.tf(client = Aws::EC2::Client.new)
+ def self.tf(client: Aws::EC2::Client.new)
self.new(client).tf
end
- def self.tfstate(client = Aws::EC2::Client.new)
- self.new(client).tfstate
+ def self.tfstate(client: Aws::EC2::Client.new, tfstate_base: nil)
+ self.new(client).tfstate(tfstate_base)
end
def initialize(client)
@client = client
end
def tf
apply_template(@client, "tf/security_group")
end
- def tfstate
+ def tfstate(tfstate_base)
resources = security_groups.inject({}) do |result, security_group|
attributes = {
"description" => security_group.description,
- "egress.#" => security_group.ip_permissions_egress.length.to_s,
"id" => security_group.group_id,
- "ingress.#" => security_group.ip_permissions.length.to_s,
"name" => security_group.group_name,
"owner_id" => security_group.owner_id,
"vpc_id" => security_group.vpc_id || "",
}
+
+ attributes.merge!(tags_attributes_of(security_group))
+ attributes.merge!(egress_attributes_of(security_group))
+ attributes.merge!(ingress_attributes_of(security_group))
+
result["aws_security_group.#{module_name_of(security_group)}"] = {
"type" => "aws_security_group",
"primary" => {
"id" => security_group.group_id,
"attributes" => attributes
@@ -39,20 +42,96 @@
}
result
end
- generate_tfstate(resources)
+ generate_tfstate(resources, tfstate_base)
end
private
+ def ingress_attributes_of(security_group)
+ attributes = { "ingress.#" => security_group.ip_permissions.length.to_s }
+
+ security_group.ip_permissions.each do |permission|
+ attributes.merge!(permission_attributes_of(security_group, permission, "ingress"))
+ end
+
+ attributes
+ end
+
+ def egress_attributes_of(security_group)
+ attributes = { "egress.#" => security_group.ip_permissions_egress.length.to_s }
+
+ security_group.ip_permissions_egress.each do |permission|
+ attributes.merge!(permission_attributes_of(security_group, permission, "egress"))
+ end
+
+ attributes
+ end
+
+ def group_hashcode_of(group)
+ Zlib.crc32(group)
+ end
+
def module_name_of(security_group)
normalize_module_name("#{security_group.group_id}-#{security_group.group_name}")
end
+ def permission_attributes_of(security_group, permission, type)
+ hashcode = permission_hashcode_of(security_group, permission)
+ security_groups = security_groups_in(permission).reject { |group_id| group_id == security_group.group_id }
+
+ attributes = {
+ "#{type}.#{hashcode}.from_port" => (permission.from_port || 0).to_s,
+ "#{type}.#{hashcode}.to_port" => (permission.to_port || 0).to_s,
+ "#{type}.#{hashcode}.protocol" => permission.ip_protocol,
+ "#{type}.#{hashcode}.cidr_blocks.#" => permission.ip_ranges.length.to_s,
+ "#{type}.#{hashcode}.security_groups.#" => security_groups.length.to_s,
+ "#{type}.#{hashcode}.self" => self_referenced_permission?(security_group, permission).to_s,
+ }
+
+ permission.ip_ranges.each_with_index do |range, index|
+ attributes["#{type}.#{hashcode}.cidr_blocks.#{index}"] = range.cidr_ip
+ end
+
+ security_groups.each do |group|
+ attributes["#{type}.#{hashcode}.security_groups.#{group_hashcode_of(group)}"] = group
+ end
+
+ attributes
+ end
+
+ def permission_hashcode_of(security_group, permission)
+ string =
+ "#{permission.from_port || 0}-" <<
+ "#{permission.to_port || 0}-" <<
+ "#{permission.ip_protocol}-" <<
+ "#{self_referenced_permission?(security_group, permission).to_s}-"
+
+ permission.ip_ranges.each { |range| string << "#{range.cidr_ip}-" }
+ security_groups_in(permission).each { |group| string << "#{group}-" }
+
+ Zlib.crc32(string)
+ end
+
+ def self_referenced_permission?(security_group, permission)
+ security_groups_in(permission).include?(security_group.group_id)
+ end
+
def security_groups
@client.describe_security_groups.security_groups
+ end
+
+ def security_groups_in(permission)
+ permission.user_id_group_pairs.map { |range| range.group_id }
+ end
+
+ def tags_attributes_of(security_group)
+ tags = security_group.tags
+ attributes = { "tags.#" => tags.length.to_s }
+ tags.each { |tag| attributes["tags.#{tag.key}"] = tag.value }
+ attributes
end
end
end
end