From 36b8d1c84fb65f89d469ffbb1736a01281aabc04 Mon Sep 17 00:00:00 2001 From: Eric Herot Date: Tue, 4 Feb 2014 14:24:31 -0500 Subject: [PATCH] Implemented Replace Route --- fog.gemspec | 2 +- lib/fog/aws/compute.rb | 1 + lib/fog/aws/requests/compute/replace_route.rb | 89 +++++++++++++++++++ tests/aws/requests/compute/route_tests.rb | 36 +++++++- 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100755 lib/fog/aws/requests/compute/replace_route.rb diff --git a/fog.gemspec b/fog.gemspec index ec03a2e3a..79bb60dab 100644 --- a/fog.gemspec +++ b/fog.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| ## the sub! line in the Rakefile s.name = 'fog' s.version = '1.19.0' - s.date = '2013-12-19' + s.date = '2014-02-04' s.rubyforge_project = 'fog' ## Make sure your summary is short. The description may be as long diff --git a/lib/fog/aws/compute.rb b/lib/fog/aws/compute.rb index 3c88653e1..ac82416b7 100644 --- a/lib/fog/aws/compute.rb +++ b/lib/fog/aws/compute.rb @@ -140,6 +140,7 @@ module Fog request :release_address request :replace_network_acl_association request :replace_network_acl_entry + request :replace_route request :register_image request :request_spot_instances request :reset_network_interface_attribute diff --git a/lib/fog/aws/requests/compute/replace_route.rb b/lib/fog/aws/requests/compute/replace_route.rb new file mode 100755 index 000000000..d65f8c4d8 --- /dev/null +++ b/lib/fog/aws/requests/compute/replace_route.rb @@ -0,0 +1,89 @@ +module Fog + module Compute + class AWS + class Real + + require 'fog/aws/parsers/compute/basic' + + # Replaces a route in a route table within a VPC. + # + # ==== Parameters + # * RouteTableId<~String> - The ID of the route table for the route. + # * DestinationCidrBlock<~String> - The CIDR address block used for the destination match. Routing decisions are based on the most specific match. + # * GatewayId<~String> - The ID of an Internet gateway attached to your VPC. + # * InstanceId<~String> - The ID of a NAT instance in your VPC. The operation fails if you specify an instance ID unless exactly one network interface is attached. + # * NetworkInterfaceId<~String> - The ID of a network interface. + # + # === Returns + # * response<~Excon::Response>: + # * body<~Hash>: + # * 'requestId'<~String> - Id of the request + # * 'return'<~Boolean> - Returns true if the request succeeds. Otherwise, returns an error. + # + # {Amazon API Reference}[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-ReplaceRoute.html] + def replace_route(route_table_id, destination_cidr_block, internet_gateway_id=nil, instance_id=nil, network_interface_id=nil) + request_vars = { + 'Action' => 'ReplaceRoute', + 'RouteTableId' => route_table_id, + 'DestinationCidrBlock' => destination_cidr_block, + :parser => Fog::Parsers::Compute::AWS::Basic.new + } + if internet_gateway_id + request_vars['GatewayId'] = internet_gateway_id + elsif instance_id + request_vars['InstanceId'] = instance_id + elsif network_interface_id + request_vars['NetworkInterfaceId'] = network_interface_id + end + request(request_vars) + end + end + + class Mock + + def replace_route(route_table_id, destination_cidr_block, internet_gateway_id=nil, instance_id=nil, network_interface_id=nil) + instance_owner_id = nil + route_table = self.data[:route_tables].find { |routetable| routetable["routeTableId"].eql? route_table_id } + if !route_table.nil? && destination_cidr_block + if !internet_gateway_id.nil? || !instance_id.nil? || !network_interface_id.nil? + if !internet_gateway_id.nil? && self.internet_gateways.all('internet-gateway-id'=>internet_gateway_id).first.nil? + raise Fog::Compute::AWS::NotFound.new("The gateway ID '#{internet_gateway_id}' does not exist") + elsif !instance_id.nil? && self.servers.all('instance-id'=>instance_id).first.nil? + raise Fog::Compute::AWS::NotFound.new("The instance ID '#{instance_id}' does not exist") + elsif !network_interface_id.nil? && self.network_interfaces.all('networkInterfaceId'=>network_interface_id).first.nil? + raise Fog::Compute::AWS::NotFound.new("The networkInterface ID '#{network_interface_id}' does not exist") + elsif route_table['routeSet'].find { |route| route['destinationCidrBlock'].eql? destination_cidr_block }.nil? + raise Fog::Compute::AWS::Error, "RouteAlreadyExists => The route identified by #{destination_cidr_block} doesn't exist." + else + response = Excon::Response.new + route_table['routeSet'].push({ + "destinationCidrBlock" => destination_cidr_block, + "gatewayId" => internet_gateway_id, + "instanceId"=>instance_id, + "instanceOwnerId"=>instance_owner_id, + "networkInterfaceId"=>network_interface_id, + "state" => "pending", + "origin" => "ReplaceRoute" + }) + response.status = 200 + response.body = { + 'requestId'=> Fog::AWS::Mock.request_id, + 'return' => true + } + response + end + else + message = 'MissingParameter => ' + message << 'The request must contain either a gateway id, a network interface id, or an instance id' + raise Fog::Compute::AWS::Error.new(message) + end + elsif route_table.nil? + raise Fog::Compute::AWS::NotFound.new("The routeTable ID '#{route_table_id}' does not exist") + elsif destination_cidr_block.empty? + raise Fog::Compute::AWS::InvalidParameterValue.new("Value () for parameter destinationCidrBlock is invalid. This is not a valid CIDR block.") + end + end + end + end + end +end diff --git a/tests/aws/requests/compute/route_tests.rb b/tests/aws/requests/compute/route_tests.rb index 5927ad9e9..37fb8cd7d 100644 --- a/tests/aws/requests/compute/route_tests.rb +++ b/tests/aws/requests/compute/route_tests.rb @@ -2,7 +2,7 @@ Shindo.tests('Fog::Compute[:aws] | route table requests', ['aws']) do @route_table_format = { 'routeTable' => [{ - 'routeSet' => [{ + 'routeSet' => [{ 'destinationCidrBlock' => String, 'gatewayId' => String, 'state' => String, @@ -46,6 +46,7 @@ Shindo.tests('Fog::Compute[:aws] | route table requests', ['aws']) do @subnet_id = Fog::Compute[:aws].create_subnet(vpc.id, '10.0.10.0/24').body['subnet']['subnetId'] @network_interface = Fog::Compute[:aws].create_network_interface(@subnet_id, {"PrivateIpAddress" => "10.0.10.23"}).body @internet_gateway_id = Fog::Compute[:aws].create_internet_gateway.body['internetGatewaySet'].first['internetGatewayId'] + @alt_internet_gateway_id = Fog::Compute[:aws].create_internet_gateway.body['internetGatewaySet'].first['internetGatewayId'] @network_interface_id = @network_interface['networkInterface']['networkInterfaceId'] key_name = 'fog-test-key' key = Fog::Compute[:aws].key_pairs.create(:name => key_name) @@ -91,6 +92,26 @@ Shindo.tests('Fog::Compute[:aws] | route table requests', ['aws']) do Fog::Compute[:aws].create_route(@route_table_id, '10.0.10.0/21', nil, nil, @network_interface_id).body end + # Tests replace_route + # - using internet gateway + # - using instance id + # - using network interface + # + Fog::Compute[:aws].attach_internet_gateway(@alt_internet_gateway_id, vpc.id).body + tests("#replace_route('#{@route_table_id}', '#{@destination_cidr_block}', '#{@alt_internet_gateway_id}', 'nil')").formats(AWS::Compute::Formats::BASIC) do + Fog::Compute[:aws].replace_route(@route_table_id, @destination_cidr_block, @alt_internet_gateway_id, nil).body + end + + instance = Fog::Compute[:aws].servers.create(:image_id => @ami, :flavor_id => 't1.micro', :key_name => 'fog-test-key', :subnet_id => @subnet_id) + instance.wait_for { state.eql? "running" } + tests("#replace_route('#{@route_table_id}', '10.0.10.0/22', 'nil', '#{instance.id}')").formats(AWS::Compute::Formats::BASIC) do + Fog::Compute[:aws].replace_route(@route_table_id, '10.0.10.0/22', nil, instance.id).body + end + + tests("#replace_route('#{@route_table_id}', '10.0.10.0/21', 'nil', 'nil', '#{@network_interface_id}')").formats(AWS::Compute::Formats::BASIC) do + Fog::Compute[:aws].replace_route(@route_table_id, '10.0.10.0/21', nil, nil, @network_interface_id).body + end + # Tests describe_route_tables # - no parameters # - filter: vpc-id => vpc_id @@ -212,6 +233,17 @@ Shindo.tests('Fog::Compute[:aws] | route table requests', ['aws']) do end end + # Tests replace_route + # - no parameters + # - passing a nonexisiting route table + # + tests('#replace_route').raises(ArgumentError) do + Fog::Compute[:aws].replace_route + end + tests("#replace_route('rtb-00000000', '#{@destination_cidr_block}')").raises(Fog::Compute::AWS::NotFound) do + Fog::Compute[:aws].replace_route('rtb-00000000', @destination_cidr_block) + end + # Test describe_route_tables # - passing a nonexisiting vpc # @@ -267,7 +299,7 @@ Shindo.tests('Fog::Compute[:aws] | route table requests', ['aws']) do Fog::Compute[:aws].disassociate_route_table(@association_id) Fog::Compute[:aws].delete_route_table(@route_table_id) end - + Fog::Compute[:aws].delete_network_interface(@network_interface_id) Fog::Compute[:aws].detach_internet_gateway(@internet_gateway_id, vpc.id) Fog::Compute[:aws].delete_internet_gateway(@internet_gateway_id)