diff --git a/doc/_resource_types/route_table.md b/doc/_resource_types/route_table.md index 5530ab73f..9887e417e 100644 --- a/doc/_resource_types/route_table.md +++ b/doc/_resource_types/route_table.md @@ -3,7 +3,8 @@ ```ruby describe route_table('my-route-table') do it { should have_route('10.0.0.0/16').target(gateway: 'local') } - it { should have_route('0.0.0.0/0').target(gateway: 'my-igw') } - it { should have_route('192.168.1.0/24').target(instance: 'my-instance') } + it { should have_route('0.0.0.0/0').target(gateway: 'igw-1ab2345c') } + it { should have_route('192.168.1.0/24').target(instance: 'my-ec2') } + it { should have_route('192.168.2.0/24').target(vpc_peering_connection: 'my-pcx') } end ``` diff --git a/doc/resource_types.md b/doc/resource_types.md index 050a330d6..66bc8704d 100644 --- a/doc/resource_types.md +++ b/doc/resource_types.md @@ -222,8 +222,9 @@ RouteTable resource type. ```ruby describe route_table('my-route-table') do it { should have_route('10.0.0.0/16').target(gateway: 'local') } - it { should have_route('0.0.0.0/0').target(gateway: 'my-igw') } - it { should have_route('192.168.1.0/24').target(instance: 'my-instance') } + it { should have_route('0.0.0.0/0').target(gateway: 'igw-1ab2345c') } + it { should have_route('192.168.1.0/24').target(instance: 'my-ec2') } + it { should have_route('192.168.2.0/24').target(vpc_peering_connection: 'my-pcx') } end ``` diff --git a/lib/awspec/generator/spec/route_table.rb b/lib/awspec/generator/spec/route_table.rb index 1c3dc6c11..a6b403e41 100644 --- a/lib/awspec/generator/spec/route_table.rb +++ b/lib/awspec/generator/spec/route_table.rb @@ -28,6 +28,10 @@ def generate_route_linespecs(route_table) instance = find_ec2(route.instance_id) linespecs.push(ERB.new(route_table_spec_instance_linetemplate, nil, '-').result(binding)) if instance end + if route.vpc_peering_connection_id + connection = find_vpc_peering_connection(route.vpc_peering_connection_id) + linespecs.push(ERB.new(route_table_spec_connection_linetemplate, nil, '-').result(binding)) if connection + end end linespecs end @@ -59,6 +63,19 @@ def route_table_spec_instance_linetemplate template end + # rubocop:disable Metrics/LineLength + def route_table_spec_connection_linetemplate + template = <<-'EOF' +<%- if connection.tag_name -%> +it { should have_route('<%= route.destination_cidr_block %>').target(vpc_peering_connection: '<%= connection.tag_name %>') } +<%- else -%> +it { should have_route('<%= route.destination_cidr_block %>').target(vpc_peering_connection: '<%= route.vpc_peering_connection_id %>') } +<%- end -%> +EOF + template + end + # rubocop:enable Metrics/LineLength + def route_table_spec_subnet_linetemplate template = <<-'EOF' <%- if subnet.tag_name -%> diff --git a/lib/awspec/helper/finder/vpc.rb b/lib/awspec/helper/finder/vpc.rb index 58e1a61cf..7fee77e0f 100644 --- a/lib/awspec/helper/finder/vpc.rb +++ b/lib/awspec/helper/finder/vpc.rb @@ -65,6 +65,27 @@ def select_subnet_by_vpc_id(vpc_id) }) res[:subnets] end + + def find_vpc_peering_connection(vpc_peering_connection_id) + res = @ec2_client.describe_vpc_peering_connections({ + filters: [ + { + name: 'vpc-peering-connection-id', + values: [vpc_peering_connection_id] + } + ] + }) + return res[:vpc_peering_connections].first if res[:vpc_peering_connections].count == 1 + res = @ec2_client.describe_vpc_peering_connections({ + filters: [ + { + name: 'tag:Name', + values: [vpc_peering_connection_id] + } + ] + }) + return res[:vpc_peering_connections].first if res[:vpc_peering_connections].count == 1 + end end end end diff --git a/lib/awspec/matcher/have_route.rb b/lib/awspec/matcher/have_route.rb index f19efd6bb..5f521dd2d 100644 --- a/lib/awspec/matcher/have_route.rb +++ b/lib/awspec/matcher/have_route.rb @@ -7,12 +7,13 @@ else @destination = destination end - route_table.has_route?(@destination, @gateway_id, @instance_id) + route_table.has_route?(@destination, @gateway_id, @instance_id, @vpc_peering_connection_id) end chain :target do |target| @gateway_id = target[:gateway] - @intance_id = target[:instance] + @instance_id = target[:instance] + @vpc_peering_connection_id = target[:vpc_peering_connection] end chain :destination do |dest| diff --git a/lib/awspec/stub/route_table.rb b/lib/awspec/stub/route_table.rb index 75fac0b68..2224d35b5 100644 --- a/lib/awspec/stub/route_table.rb +++ b/lib/awspec/stub/route_table.rb @@ -90,6 +90,16 @@ network_interface_id: nil, vpc_peering_connection_id: nil, state: 'active' + }, + { + destination_cidr_block: '192.168.2.0/24', + destination_prefix_list_id: nil, + gateway_id: nil, + instance_id: nil, + instance_owner_id: nil, + network_interface_id: nil, + vpc_peering_connection_id: 'pcx-c56789de', + state: 'active' } ], associations: [ @@ -144,6 +154,19 @@ ] } ] + }, + describe_vpc_peering_connections: { + vpc_peering_connections: [ + { + vpc_peering_connection_id: 'pcx-c56789de', + tags: [ + { + key: 'Name', + value: 'my-pcx' + } + ] + } + ] } } } diff --git a/lib/awspec/type/route_table.rb b/lib/awspec/type/route_table.rb index 1c53968dc..8ba10ee53 100644 --- a/lib/awspec/type/route_table.rb +++ b/lib/awspec/type/route_table.rb @@ -6,26 +6,14 @@ def initialize(id) @id = @resource[:route_table_id] if @resource end - def has_route?(destination, gateway_id = nil, instance_id = nil) + def has_route?(destination, gateway_id = nil, instance_id = nil, vpc_peering_connection_id = nil) @resource.routes.find do |route| if destination next false unless route.destination_cidr_block == destination end - # * gateway - next true if route.gateway_id == gateway_id - # internet gateway - igw = find_internet_gateway(gateway_id) - next true if igw && igw.tag_name == gateway_id - # vpn gateway - vgw = find_vpn_gateway(gateway_id) - next true if vgw && vgw.tag_name == gateway_id - # customer gateway - cgw = find_customer_gateway(gateway_id) - next true if cgw && cgw.tag_name == gateway_id - # instance - next true if route.instance_id == instance_id - instance = find_ec2(instance_id) - next true if instance && instance.tag_name == instance_id + next target_gateway?(route, gateway_id) if gateway_id + next target_instance?(route, instance_id) if instance_id + next target_vpc_peering_connection?(route, vpc_peering_connection_id) if vpc_peering_connection_id end end @@ -36,5 +24,38 @@ def has_subnet?(subnet_id) a[:subnet_id] == subnet[:subnet_id] end end + + private + + def target_gateway?(route, gateway_id) + # * gateway + return true if route.gateway_id == gateway_id + # internet gateway + igw = find_internet_gateway(gateway_id) + return true if igw && igw.tag_name == gateway_id + # vpn gateway + vgw = find_vpn_gateway(gateway_id) + return true if vgw && vgw.tag_name == gateway_id + # customer gateway + cgw = find_customer_gateway(gateway_id) + return true if cgw && cgw.tag_name == gateway_id + false + end + + def target_instance?(route, instance_id) + # instance + return true if route.instance_id == instance_id + instance = find_ec2(instance_id) + return true if instance && instance.tag_name == instance_id + false + end + + def target_vpc_peering_connection?(route, vpc_peering_connection_id) + # vpc_peering_connection_id + return true if route.vpc_peering_connection_id == vpc_peering_connection_id + connection = find_vpc_peering_connection(vpc_peering_connection_id) + return true if connection && connection.tag_name == vpc_peering_connection_id + false + end end end diff --git a/spec/generator/spec/route_table_spec.rb b/spec/generator/spec/route_table_spec.rb index 950b8f247..78ebc95f4 100644 --- a/spec/generator/spec/route_table_spec.rb +++ b/spec/generator/spec/route_table_spec.rb @@ -13,6 +13,7 @@ it { should have_route('10.0.0.0/16').target(gateway: 'local') } it { should have_route('0.0.0.0/0').target(gateway: 'igw-1ab2345c') } it { should have_route('192.168.1.0/24').target(instance: 'my-ec2') } + it { should have_route('192.168.2.0/24').target(vpc_peering_connection: 'my-pcx') } it { should have_subnet('my-subnet') } end EOF diff --git a/spec/type/route_table_spec.rb b/spec/type/route_table_spec.rb index 31e74a6fd..d98da0b88 100644 --- a/spec/type/route_table_spec.rb +++ b/spec/type/route_table_spec.rb @@ -8,6 +8,7 @@ it { should have_route('10.0.0.0/16').target(gateway: 'local') } it { should have_route('0.0.0.0/0').target(gateway: 'my-igw') } it { should have_route('192.168.1.0/24').target(instance: 'my-ec2') } + it { should have_route('192.168.2.0/24').target(vpc_peering_connection: 'my-pcx') } it { should have_subnet('my-subnet') } end