Commit beb0b1af authored by Daisuke Fujita's avatar Daisuke Fujita

Merge pull request #30 from dtan4/network-acl

[WIP] Add Network ACL
parents 9eac35f3 eabc72df
......@@ -15,6 +15,7 @@ require "terraforming/resource/db_security_group"
require "terraforming/resource/db_subnet_group"
require "terraforming/resource/ec2"
require "terraforming/resource/elb"
require "terraforming/resource/network_acl"
require "terraforming/resource/rds"
require "terraforming/resource/s3"
require "terraforming/resource/security_group"
......
......@@ -30,6 +30,12 @@ module Terraforming
execute(Terraforming::Resource::ELB, options)
end
desc "nacl", "Network ACL"
option :tfstate, type: :boolean
def nacl
execute(Terraforming::Resource::NetworkACL, options)
end
desc "rds", "RDS"
option :tfstate, type: :boolean
def rds
......
module Terraforming::Resource
class NetworkACL
include Terraforming::Util
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
end
def initialize(client)
@client = client
end
def tf
apply_template(@client, "tf/network_acl")
end
def tfstate
resources = network_acls.inject({}) do |result, network_acl|
attributes = {
"egress.#" => egresses_of(network_acl).length.to_s,
"id" => network_acl.network_acl_id,
"ingress.#" => ingresses_of(network_acl).length.to_s,
"tags.#" => network_acl.tags.length.to_s,
"vpc_id" => network_acl.vpc_id,
}
result["aws_network_acl.#{module_name_of(network_acl)}"] = {
"type" => "aws_network_acl",
"primary" => {
"id" => network_acl.network_acl_id,
"attributes" => attributes
}
}
result
end
generate_tfstate(resources)
end
private
def egresses_of(network_acl)
network_acl.entries.select { |entry| entry.egress }
end
def from_port_of(entry)
entry.port_range ? entry.port_range.from : 0
end
def ingresses_of(network_acl)
network_acl.entries.select { |entry| !entry.egress }
end
def module_name_of(network_acl)
normalize_module_name(name_from_tag(network_acl, network_acl.network_acl_id))
end
def network_acls
@client.describe_network_acls(filters: [{ name: "default", values: ["false"] }]).network_acls
end
def to_port_of(entry)
entry.port_range ? entry.port_range.to : 65535
end
end
end
<% network_acls.each do |network_acl| -%>
resource "aws_network_acl" "<%= module_name_of(network_acl) %>" {
vpc_id = "<%= network_acl.vpc_id %>"
<% ingresses_of(network_acl).each do |ingress| -%>
ingress {
from_port = <%= from_port_of(ingress) %>
to_port = <%= to_port_of(ingress) %>
rule_no = <%= ingress.rule_number %>
action = "<%= ingress.rule_action %>"
protocol = "<%= ingress.protocol %>"
cidr_block = "<%= ingress.cidr_block %>"
}
<% end -%>
<% egresses_of(network_acl).each do |egress| -%>
egress {
from_port = <%= from_port_of(egress) %>
to_port = <%= to_port_of(egress) %>
rule_no = <%= egress.rule_number %>
action = "<%= egress.rule_action %>"
protocol = "<%= egress.protocol %>"
cidr_block = "<%= egress.cidr_block %>"
}
<% end -%>
tags {
<% network_acl.tags.each do |tag| -%>
<%= tag.key %> = "<%= tag.value %>"
<% end -%>
}
}
<% end -%>
......@@ -82,6 +82,22 @@ module Terraforming
end
end
describe "nacl" do
context "without --tfstate" do
it "should export NetworkACL tf" do
expect(Terraforming::Resource::NetworkACL).to receive(:tf)
described_class.new.invoke(:nacl, [], {})
end
end
context "with --tfstate" do
it "should export NetworkACL tfstate" do
expect(Terraforming::Resource::NetworkACL).to receive(:tfstate)
described_class.new.invoke(:nacl, [], { tfstate: true })
end
end
end
describe "RDS" do
context "without --tfstate" do
it "should export RDS tf" do
......
require "spec_helper"
module Terraforming::Resource
describe NetworkACL do
let(:client) do
Aws::EC2::Client.new(stub_responses: true)
end
let(:network_acls) do
[
{
network_acl_id: "acl-1234abcd",
vpc_id: "vpc-1234abcd",
is_default: true,
entries: [
{
rule_number: 100,
protocol: "-1",
rule_action: "allow",
egress: false,
cidr_block: "0.0.0.0/0",
port_range: nil,
},
{
rule_number: 32767,
protocol: "-1",
rule_action: "deny",
egress: true,
cidr_block: "0.0.0.0/0",
port_range: {
from: 80,
to: 80,
},
},
],
associations: [
{
network_acl_association_id: "aclassoc-1234abcd",
network_acl_id: "acl-1234abcd",
subnet_id: "subnet-1234abcd"
},
{
network_acl_association_id: "aclassoc-5678efgh",
network_acl_id: "acl-1234abcd",
subnet_id: "subnet-5678efgh"
},
],
tags: [
{ key: "Name", value: "hoge" },
]
},
{
network_acl_id: "acl-5678efgh",
vpc_id: "vpc-5678efgh",
is_default: true,
entries: [
{
rule_number: 100,
protocol: "-1",
rule_action: "allow",
egress: false,
cidr_block: "0.0.0.0/0",
port_range: nil,
},
{
rule_number: 32767,
protocol: "-1",
rule_action: "deny",
egress: true,
cidr_block: "0.0.0.0/0",
port_range: {
from: 80,
to: 80
}
},
],
associations: [
{
network_acl_association_id: "aclassoc-9012ijkl",
network_acl_id: "acl-5678efgh",
subnet_id: "subnet-9012ijkl"
},
{
network_acl_association_id: "aclassoc-3456mnop",
network_acl_id: "acl-5678efgh",
subnet_id: "subnet-3456mnop"
},
],
tags: [
{ key: "Name", value: "fuga" },
]
},
]
end
before do
client.stub_responses(:describe_network_acls, network_acls: network_acls)
end
describe ".tf" do
it "should generate tf" do
expect(described_class.tf(client)).to eq <<-EOS
resource "aws_network_acl" "hoge" {
vpc_id = "vpc-1234abcd"
ingress {
from_port = 0
to_port = 65535
rule_no = 100
action = "allow"
protocol = "-1"
cidr_block = "0.0.0.0/0"
}
egress {
from_port = 80
to_port = 80
rule_no = 32767
action = "deny"
protocol = "-1"
cidr_block = "0.0.0.0/0"
}
tags {
Name = "hoge"
}
}
resource "aws_network_acl" "fuga" {
vpc_id = "vpc-5678efgh"
ingress {
from_port = 0
to_port = 65535
rule_no = 100
action = "allow"
protocol = "-1"
cidr_block = "0.0.0.0/0"
}
egress {
from_port = 80
to_port = 80
rule_no = 32767
action = "deny"
protocol = "-1"
cidr_block = "0.0.0.0/0"
}
tags {
Name = "fuga"
}
}
EOS
end
end
describe ".tfstate" do
it "should generate tfstate" do
expect(described_class.tfstate(client)).to eq JSON.pretty_generate({
"version" => 1,
"serial" => 1,
"modules" => {
"path" => [
"root"
],
"outputs" => {},
"resources" => {
"aws_network_acl.hoge" => {
"type" => "aws_network_acl",
"primary" => {
"id" => "acl-1234abcd",
"attributes" => {
"egress.#" => "1",
"id" => "acl-1234abcd",
"ingress.#" => "1",
"tags.#" => "1",
"vpc_id" => "vpc-1234abcd",
}
}
},
"aws_network_acl.fuga" => {
"type" => "aws_network_acl",
"primary" => {
"id" => "acl-5678efgh",
"attributes" => {
"egress.#" => "1",
"id" => "acl-5678efgh",
"ingress.#" => "1",
"tags.#" => "1",
"vpc_id" => "vpc-5678efgh",
}
}
}
}
}
})
end
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment