Skip to content

Commit

Permalink
Add opened_only matcher for security groups.
Browse files Browse the repository at this point in the history
This matcher allows the user to make exclusivity statements about certain rules.
Prior, a user could only make statements about the existence of opened rules for
security groups, now they can state that not only is there an opened rule but
that that is the _only_ open rule for a given port, protocol, cidr.
  • Loading branch information
ceaess committed Feb 17, 2016
1 parent 9f5e4a0 commit a576ff0
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 13 deletions.
6 changes: 6 additions & 0 deletions doc/resource_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,12 @@ end
```


### be_inbound_opened_only

### be_opened_only

### be_outbound_opened_only

### its(:inbound), its(:outbound)

```ruby
Expand Down
1 change: 1 addition & 0 deletions lib/awspec/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

# SecurityGroup
require 'awspec/matcher/be_opened'
require 'awspec/matcher/be_opened_only'

# Route53
require 'awspec/matcher/have_record_set'
Expand Down
17 changes: 17 additions & 0 deletions lib/awspec/matcher/be_opened_only.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
RSpec::Matchers.define :be_opened_only do |port|
match do |sg|
sg.opened_only?(port, @protocol, @cidr)
end

chain :protocol do |protocol|
@protocol = protocol
end

chain :for do |cidr|
@cidr = cidr
end

chain :target do |cidr|
@cidr = cidr
end
end
30 changes: 26 additions & 4 deletions lib/awspec/stub/security_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,28 @@
}
]
},
{
from_port: 60_000,
to_port: 60_000,
ip_protocol: 'tcp',
ip_ranges: [
{
cidr_ip: '100.456.789.012/32'
}
],
user_id_group_pairs: []
},
{
from_port: 70_000,
to_port: 70_000,
ip_protocol: 'tcp',
ip_ranges: [
{
cidr_ip: '100.456.789.012/32'
}
],
user_id_group_pairs: []
},
{
from_port: 50_000,
to_port: 50_009,
Expand All @@ -47,12 +69,12 @@
],
ip_permissions_egress: [
{
from_port: nil,
to_port: nil,
ip_protocol: '-1',
from_port: 50_000,
to_port: 50_000,
ip_protocol: 'tcp',
ip_ranges: [
{
cidr_ip: '0.0.0.0/0'
cidr_ip: '100.456.789.012/32'
}
]
}
Expand Down
29 changes: 29 additions & 0 deletions lib/awspec/type/security_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ def opened?(port = nil, protocol = nil, cidr = nil)
outbound_opened?(port, protocol, cidr)
end

def opened_only?(port = nil, protocol = nil, cidr = nil)
return inbound_opened_only?(port, protocol, cidr) if @inbound
outbound_opened_only?(port, protocol, cidr)
end

def inbound_opened?(port = nil, protocol = nil, cidr = nil)
@resource_via_client[:ip_permissions].find do |permission|
next true unless port
Expand All @@ -38,6 +43,18 @@ def inbound_opened?(port = nil, protocol = nil, cidr = nil)
end
end

def inbound_opened_only?(port = nil, protocol = nil, cidr = nil)
permissions = @resource_via_client[:ip_permissions].select do |permission|
port_between?(port, permission[:from_port], permission[:to_port])
end
permissions = permissions.select { |permission| permission[:ip_protocol] == protocol }
cidrs = []
permissions.each do |permission|
permission[:ip_ranges].select { |ip_range| cidrs.push(ip_range[:cidr_ip]) }
end
cidrs == [cidr]
end

def outbound_opened?(port = nil, protocol = nil, cidr = nil)
@resource_via_client[:ip_permissions_egress].find do |permission|
next true unless port
Expand All @@ -62,6 +79,18 @@ def outbound_opened?(port = nil, protocol = nil, cidr = nil)
end
end

def outbound_opened_only?(port = nil, protocol = nil, cidr = nil)
permissions = @resource_via_client[:ip_permissions_egress].select do |permission|
port_between?(port, permission[:from_port], permission[:to_port])
end
permissions = permissions.select { |permission| permission[:ip_protocol] == protocol }
cidrs = []
permissions.each do |permission|
permission[:ip_ranges].select { |ip_range| cidrs.push(ip_range[:cidr_ip]) }
end
cidrs == [cidr]
end

def inbound
@inbound = true
self
Expand Down
8 changes: 5 additions & 3 deletions spec/generator/spec/security_group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
its(:inbound) { should be_opened(80).protocol('tcp').for('123.456.789.012/32') }
its(:inbound) { should be_opened(80).protocol('tcp').for('456.789.123.456/32') }
its(:inbound) { should be_opened(22).protocol('tcp').for('group-name-sg') }
its(:inbound) { should be_opened(60000).protocol('tcp').for('100.456.789.012/32') }
its(:inbound) { should be_opened(70000).protocol('tcp').for('100.456.789.012/32') }
its(:inbound) { should be_opened('50000-50009').protocol('tcp').for('123.456.789.012/32') }
its(:outbound) { should be_opened }
its(:inbound_rule_count) { should eq 4 }
its(:outbound) { should be_opened(50000).protocol('tcp').for('100.456.789.012/32') }
its(:inbound_rule_count) { should eq 6 }
its(:outbound_rule_count) { should eq 1 }
its(:inbound_permissions_count) { should eq 3 }
its(:inbound_permissions_count) { should eq 5 }
its(:outbound_permissions_count) { should eq 1 }
it { should belong_to_vpc('my-vpc') }
end
Expand Down
15 changes: 9 additions & 6 deletions spec/type/security_group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
its(:inbound) { should be_opened(22).protocol('tcp').for('sg-5a6b7cd8') }
its(:inbound) { should be_opened('50000-50009').protocol('tcp').for('123.456.789.012/32') }
its(:inbound) { should_not be_opened('50010-50019').protocol('tcp').for('123.456.789.012/32') }
its(:outbound) { should be_opened }
its(:inbound_permissions_count) { should eq 3 }
its(:ip_permissions_count) { should eq 3 }
its(:outbound) { should be_opened(50_000) }
its(:inbound) { should be_opened_only(60_000).protocol('tcp').for('100.456.789.012/32') }
its(:inbound) { should be_opened_only(70_000).protocol('tcp').for('100.456.789.012/32') }
its(:outbound) { should be_opened_only(50_000).protocol('tcp').for('100.456.789.012/32') }
its(:inbound_permissions_count) { should eq 5 }
its(:ip_permissions_count) { should eq 5 }
its(:outbound_permissions_count) { should eq 1 }
its(:ip_permissions_egress_count) { should eq 1 }
its(:inbound_rule_count) { should eq 4 }
its(:inbound_rule_count) { should eq 6 }
its(:outbound_rule_count) { should eq 1 }
# its(:inbound) { should be_opened(22).protocol('tcp').for('group-name-sg') }
# its(:inbound) { should be_opened(22).protocol('tcp').for('my-db-sg') }
Expand All @@ -29,13 +32,13 @@

describe security_group('my-security-group-name') do
it { should exist }
its(:outbound) { should be_opened }
its(:outbound) { should be_opened(50_000) }
its(:inbound) { should be_opened(80) }
it { should belong_to_vpc('my-vpc') }
end

describe security_group('my-security-tag-name') do
its(:outbound) { should be_opened }
its(:outbound) { should be_opened(50_000) }
its(:inbound) { should be_opened(80) }
it { should belong_to_vpc('my-vpc') }
end

0 comments on commit a576ff0

Please sign in to comment.