Add support for AWS VPC Network ACLs
This commit is contained in:
parent
13090e998b
commit
9fc03381dc
|
@ -251,6 +251,12 @@ module Fog
|
||||||
"sg-#{Fog::Mock.random_hex(8)}"
|
"sg-#{Fog::Mock.random_hex(8)}"
|
||||||
end
|
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
|
def self.network_interface_id
|
||||||
"eni-#{Fog::Mock.random_hex(8)}"
|
"eni-#{Fog::Mock.random_hex(8)}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,8 @@ module Fog
|
||||||
collection :internet_gateways
|
collection :internet_gateways
|
||||||
model :key_pair
|
model :key_pair
|
||||||
collection :key_pairs
|
collection :key_pairs
|
||||||
|
model :network_acl
|
||||||
|
collection :network_acls
|
||||||
model :network_interface
|
model :network_interface
|
||||||
collection :network_interfaces
|
collection :network_interfaces
|
||||||
model :route_table
|
model :route_table
|
||||||
|
@ -60,6 +62,8 @@ module Fog
|
||||||
request :create_internet_gateway
|
request :create_internet_gateway
|
||||||
request :create_image
|
request :create_image
|
||||||
request :create_key_pair
|
request :create_key_pair
|
||||||
|
request :create_network_acl
|
||||||
|
request :create_network_acl_entry
|
||||||
request :create_network_interface
|
request :create_network_interface
|
||||||
request :create_placement_group
|
request :create_placement_group
|
||||||
request :create_route
|
request :create_route
|
||||||
|
@ -76,6 +80,8 @@ module Fog
|
||||||
request :delete_dhcp_options
|
request :delete_dhcp_options
|
||||||
request :delete_internet_gateway
|
request :delete_internet_gateway
|
||||||
request :delete_key_pair
|
request :delete_key_pair
|
||||||
|
request :delete_network_acl
|
||||||
|
request :delete_network_acl_entry
|
||||||
request :delete_network_interface
|
request :delete_network_interface
|
||||||
request :delete_security_group
|
request :delete_security_group
|
||||||
request :delete_placement_group
|
request :delete_placement_group
|
||||||
|
@ -98,6 +104,7 @@ module Fog
|
||||||
request :describe_reserved_instances
|
request :describe_reserved_instances
|
||||||
request :describe_instance_status
|
request :describe_instance_status
|
||||||
request :describe_key_pairs
|
request :describe_key_pairs
|
||||||
|
request :describe_network_acls
|
||||||
request :describe_network_interface_attribute
|
request :describe_network_interface_attribute
|
||||||
request :describe_network_interfaces
|
request :describe_network_interfaces
|
||||||
request :describe_route_tables
|
request :describe_route_tables
|
||||||
|
@ -131,6 +138,8 @@ module Fog
|
||||||
request :purchase_reserved_instances_offering
|
request :purchase_reserved_instances_offering
|
||||||
request :reboot_instances
|
request :reboot_instances
|
||||||
request :release_address
|
request :release_address
|
||||||
|
request :replace_network_acl_association
|
||||||
|
request :replace_network_acl_entry
|
||||||
request :register_image
|
request :register_image
|
||||||
request :request_spot_instances
|
request :request_spot_instances
|
||||||
request :reset_network_interface_attribute
|
request :reset_network_interface_attribute
|
||||||
|
@ -214,6 +223,7 @@ module Fog
|
||||||
'ipPermissions' => [],
|
'ipPermissions' => [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
:network_acls => {},
|
||||||
:network_interfaces => {},
|
:network_interfaces => {},
|
||||||
:snapshots => {},
|
:snapshots => {},
|
||||||
:volumes => {},
|
:volumes => {},
|
||||||
|
|
|
@ -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
|
|
@ -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,0 +1,28 @@
|
||||||
|
module Fog
|
||||||
|
module Parsers
|
||||||
|
module Compute
|
||||||
|
module AWS
|
||||||
|
require 'fog/aws/parsers/compute/network_acl_parser'
|
||||||
|
|
||||||
|
class CreateNetworkAcl < NetworkAclParser
|
||||||
|
def reset
|
||||||
|
super
|
||||||
|
@response = { 'networkAcl' => {} }
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_element(name)
|
||||||
|
case name
|
||||||
|
when 'requestId'
|
||||||
|
@response[name] = value
|
||||||
|
when 'networkAcl'
|
||||||
|
@response['networkAcl'] = @network_acl
|
||||||
|
reset_nacl
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,42 @@
|
||||||
|
module Fog
|
||||||
|
module Parsers
|
||||||
|
module Compute
|
||||||
|
module AWS
|
||||||
|
require 'fog/aws/parsers/compute/network_acl_parser'
|
||||||
|
|
||||||
|
class DescribeNetworkAcls < NetworkAclParser
|
||||||
|
def reset
|
||||||
|
super
|
||||||
|
@response = { 'networkAclSet' => [] }
|
||||||
|
@item_level = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def start_element(name, attrs = [])
|
||||||
|
super
|
||||||
|
case name
|
||||||
|
when 'item'
|
||||||
|
@item_level += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_element(name)
|
||||||
|
case name
|
||||||
|
when 'requestId'
|
||||||
|
@response[name] = value
|
||||||
|
when 'item'
|
||||||
|
@item_level -= 1
|
||||||
|
if @item_level == 0
|
||||||
|
@response['networkAclSet'] << @network_acl
|
||||||
|
reset_nacl
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,105 @@
|
||||||
|
module Fog
|
||||||
|
module Parsers
|
||||||
|
module Compute
|
||||||
|
module AWS
|
||||||
|
|
||||||
|
class NetworkAclParser < Fog::Parsers::Base
|
||||||
|
def reset_nacl
|
||||||
|
@network_acl = { 'associationSet' => [], 'entrySet' => [], 'tagSet' => {} }
|
||||||
|
@association = {}
|
||||||
|
@entry = { 'icmpTypeCode' => {}, 'portRange' => {} }
|
||||||
|
@tag = {}
|
||||||
|
|
||||||
|
@in_entry_set = false
|
||||||
|
@in_association_set = false
|
||||||
|
@in_tag_set = false
|
||||||
|
@in_port_range = false
|
||||||
|
@in_icmp_type_code = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset
|
||||||
|
reset_nacl
|
||||||
|
end
|
||||||
|
|
||||||
|
def start_element(name, attrs = [])
|
||||||
|
super
|
||||||
|
case name
|
||||||
|
when 'entrySet'
|
||||||
|
@in_entry_set = true
|
||||||
|
when 'associationSet'
|
||||||
|
@in_association_set = true
|
||||||
|
when 'tagSet'
|
||||||
|
@in_tag_set = true
|
||||||
|
when 'portRange'
|
||||||
|
@in_port_range = true
|
||||||
|
when 'icmpTypeCode'
|
||||||
|
@in_icmp_type_code = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_element(name)
|
||||||
|
if @in_entry_set
|
||||||
|
if @in_port_range
|
||||||
|
case name
|
||||||
|
when 'portRange'
|
||||||
|
@in_port_range = false
|
||||||
|
when 'from', 'to'
|
||||||
|
@entry['portRange'][name] = value.to_i
|
||||||
|
end
|
||||||
|
elsif @in_icmp_type_code
|
||||||
|
case name
|
||||||
|
when 'icmpTypeCode'
|
||||||
|
@in_icmp_type_code = false
|
||||||
|
when 'code', 'type'
|
||||||
|
@entry['icmpTypeCode'][name] = value.to_i
|
||||||
|
end
|
||||||
|
else
|
||||||
|
case name
|
||||||
|
when 'entrySet'
|
||||||
|
@in_entry_set = false
|
||||||
|
when 'item'
|
||||||
|
@network_acl['entrySet'] << @entry
|
||||||
|
@entry = { 'icmpTypeCode' => {}, 'portRange' => {} }
|
||||||
|
when 'ruleNumber', 'protocol'
|
||||||
|
@entry[name] = value.to_i
|
||||||
|
when 'ruleAction', 'cidrBlock'
|
||||||
|
@entry[name] = value
|
||||||
|
when 'egress'
|
||||||
|
@entry[name] = value == 'true'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif @in_association_set
|
||||||
|
case name
|
||||||
|
when 'associationSet'
|
||||||
|
@in_association_set = false
|
||||||
|
when 'item'
|
||||||
|
@network_acl['associationSet'] << @association
|
||||||
|
@association = {}
|
||||||
|
when 'networkAclAssociationId', 'networkAclId', 'subnetId'
|
||||||
|
@association[name] = value
|
||||||
|
end
|
||||||
|
elsif @in_tag_set
|
||||||
|
case name
|
||||||
|
when 'tagSet'
|
||||||
|
@in_tag_set = false
|
||||||
|
when 'item'
|
||||||
|
@network_acl['tagSet'][@tag['key']] = @tag['value']
|
||||||
|
@tag = {}
|
||||||
|
when 'key', 'value'
|
||||||
|
@tag[name] = value
|
||||||
|
end
|
||||||
|
else
|
||||||
|
case name
|
||||||
|
when 'networkAclId', 'vpcId'
|
||||||
|
@network_acl[name] = value
|
||||||
|
when 'default'
|
||||||
|
@network_acl[name] = value == 'true'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
module Fog
|
||||||
|
module Parsers
|
||||||
|
module Compute
|
||||||
|
module AWS
|
||||||
|
class ReplaceNetworkAclAssociation < Fog::Parsers::Base
|
||||||
|
def reset
|
||||||
|
@response = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_element(name)
|
||||||
|
case name
|
||||||
|
when 'requestId', 'newAssociationId'
|
||||||
|
@response[name] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,105 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/create_network_acl'
|
||||||
|
|
||||||
|
# Creates a network ACL
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * vpcId<~String> - The ID of the VPC to create this network ACL under
|
||||||
|
#
|
||||||
|
# === Returns
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'networkAcl'<~Array>: - The network ACL
|
||||||
|
# * 'networkAclId'<~String> - The ID of the network ACL
|
||||||
|
# * 'vpcId'<~String> - The ID of the VPC for the network ACL
|
||||||
|
# * 'default'<~Boolean> - Indicates whether this is the default network ACL for the VPC
|
||||||
|
# * 'entrySet'<~Array>: - A list of entries (rules) in the network ACL
|
||||||
|
# * 'ruleNumber'<~Integer> - The rule number for the entry. ACL entries are processed in ascending order by rule number
|
||||||
|
# * 'protocol'<~Integer> - The protocol. A value of -1 means all protocols
|
||||||
|
# * 'ruleAction'<~String> - Indicates whether to allow or deny the traffic that matches the rule
|
||||||
|
# * 'egress'<~Boolean> - Indicates whether the rule is an egress rule (applied to traffic leaving the subnet)
|
||||||
|
# * 'cidrBlock'<~String> - The network range to allow or deny, in CIDR notation
|
||||||
|
# * 'icmpTypeCode'<~Hash> - ICMP protocol: The ICMP type and code
|
||||||
|
# * 'code'<~Integer> - The ICMP code. A value of -1 means all codes for the specified ICMP type
|
||||||
|
# * 'type'<~Integer> - The ICMP type. A value of -1 means all types
|
||||||
|
# * 'portRange'<~Hash> - TCP or UDP protocols: The range of ports the rule applies to
|
||||||
|
# * 'from'<~Integer> - The first port in the range
|
||||||
|
# * 'to'<~Integer> - The last port in the range
|
||||||
|
# * 'associationSet'<~Array>: - A list of associations between the network ACL and subnets
|
||||||
|
# * 'networkAclAssociationId'<~String> - The ID of the association
|
||||||
|
# * 'networkAclId'<~String> - The ID of the network ACL
|
||||||
|
# * 'subnetId'<~String> - The ID of the subnet
|
||||||
|
# * 'tagSet'<~Array>: - Tags assigned to the resource.
|
||||||
|
# * 'key'<~String> - Tag's key
|
||||||
|
# * 'value'<~String> - Tag's value
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-CreateNetworkAcl.html]
|
||||||
|
def create_network_acl(vpcId, options = {})
|
||||||
|
request({
|
||||||
|
'Action' => 'CreateNetworkAcl',
|
||||||
|
'VpcId' => vpcId,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::CreateNetworkAcl.new
|
||||||
|
}.merge!(options))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def create_network_acl(vpcId, options = {})
|
||||||
|
response = Excon::Response.new
|
||||||
|
if vpcId
|
||||||
|
id = Fog::AWS::Mock.network_acl_id
|
||||||
|
|
||||||
|
unless self.data[:vpcs].detect { |s| s['vpcId'] == vpcId }
|
||||||
|
raise Fog::Compute::AWS::Error.new("Unknown VPC '#{vpcId}' specified")
|
||||||
|
end
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'networkAclId' => id,
|
||||||
|
'vpcId' => vpcId,
|
||||||
|
'default' => false,
|
||||||
|
'entrySet' => [
|
||||||
|
{
|
||||||
|
'icmpTypeCode' => {},
|
||||||
|
'portRange' => {},
|
||||||
|
'ruleNumber' => 32767,
|
||||||
|
'protocol' => -1,
|
||||||
|
'ruleAction' => "deny",
|
||||||
|
'egress' => true,
|
||||||
|
'cidrBlock' => "0.0.0.0/0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icmpTypeCode' => {},
|
||||||
|
'portRange' => {},
|
||||||
|
'ruleNumber' => 32767,
|
||||||
|
'protocol' => -1,
|
||||||
|
'ruleAction' => "deny",
|
||||||
|
'egress' => false,
|
||||||
|
'cidrBlock' => "0.0.0.0/0",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'associationSet' => [],
|
||||||
|
'tagSet' => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.data[:network_acls][id] = data
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'networkAcl' => data
|
||||||
|
}
|
||||||
|
else
|
||||||
|
response.status = 400
|
||||||
|
response.body = {
|
||||||
|
'Code' => 'InvalidParameterValue',
|
||||||
|
'Message' => "Invalid value '' for subnetId"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,80 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/basic'
|
||||||
|
|
||||||
|
# Creates a Network ACL entry
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * network_acl_id<~String> - The ID of the ACL to add this entry to
|
||||||
|
# * 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
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'return'<~Boolean> - Returns true if the request succeeds.
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-CreateNetworkAclEntry.html]
|
||||||
|
def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options = {})
|
||||||
|
request({
|
||||||
|
'Action' => 'CreateNetworkAclEntry',
|
||||||
|
'NetworkAclId' => network_acl_id,
|
||||||
|
'RuleNumber' => rule_number,
|
||||||
|
'Protocol' => protocol,
|
||||||
|
'RuleAction' => rule_action,
|
||||||
|
'Egress' => egress,
|
||||||
|
'CidrBlock' => cidr_block,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::Basic.new
|
||||||
|
}.merge!(options))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options = {})
|
||||||
|
response = Excon::Response.new
|
||||||
|
if self.data[:network_acls][network_acl_id]
|
||||||
|
|
||||||
|
if self.data[:network_acls][network_acl_id]['entrySet'].detect { |r| r['ruleNumber'] == rule_number && r['egress'] == egress }
|
||||||
|
raise Fog::Compute::AWS::Error.new("Already a rule with that number")
|
||||||
|
end
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'ruleNumber' => rule_number,
|
||||||
|
'protocol' => protocol,
|
||||||
|
'ruleAction' => rule_action,
|
||||||
|
'egress' => egress,
|
||||||
|
'cidrBlock' => cidr_block,
|
||||||
|
'icmpTypeCode' => {},
|
||||||
|
'portRange' => {}
|
||||||
|
}
|
||||||
|
data['icmpTypeCode']['code'] = options['Icmp.Code'] if options['Icmp.Code']
|
||||||
|
data['icmpTypeCode']['type'] = options['Icmp.Type'] if options['Icmp.Type']
|
||||||
|
data['portRange']['from'] = options['PortRange.From'] if options['PortRange.From']
|
||||||
|
data['portRange']['to'] = options['PortRange.To'] if options['PortRange.To']
|
||||||
|
self.data[:network_acls][network_acl_id]['entrySet'] << data
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'return' => true
|
||||||
|
}
|
||||||
|
response
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::NotFound.new("The network ACL '#{network_acl_id}' does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -56,6 +56,17 @@ module Fog
|
||||||
'tagSet' => {}
|
'tagSet' => {}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Add this subnet to the default network ACL
|
||||||
|
accid = Fog::AWS::Mock.network_acl_association_id
|
||||||
|
default_nacl = self.data[:network_acls].values.detect { |nacl| nacl['vpcId'] == vpcId && nacl['default'] }
|
||||||
|
if default_nacl
|
||||||
|
default_nacl['associationSet'] << {
|
||||||
|
'networkAclAssociationId' => accid,
|
||||||
|
'networkAclId' => default_nacl['networkAclId'],
|
||||||
|
'subnetId' => self.data[:subnets].last['subnetId'],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
response.body = {
|
response.body = {
|
||||||
'requestId' => Fog::AWS::Mock.request_id,
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
'subnetSet' => self.data[:subnets]
|
'subnetSet' => self.data[:subnets]
|
||||||
|
|
|
@ -66,6 +66,12 @@ module Fog
|
||||||
assoc = add_route_association(default_route.id, nil, true)
|
assoc = add_route_association(default_route.id, nil, true)
|
||||||
route_table["associationSet"].push(assoc)
|
route_table["associationSet"].push(assoc)
|
||||||
|
|
||||||
|
# Create a default network ACL
|
||||||
|
default_nacl = self.network_acls.new(:vpc_id => vpc_id)
|
||||||
|
default_nacl.save
|
||||||
|
# Manually override since Amazon doesn't let you create a default one
|
||||||
|
self.data[:network_acls][default_nacl.network_acl_id]['default'] = true
|
||||||
|
|
||||||
response.body = {
|
response.body = {
|
||||||
'requestId' => Fog::AWS::Mock.request_id,
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
'vpcSet' => self.data[:vpcs]
|
'vpcSet' => self.data[:vpcs]
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/basic'
|
||||||
|
|
||||||
|
# Deletes a network ACL.
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * network_acl_id<~String> - The ID of the network ACL you want to delete.
|
||||||
|
#
|
||||||
|
# === Returns
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'return'<~Boolean> - Returns true if the request succeeds.
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteNetworkAcl.html]
|
||||||
|
def delete_network_acl(network_acl_id)
|
||||||
|
request(
|
||||||
|
'Action' => 'DeleteNetworkAcl',
|
||||||
|
'NetworkAclId' => network_acl_id,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::Basic.new
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def delete_network_acl(network_acl_id)
|
||||||
|
response = Excon::Response.new
|
||||||
|
if self.data[:network_acls][network_acl_id]
|
||||||
|
|
||||||
|
if self.data[:network_acls][network_acl_id]['associationSet'].any?
|
||||||
|
raise Fog::Compute::AWS::Error.new("ACL is in use")
|
||||||
|
end
|
||||||
|
|
||||||
|
self.data[:network_acls].delete(network_acl_id)
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'return' => true
|
||||||
|
}
|
||||||
|
response
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::NotFound.new("The network ACL '#{network_acl_id}' does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,55 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/basic'
|
||||||
|
|
||||||
|
# Deletes a network ACL entry
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * network_acl_id<~String> - The ID of the network ACL
|
||||||
|
# * rule_number<~Integer> - The rule number of the entry to delete.
|
||||||
|
# * egress<~Boolean> - Indicates whether the rule is an egress rule (true) or ingress rule (false)
|
||||||
|
#
|
||||||
|
# === Returns
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'return'<~Boolean> - Returns true if the request succeeds.
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteNetworkAclEntry.html]
|
||||||
|
def delete_network_acl_entry(network_acl_id, rule_number, egress)
|
||||||
|
request(
|
||||||
|
'Action' => 'DeleteNetworkAclEntry',
|
||||||
|
'NetworkAclId' => network_acl_id,
|
||||||
|
'RuleNumber' => rule_number,
|
||||||
|
'Egress' => egress,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::Basic.new
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def delete_network_acl_entry(network_acl_id, rule_number, egress)
|
||||||
|
response = Excon::Response.new
|
||||||
|
if self.data[:network_acls][network_acl_id]
|
||||||
|
if self.data[:network_acls][network_acl_id]['entrySet'].detect { |r| r['ruleNumber'] == rule_number && r['egress'] == egress }
|
||||||
|
self.data[:network_acls][network_acl_id]['entrySet'].delete_if { |r| r['ruleNumber'] == rule_number && r['egress'] == egress }
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::Error.new("No rule with that number and egress value")
|
||||||
|
end
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'return' => true
|
||||||
|
}
|
||||||
|
response
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::NotFound.new("The network ACL '#{network_acl_id}' does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,6 +36,10 @@ module Fog
|
||||||
response.status = 200
|
response.status = 200
|
||||||
self.data[:vpcs].reject! { |v| v['vpcId'] == vpc_id }
|
self.data[:vpcs].reject! { |v| v['vpcId'] == vpc_id }
|
||||||
|
|
||||||
|
# Delete the default network ACL
|
||||||
|
network_acl_id = self.network_acls.all('vpc-id' => vpc_id, 'default' => true).first.network_acl_id
|
||||||
|
self.data[:network_acls].delete(network_acl_id)
|
||||||
|
|
||||||
response.body = {
|
response.body = {
|
||||||
'requestId' => Fog::AWS::Mock.request_id,
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
'return' => true
|
'return' => true
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
|
||||||
|
require 'fog/aws/parsers/compute/describe_network_acls'
|
||||||
|
|
||||||
|
# Describe all or specified network ACLs
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * filters<~Hash> - List of filters to limit results with
|
||||||
|
#
|
||||||
|
# === Returns
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'networkAclSet'<~Array>: - A list of network ACLs
|
||||||
|
# * 'networkAclId'<~String> - The ID of the network ACL
|
||||||
|
# * 'vpcId'<~String> - The ID of the VPC for the network ACL
|
||||||
|
# * 'default'<~Boolean> - Indicates whether this is the default network ACL for the VPC
|
||||||
|
# * 'entrySet'<~Array>: - A list of entries (rules) in the network ACL
|
||||||
|
# * 'ruleNumber'<~Integer> - The rule number for the entry. ACL entries are processed in ascending order by rule number
|
||||||
|
# * 'protocol'<~Integer> - The protocol. A value of -1 means all protocols
|
||||||
|
# * 'ruleAction'<~String> - Indicates whether to allow or deny the traffic that matches the rule
|
||||||
|
# * 'egress'<~Boolean> - Indicates whether the rule is an egress rule (applied to traffic leaving the subnet)
|
||||||
|
# * 'cidrBlock'<~String> - The network range to allow or deny, in CIDR notation
|
||||||
|
# * 'icmpTypeCode'<~Hash> - ICMP protocol: The ICMP type and code
|
||||||
|
# * 'code'<~Integer> - The ICMP code. A value of -1 means all codes for the specified ICMP type
|
||||||
|
# * 'type'<~Integer> - The ICMP type. A value of -1 means all types
|
||||||
|
# * 'portRange'<~Hash> - TCP or UDP protocols: The range of ports the rule applies to
|
||||||
|
# * 'from'<~Integer> - The first port in the range
|
||||||
|
# * 'to'<~Integer> - The last port in the range
|
||||||
|
# * 'associationSet'<~Array>: - A list of associations between the network ACL and subnets
|
||||||
|
# * 'networkAclAssociationId'<~String> - The ID of the association
|
||||||
|
# * 'networkAclId'<~String> - The ID of the network ACL
|
||||||
|
# * 'subnetId'<~String> - The ID of the subnet
|
||||||
|
# * 'tagSet'<~Array>: - Tags assigned to the resource.
|
||||||
|
# * 'key'<~String> - Tag's key
|
||||||
|
# * 'value'<~String> - Tag's value
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeNetworkAcls.html]
|
||||||
|
def describe_network_acls(filters = {})
|
||||||
|
params = Fog::AWS.indexed_filters(filters)
|
||||||
|
request({
|
||||||
|
'Action' => 'DescribeNetworkAcls',
|
||||||
|
:idempotent => true,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::DescribeNetworkAcls.new
|
||||||
|
}.merge!(params))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def describe_network_acls(filters = {})
|
||||||
|
response = Excon::Response.new
|
||||||
|
|
||||||
|
network_acls = self.data[:network_acls].values
|
||||||
|
|
||||||
|
aliases = {
|
||||||
|
'vpc-id' => 'vpcId',
|
||||||
|
'network-acl-id' => 'networkAclId',
|
||||||
|
'default' => 'default',
|
||||||
|
}
|
||||||
|
association_aliases = {
|
||||||
|
'association-id' => 'networkAclAssociationId',
|
||||||
|
'network-acl-id' => 'networkAclId',
|
||||||
|
'subnet-id' => 'subnetId',
|
||||||
|
}
|
||||||
|
entry_aliases = {
|
||||||
|
'cidr' => 'cidrBlock',
|
||||||
|
'egress' => 'egress',
|
||||||
|
'rule-action' => 'ruleAction',
|
||||||
|
'rule-number' => 'ruleNumber',
|
||||||
|
'protocol' => 'protocol',
|
||||||
|
'egress' => 'egress',
|
||||||
|
}
|
||||||
|
for filter_key, filter_value in filters
|
||||||
|
filter_key = filter_key.to_s
|
||||||
|
if association_key = filter_key.split('association.')[1]
|
||||||
|
aliased_key = association_aliases[association_key]
|
||||||
|
network_acls = network_acls.reject{|nacl| !nacl['associationSet'].detect {|association| [*filter_value].include?(association[aliased_key])}}
|
||||||
|
elsif entry_key = filter_key.split('entry.icmp.')[1]
|
||||||
|
network_acls = network_acls.reject{|nacl| !nacl['entrySet'].detect {|association| [*filter_value].include?(association['icmpTypeCode'][entry_key])}}
|
||||||
|
elsif entry_key = filter_key.split('entry.port-range.')[1]
|
||||||
|
network_acls = network_acls.reject{|nacl| !nacl['entrySet'].detect {|association| [*filter_value].include?(association['portRange'][entry_key])}}
|
||||||
|
elsif entry_key = filter_key.split('entry.')[1]
|
||||||
|
aliased_key = entry_aliases[entry_key]
|
||||||
|
network_acls = network_acls.reject{|nacl| !nacl['entrySet'].detect {|association| [*filter_value].include?(association[aliased_key])}}
|
||||||
|
else
|
||||||
|
aliased_key = aliases[filter_key]
|
||||||
|
network_acls = network_acls.reject{|nacl| ![*filter_value].include?(nacl[aliased_key])}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'networkAclSet' => network_acls
|
||||||
|
}
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,66 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/replace_network_acl_association'
|
||||||
|
|
||||||
|
# Replace the network ACL for a subnet with a
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * association_id<~String> - The ID of the current association between the original network ACL and the subnet
|
||||||
|
# * network_acl_id<~String> - The ID of the network ACL
|
||||||
|
#
|
||||||
|
# === Returns
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'return'<~Boolean> - Returns true if the request succeeds.
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-ReplaceNetworkAclAssociation.html]
|
||||||
|
def replace_network_acl_association(association_id, network_acl_id)
|
||||||
|
request({
|
||||||
|
'Action' => 'ReplaceNetworkAclAssociation',
|
||||||
|
'AssociationId' => association_id,
|
||||||
|
'NetworkAclId' => network_acl_id,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::ReplaceNetworkAclAssociation.new
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def replace_network_acl_association(association_id, network_acl_id)
|
||||||
|
response = Excon::Response.new
|
||||||
|
if self.data[:network_acls][network_acl_id]
|
||||||
|
# find the old assoc
|
||||||
|
old_nacl = self.data[:network_acls].values.detect do |n|
|
||||||
|
n['associationSet'].detect { |assoc| assoc['networkAclAssociationId'] == association_id }
|
||||||
|
end
|
||||||
|
|
||||||
|
unless old_nacl
|
||||||
|
raise Fog::Compute::AWS::Error.new("Invalid association_id #{association_id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
subnet_id = old_nacl['associationSet'].detect { |assoc| assoc['networkAclAssociationId'] == association_id }['subnetId']
|
||||||
|
old_nacl['associationSet'].delete_if { |assoc| assoc['networkAclAssociationId'] == association_id }
|
||||||
|
|
||||||
|
id = Fog::AWS::Mock.network_acl_association_id
|
||||||
|
self.data[:network_acls][network_acl_id]['associationSet'] << {
|
||||||
|
'networkAclAssociationId' => id,
|
||||||
|
'networkAclId' => network_acl_id,
|
||||||
|
'subnetId' => subnet_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'newAssociationId' => id
|
||||||
|
}
|
||||||
|
response
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::NotFound.new("The network ACL '#{network_acl_id}' does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,81 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class AWS
|
||||||
|
class Real
|
||||||
|
require 'fog/aws/parsers/compute/basic'
|
||||||
|
|
||||||
|
# Replaces a Network ACL entry with the same rule number
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * network_acl_id<~String> - The ID of the ACL to add this entry to
|
||||||
|
# * 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
|
||||||
|
# * response<~Excon::Response>:
|
||||||
|
# * body<~Hash>:
|
||||||
|
# * 'requestId'<~String> - Id of request
|
||||||
|
# * 'return'<~Boolean> - Returns true if the request succeeds.
|
||||||
|
#
|
||||||
|
# {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-ReplaceNetworkAclEntry.html]
|
||||||
|
def replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options = {})
|
||||||
|
request({
|
||||||
|
'Action' => 'ReplaceNetworkAclEntry',
|
||||||
|
'NetworkAclId' => network_acl_id,
|
||||||
|
'RuleNumber' => rule_number,
|
||||||
|
'Protocol' => protocol,
|
||||||
|
'RuleAction' => rule_action,
|
||||||
|
'Egress' => egress,
|
||||||
|
'CidrBlock' => cidr_block,
|
||||||
|
:parser => Fog::Parsers::Compute::AWS::Basic.new
|
||||||
|
}.merge!(options))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options = {})
|
||||||
|
response = Excon::Response.new
|
||||||
|
if self.data[:network_acls][network_acl_id]
|
||||||
|
|
||||||
|
unless self.data[:network_acls][network_acl_id]['entrySet'].detect { |r| r['ruleNumber'] == rule_number && r['egress'] == egress }
|
||||||
|
raise Fog::Compute::AWS::Error.new("No rule with that number")
|
||||||
|
end
|
||||||
|
self.data[:network_acls][network_acl_id]['entrySet'].delete_if { |r| r['ruleNumber'] == rule_number && r['egress'] == egress }
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'ruleNumber' => rule_number,
|
||||||
|
'protocol' => protocol,
|
||||||
|
'ruleAction' => rule_action,
|
||||||
|
'egress' => egress,
|
||||||
|
'cidrBlock' => cidr_block,
|
||||||
|
'icmpTypeCode' => {},
|
||||||
|
'portRange' => {}
|
||||||
|
}
|
||||||
|
data['icmpTypeCode']['code'] = options['Icmp.Code'] if options['Icmp.Code']
|
||||||
|
data['icmpTypeCode']['type'] = options['Icmp.Type'] if options['Icmp.Type']
|
||||||
|
data['portRange']['from'] = options['PortRange.From'] if options['PortRange.From']
|
||||||
|
data['portRange']['to'] = options['PortRange.To'] if options['PortRange.To']
|
||||||
|
self.data[:network_acls][network_acl_id]['entrySet'] << data
|
||||||
|
|
||||||
|
response.status = 200
|
||||||
|
response.body = {
|
||||||
|
'requestId' => Fog::AWS::Mock.request_id,
|
||||||
|
'return' => true
|
||||||
|
}
|
||||||
|
response
|
||||||
|
else
|
||||||
|
raise Fog::Compute::AWS::NotFound.new("The network ACL '#{network_acl_id}' does not exist")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,109 @@
|
||||||
|
Shindo.tests("Fog::Compute[:aws] | network_acl", ['aws']) do
|
||||||
|
@vpc = Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||||
|
@subnet = Fog::Compute[:aws].subnets.create('vpc_id' => @vpc.id, 'cidr_block' => '10.0.10.16/28')
|
||||||
|
|
||||||
|
model_tests(Fog::Compute[:aws].network_acls, { :vpc_id => @vpc.id }, true)
|
||||||
|
|
||||||
|
tests("associate_with") do
|
||||||
|
@new_nacl = Fog::Compute[:aws].network_acls.create(:vpc_id => @vpc.id)
|
||||||
|
@default_nacl = Fog::Compute[:aws].network_acls.all('vpc-id' => @vpc.id, 'default' => true).first
|
||||||
|
|
||||||
|
test("associate_with new_nacl") do
|
||||||
|
@new_nacl.associate_with(@subnet)
|
||||||
|
end
|
||||||
|
|
||||||
|
@new_nacl.reload
|
||||||
|
|
||||||
|
test("associate_with correctly updates new_nacl") do
|
||||||
|
@new_nacl.associations.collect { |a| a['subnetId'] } == [@subnet.subnet_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
@default_nacl.associate_with(@subnet)
|
||||||
|
@new_nacl.reload
|
||||||
|
@default_nacl.reload
|
||||||
|
|
||||||
|
test("associate_with correctly updates new_nacl after removal") do
|
||||||
|
@new_nacl.associations.collect { |a| a['subnetId'] } == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test("associate_with correctly updates default_nacl after removal") do
|
||||||
|
@default_nacl.associations.collect { |a| a['subnetId'] } == [@subnet.subnet_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
@new_nacl.destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
tests("add_rule and remove_rule") do
|
||||||
|
@new_nacl = Fog::Compute[:aws].network_acls.create(:vpc_id => @vpc.id)
|
||||||
|
default_rules = @new_nacl.entries.dup
|
||||||
|
|
||||||
|
test("add a new inbound rule") do
|
||||||
|
@new_nacl.add_inbound_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', 'PortRange.From' => 22, 'PortRange.To' => 22)
|
||||||
|
@new_nacl.reload
|
||||||
|
(@new_nacl.entries - default_rules) == [{
|
||||||
|
"icmpTypeCode" => {},
|
||||||
|
"portRange" => {
|
||||||
|
"from" => 22,
|
||||||
|
"to" => 22
|
||||||
|
},
|
||||||
|
"ruleNumber" => 100,
|
||||||
|
"protocol" => 6,
|
||||||
|
"ruleAction" => "allow",
|
||||||
|
"egress" => false,
|
||||||
|
"cidrBlock" => "0.0.0.0/0"
|
||||||
|
}]
|
||||||
|
end
|
||||||
|
|
||||||
|
test("remove inbound rule") do
|
||||||
|
@new_nacl.remove_inbound_rule(100)
|
||||||
|
@new_nacl.reload
|
||||||
|
@new_nacl.entries == default_rules
|
||||||
|
end
|
||||||
|
|
||||||
|
test("add a new outbound rule") do
|
||||||
|
@new_nacl.add_outbound_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', 'PortRange.From' => 22, 'PortRange.To' => 22)
|
||||||
|
@new_nacl.reload
|
||||||
|
(@new_nacl.entries - default_rules) == [{
|
||||||
|
"icmpTypeCode" => {},
|
||||||
|
"portRange" => {
|
||||||
|
"from" => 22,
|
||||||
|
"to" => 22
|
||||||
|
},
|
||||||
|
"ruleNumber" => 100,
|
||||||
|
"protocol" => 6,
|
||||||
|
"ruleAction" => "allow",
|
||||||
|
"egress" => true,
|
||||||
|
"cidrBlock" => "0.0.0.0/0"
|
||||||
|
}]
|
||||||
|
end
|
||||||
|
|
||||||
|
test("remove outbound rule") do
|
||||||
|
@new_nacl.remove_outbound_rule(100)
|
||||||
|
@new_nacl.reload
|
||||||
|
@new_nacl.entries == default_rules
|
||||||
|
end
|
||||||
|
|
||||||
|
test("update rule") do
|
||||||
|
@new_nacl.add_inbound_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', 'PortRange.From' => 22, 'PortRange.To' => 22)
|
||||||
|
@new_nacl.update_inbound_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '10.0.0.0/8', 'PortRange.From' => 22, 'PortRange.To' => 22)
|
||||||
|
@new_nacl.reload
|
||||||
|
(@new_nacl.entries - default_rules) == [{
|
||||||
|
"icmpTypeCode" => {},
|
||||||
|
"portRange" => {
|
||||||
|
"from" => 22,
|
||||||
|
"to" => 22
|
||||||
|
},
|
||||||
|
"ruleNumber" => 100,
|
||||||
|
"protocol" => 6,
|
||||||
|
"ruleAction" => "allow",
|
||||||
|
"egress" => false,
|
||||||
|
"cidrBlock" => "10.0.0.0/8"
|
||||||
|
}]
|
||||||
|
end
|
||||||
|
|
||||||
|
@new_nacl.destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
@subnet.destroy
|
||||||
|
@vpc.destroy
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
Shindo.tests("Fog::Compute[:aws] | network_acls", ['aws']) do
|
||||||
|
@vpc = Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||||
|
|
||||||
|
collection_tests(Fog::Compute[:aws].network_acls, { :vpc_id => @vpc.id }, true)
|
||||||
|
|
||||||
|
@vpc.destroy
|
||||||
|
end
|
|
@ -0,0 +1,86 @@
|
||||||
|
Shindo.tests('Fog::Compute[:aws] | network acl requests', ['aws']) do
|
||||||
|
|
||||||
|
@network_acl_format = {
|
||||||
|
'networkAclId' => String,
|
||||||
|
'vpcId' => String,
|
||||||
|
'default' => Fog::Boolean,
|
||||||
|
'entrySet' => [{
|
||||||
|
'ruleNumber' => Integer,
|
||||||
|
'protocol' => Integer,
|
||||||
|
'ruleAction' => String,
|
||||||
|
'egress' => Fog::Boolean,
|
||||||
|
'cidrBlock' => String,
|
||||||
|
'icmpTypeCode' => {
|
||||||
|
'code' => Fog::Nullable::Integer,
|
||||||
|
'type' => Fog::Nullable::Integer
|
||||||
|
},
|
||||||
|
'portRange' => {
|
||||||
|
'from' => Fog::Nullable::Integer,
|
||||||
|
'to' => Fog::Nullable::Integer
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'associationSet' => Array,
|
||||||
|
'tagSet' => Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
@network_acls_format = {
|
||||||
|
'requestId' => String,
|
||||||
|
'networkAclSet' => [ @network_acl_format ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@network_acl_replace_association = {
|
||||||
|
'requestId' => String,
|
||||||
|
'newAssociationId' => String
|
||||||
|
}
|
||||||
|
|
||||||
|
tests('success') do
|
||||||
|
@vpc = Fog::Compute[:aws].vpcs.create('cidr_block' => '10.0.10.0/24')
|
||||||
|
@subnet = Fog::Compute[:aws].subnets.create('vpc_id' => @vpc.id, 'cidr_block' => '10.0.10.16/28')
|
||||||
|
@network_acl = nil
|
||||||
|
|
||||||
|
# Describe network interfaces
|
||||||
|
tests('#describe_network_acls').formats(@network_acls_format) do
|
||||||
|
Fog::Compute[:aws].describe_network_acls.body
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#create_network_acl').formats(@network_acl_format) do
|
||||||
|
data = Fog::Compute[:aws].create_network_acl(@vpc.id).body
|
||||||
|
|
||||||
|
@network_acl = data['networkAcl']
|
||||||
|
data['networkAcl']
|
||||||
|
end
|
||||||
|
|
||||||
|
tests("#create_network_acl_entry").formats(AWS::Compute::Formats::BASIC) do
|
||||||
|
Fog::Compute[:aws].create_network_acl_entry(@network_acl['networkAclId'], 100, 6, 'allow', '0.0.0.0/8', false, 'PortRange.From' => 22, 'PortRange.To' => 22).body
|
||||||
|
end
|
||||||
|
|
||||||
|
tests("#replace_network_acl_entry").formats(AWS::Compute::Formats::BASIC) do
|
||||||
|
Fog::Compute[:aws].replace_network_acl_entry(@network_acl['networkAclId'], 100, 6, 'deny', '0.0.0.0/8', false, 'PortRange.From' => 22, 'PortRange.To' => 22).body
|
||||||
|
end
|
||||||
|
|
||||||
|
tests("#delete_network_acl_entry").formats(AWS::Compute::Formats::BASIC) do
|
||||||
|
Fog::Compute[:aws].delete_network_acl_entry(@network_acl['networkAclId'], 100, false).body
|
||||||
|
end
|
||||||
|
|
||||||
|
default_acl = Fog::Compute[:aws].describe_network_acls('vpc-id' => @vpc.id, 'default' => true).body['networkAclSet'].first
|
||||||
|
@assoc_id = default_acl['associationSet'].first['networkAclAssociationId']
|
||||||
|
|
||||||
|
tests("#replace_network_acl_association").formats(@network_acl_replace_association) do
|
||||||
|
data = Fog::Compute[:aws].replace_network_acl_association(@assoc_id, @network_acl['networkAclId']).body
|
||||||
|
@assoc_id = data['newAssociationId']
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
tests("#replace_network_acl_association").formats(@network_acl_replace_association) do
|
||||||
|
Fog::Compute[:aws].replace_network_acl_association(@assoc_id, default_acl['networkAclId']).body
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#delete_network_acl').formats(AWS::Compute::Formats::BASIC) do
|
||||||
|
Fog::Compute[:aws].delete_network_acl(@network_acl['networkAclId']).body
|
||||||
|
end
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
@subnet.destroy
|
||||||
|
@vpc.destroy
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue