Skip to content

Commit

Permalink
Add support for AWS VPC Network ACLs
Browse files Browse the repository at this point in the history
  • Loading branch information
drcapulet committed Dec 20, 2013
1 parent 13090e9 commit 9fc0338
Show file tree
Hide file tree
Showing 21 changed files with 1,285 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/fog/aws.rb
Expand Up @@ -251,6 +251,12 @@ def self.security_group_id
"sg-#{Fog::Mock.random_hex(8)}"
end

def self.network_acl_id
"acl-#{Fog::Mock.random_hex(8)}"
end
def self.network_acl_association_id
"aclassoc-#{Fog::Mock.random_hex(8)}"
end
def self.network_interface_id
"eni-#{Fog::Mock.random_hex(8)}"
end
Expand Down
10 changes: 10 additions & 0 deletions lib/fog/aws/compute.rb
Expand Up @@ -24,6 +24,8 @@ class AWS < Fog::Service
collection :internet_gateways
model :key_pair
collection :key_pairs
model :network_acl
collection :network_acls
model :network_interface
collection :network_interfaces
model :route_table
Expand Down Expand Up @@ -60,6 +62,8 @@ class AWS < Fog::Service
request :create_internet_gateway
request :create_image
request :create_key_pair
request :create_network_acl
request :create_network_acl_entry
request :create_network_interface
request :create_placement_group
request :create_route
Expand All @@ -76,6 +80,8 @@ class AWS < Fog::Service
request :delete_dhcp_options
request :delete_internet_gateway
request :delete_key_pair
request :delete_network_acl
request :delete_network_acl_entry
request :delete_network_interface
request :delete_security_group
request :delete_placement_group
Expand All @@ -98,6 +104,7 @@ class AWS < Fog::Service
request :describe_reserved_instances
request :describe_instance_status
request :describe_key_pairs
request :describe_network_acls
request :describe_network_interface_attribute
request :describe_network_interfaces
request :describe_route_tables
Expand Down Expand Up @@ -131,6 +138,8 @@ class AWS < Fog::Service
request :purchase_reserved_instances_offering
request :reboot_instances
request :release_address
request :replace_network_acl_association
request :replace_network_acl_entry
request :register_image
request :request_spot_instances
request :reset_network_interface_attribute
Expand Down Expand Up @@ -214,6 +223,7 @@ def self.data
'ipPermissions' => [],
},
},
:network_acls => {},
:network_interfaces => {},
:snapshots => {},
:volumes => {},
Expand Down
170 changes: 170 additions & 0 deletions lib/fog/aws/models/compute/network_acl.rb
@@ -0,0 +1,170 @@
require 'fog/core/model'

module Fog
module Compute
class AWS

class NetworkAcl < Fog::Model
ICMP = 1
TCP = 6
UDP = 17

identity :network_acl_id, :aliases => 'networkAclId'
attribute :vpc_id, :aliases => 'vpcId'
attribute :default
attribute :entries, :aliases => 'entrySet'
attribute :associations, :aliases => 'associationSet'
attribute :tags, :aliases => 'tagSet'

# Add an inbound rule, shortcut method for #add_rule
def add_inbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
add_rule(rule_number, protocol, rule_action, cidr_block, false, options)
end

# Add an outbound rule, shortcut method for #add_rule
def add_outbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
add_rule(rule_number, protocol, rule_action, cidr_block, true, options)
end

# Add a new rule
#
# network_acl.add_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', true, 'PortRange.From' => 22, 'PortRange.To' => 22)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * protocol<~Integer> - The IP protocol to which the rule applies. You can use -1 to mean all protocols.
# * rule_action<~String> - Allows or denies traffic that matches the rule. (either allow or deny)
# * cidr_block<~String> - The CIDR range to allow or deny
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
# * options<~Hash>:
# * 'Icmp.Code' - ICMP code, required if protocol is 1
# * 'Icmp.Type' - ICMP type, required if protocol is 1
# * 'PortRange.From' - The first port in the range, required if protocol is 6 (TCP) or 17 (UDP)
# * 'PortRange.To' - The last port in the range, required if protocol is 6 (TCP) or 17 (UDP)
#
# ==== Returns
#
# True or false depending on the result
#
def add_rule(rule_number, protocol, rule_action, cidr_block, egress, options = {})
requires :network_acl_id

service.create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options)
true
end

# Remove an inbound rule, shortcut method for #remove_rule
def remove_inbound_rule(rule_number)
remove_rule(rule_number, false)
end

# Remove an outbound rule, shortcut method for #remove_rule
def remove_outbound_rule(rule_number)
remove_rule(rule_number, true)
end

# Update a specific rule number
#
# network_acl.remove_rule(100, true)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
#
# ==== Returns
#
# True or false depending on the result
#
def remove_rule(rule_number, egress)
requires :network_acl_id

service.delete_network_acl_entry(network_acl_id, rule_number, egress)
true
end

# Update an inbound rule, shortcut method for #update_rule
def update_inbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
update_rule(rule_number, protocol, rule_action, cidr_block, false, options)
end

# Update an outbound rule, shortcut method for #update_rule
def update_outbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
update_rule(rule_number, protocol, rule_action, cidr_block, true, options)
end

# Update a specific rule number
#
# network_acl.update_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', true, 'PortRange.From' => 22, 'PortRange.To' => 22)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * protocol<~Integer> - The IP protocol to which the rule applies. You can use -1 to mean all protocols.
# * rule_action<~String> - Allows or denies traffic that matches the rule. (either allow or deny)
# * cidr_block<~String> - The CIDR range to allow or deny
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
# * options<~Hash>:
# * 'Icmp.Code' - ICMP code, required if protocol is 1
# * 'Icmp.Type' - ICMP type, required if protocol is 1
# * 'PortRange.From' - The first port in the range, required if protocol is 6 (TCP) or 17 (UDP)
# * 'PortRange.To' - The last port in the range, required if protocol is 6 (TCP) or 17 (UDP)
#
# ==== Returns
#
# True or false depending on the result
#
def update_rule(rule_number, protocol, rule_action, cidr_block, egress, options = {})
requires :network_acl_id

service.replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options)
true
end

# Associate a subnet with this network ACL
#
# network_acl.associate_with(subnet)
#
# ==== Parameters
# * subnet<~Subnet> - Subnet object to associate with this network ACL
#
# ==== Returns
#
# True or false depending on the result
#
def associate_with(subnet)
requires :network_acl_id

# We have to manually find out the network ACL the subnet is currently associated with
old_id = service.network_acls.all('association.subnet-id' => subnet.subnet_id).first.associations.detect { |a| a['subnetId'] == subnet.subnet_id }['networkAclAssociationId']
service.replace_network_acl_association(old_id, network_acl_id)
true
end

# Removes an existing network ACL
#
# network_acl.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :network_acl_id

service.delete_network_acl(network_acl_id)
true
end

# Create a network ACL
#
# >> g = AWS.network_acls.new(:vpc_id => 'vpc-abcdefgh')
# >> g.save
def save
requires :vpc_id
data = service.create_network_acl(vpc_id).body['networkAcl']
merge_attributes(data)
true
end
end
end
end
end
138 changes: 138 additions & 0 deletions lib/fog/aws/models/compute/network_acls.rb
@@ -0,0 +1,138 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/network_acl'

module Fog
module Compute
class AWS

class NetworkAcls < Fog::Collection

attribute :filters

model Fog::Compute::AWS::NetworkAcl

# Creates a new network ACL
#
# AWS.network_acls.new
#
# ==== Returns
#
# Returns the details of the new network ACL
#
#>> <Fog::Compute::AWS::NetworkAcl
# network_acl_id=nil,
# vpc_id=nil,
# default=nil,
# entries=nil,
# associations=nil,
# tags=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end

# Returns an array of all network ACLs that have been created
#
# AWS.network_acls.all
#
# ==== Returns
#
# Returns an array of all network ACLs
#
#>> AWS.network_acls.all
# <Fog::AWS::Compute::NetworkAcls
# filters={}
# [
# <Fog::Compute::AWS::NetworkAcl
# network_acl_id="acl-abcdefgh",
# vpc_id="vpc-abcdefgh",
# default=true,
# entries=[
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => false,
# "cidrBlock" => "0.0.0.0/0"
# },
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => true,
# "cidrBlock" => "0.0.0.0/0"
# }
# ],
# associations=[
# {
# "networkAclAssociationId" => "aclassoc-abcdefgh",
# "networkAclId" => "acl-abcdefgh",
# "subnetId" => "subnet-abcdefgh"
# }
# ],
# tags={}
# >
# ]
# >
#
def all(filters = filters)
self.filters = filters
data = service.describe_network_acls(filters).body
load(data['networkAclSet'])
end

# Used to retrieve a network interface
# network interface id is required to get any information
#
# You can run the following command to get the details:
# AWS.network_interfaces.get("eni-11223344")
#
# ==== Returns
#
#>> AWS.network_acls.get("acl-abcdefgh")
# <Fog::Compute::AWS::NetworkAcl
# network_acl_id="acl-abcdefgh",
# vpc_id="vpc-abcdefgh",
# default=true,
# entries=[
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => false,
# "cidrBlock" => "0.0.0.0/0"
# },
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => true,
# "cidrBlock" => "0.0.0.0/0"
# }
# ],
# associations=[
# {
# "networkAclAssociationId" => "aclassoc-abcdefgh",
# "networkAclId" => "acl-abcdefgh",
# "subnetId" => "subnet-abcdefgh"
# }
# ],
# tags={}
# >
def get(nacl_id)
self.class.new(:service => service).all('network-acl-id' => nacl_id).first if nacl_id
end
end
end
end
end

0 comments on commit 9fc0338

Please sign in to comment.