ec2-security-czar 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.octopolo.yml +4 -0
- data/.ruby-gemset +2 -0
- data/.ruby-version +2 -0
- data/.soyuz.yml +13 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.markdown +1 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/ec2-security-czar +35 -0
- data/ec2-security-czar.gemspec +33 -0
- data/lib/ec2-security-czar/base.rb +52 -0
- data/lib/ec2-security-czar/rule.rb +87 -0
- data/lib/ec2-security-czar/security_group.rb +209 -0
- data/lib/ec2-security-czar/version.rb +3 -0
- data/lib/ec2_security_czar.rb +4 -0
- data/spec/lib/ec2-security-czar/base_spec.rb +94 -0
- data/spec/lib/ec2-security-czar/rule_spec.rb +183 -0
- data/spec/lib/ec2-security-czar/security_group_spec.rb +240 -0
- data/spec/spec_helper.rb +32 -0
- metadata +226 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
require 'ec2-security-czar/base'
|
3
|
+
|
4
|
+
module Ec2SecurityCzar
|
5
|
+
describe Base do
|
6
|
+
let(:access_key){ 'aws-key' }
|
7
|
+
let(:secret_access_key){ 'aws-secret-key' }
|
8
|
+
let(:region) { 'us-east-1' }
|
9
|
+
let(:aws_conf) { { access_key: access_key, secret_key: secret_access_key } }
|
10
|
+
let(:ec2) { double }
|
11
|
+
let(:environment) {double}
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow(File).to receive(:exists?).with('config/aws_keys.yml').and_return(true)
|
15
|
+
allow(YAML).to receive(:load_file).and_return(aws_conf)
|
16
|
+
stub_const("AWS", double("AWS const"))
|
17
|
+
stub_const("SecurityGroup", double("Security Group"))
|
18
|
+
allow(AWS).to receive(:ec2).and_return(ec2)
|
19
|
+
allow(AWS).to receive(:config)
|
20
|
+
allow(SecurityGroup).to receive(:update_security_groups) {[]}
|
21
|
+
end
|
22
|
+
|
23
|
+
context ".new" do
|
24
|
+
subject { Base }
|
25
|
+
|
26
|
+
context "without mfa" do
|
27
|
+
it "configures the AWS sdk" do
|
28
|
+
expect(AWS).to receive(:config).with(
|
29
|
+
hash_including(access_key_id: access_key, secret_access_key: secret_access_key, region: region)
|
30
|
+
)
|
31
|
+
allow(YAML).to receive(:load_file).with('config/aws_keys.yml').and_return(aws_conf)
|
32
|
+
subject.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with mfa" do
|
37
|
+
let(:mfa_token) { '12345' }
|
38
|
+
let(:mfa_serial_number) { 'aws-mfa-serial' }
|
39
|
+
let(:aws_conf) { { access_key: access_key, secret_key: secret_access_key, mfa_serial_number: mfa_serial_number } }
|
40
|
+
|
41
|
+
it "configures the AWS sdk" do
|
42
|
+
allow_any_instance_of(Base).to receive(:mfa_auth)
|
43
|
+
expect(AWS).to receive(:config).with(
|
44
|
+
hash_including(access_key_id: access_key, secret_access_key: secret_access_key, region: region)
|
45
|
+
)
|
46
|
+
subject.new
|
47
|
+
end
|
48
|
+
it "runs mfa auth" do
|
49
|
+
expect_any_instance_of(Base).to receive(:mfa_auth).with(mfa_token)
|
50
|
+
subject.new(nil, token: mfa_token)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "#load_config" do
|
56
|
+
subject { Base }
|
57
|
+
context "no environment is set" do
|
58
|
+
it "loads the config for the default environment" do
|
59
|
+
expect(aws_conf).to_not receive(:[]).with(nil)
|
60
|
+
subject.new
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context "environment is set" do
|
64
|
+
let(:environment) { 'environment' }
|
65
|
+
let(:environment_conf) { { environment => aws_conf } }
|
66
|
+
|
67
|
+
before do
|
68
|
+
allow(YAML).to receive(:load_file).with("config/aws_keys.yml").and_return(environment_conf)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "loads the config for the passed environment" do
|
72
|
+
expect(AwsConfig).to receive(:[]).with(environment_conf).and_return(environment_conf)
|
73
|
+
expect(environment_conf).to receive(:[]).with(environment).and_return(aws_conf)
|
74
|
+
subject.new(environment)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "#update_security_groups" do
|
80
|
+
let(:environment) { 'environment' }
|
81
|
+
let(:environment_conf) { { environment => aws_conf } }
|
82
|
+
|
83
|
+
before do
|
84
|
+
subject.instance_variable_set("@environment", environment)
|
85
|
+
allow(YAML).to receive(:load_file).with("config/aws_keys.yml").and_return(environment_conf)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "delegates to the SecurityGroup class" do
|
89
|
+
expect(SecurityGroup).to receive(:update_security_groups).with(ec2, environment, region)
|
90
|
+
subject.update_security_groups
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
require 'ec2-security-czar/rule'
|
3
|
+
require 'ec2-security-czar/security_group'
|
4
|
+
|
5
|
+
module Ec2SecurityCzar
|
6
|
+
describe Rule do
|
7
|
+
let(:direction) { :outbound }
|
8
|
+
let(:ip_range) { '0.0.0.0/0' }
|
9
|
+
let(:group_id) { 'sec-group' }
|
10
|
+
let(:group) { {group_id: group_id} }
|
11
|
+
let(:protocol) { :tcp }
|
12
|
+
let(:port_range) { '666' }
|
13
|
+
let(:api_object) { double }
|
14
|
+
let(:options) {
|
15
|
+
{
|
16
|
+
direction: direction,
|
17
|
+
ip_range: ip_range,
|
18
|
+
protocol: protocol,
|
19
|
+
group: group,
|
20
|
+
port_range: port_range,
|
21
|
+
api_object: api_object,
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(subject).to receive(:say)
|
27
|
+
allow(subject).to receive(:pretty_print)
|
28
|
+
end
|
29
|
+
|
30
|
+
subject { Rule.new(options) }
|
31
|
+
|
32
|
+
context "#equal?" do
|
33
|
+
it "returns true if all options are equal" do
|
34
|
+
expect(subject.equal?(subject.dup)).to be_truthy
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns false if all options are not equal" do
|
38
|
+
bogus_rule = Rule.new(options.merge(ip_range: '1.1.1.1/32'))
|
39
|
+
expect(subject.equal?(bogus_rule)).to be_falsey
|
40
|
+
end
|
41
|
+
|
42
|
+
context "rule with group name to a group id" do
|
43
|
+
let(:group_name) { 'sec-group-name' }
|
44
|
+
|
45
|
+
it "returns true if the group ids are the same" do
|
46
|
+
allow(SecurityGroup).to receive(:lookup).with(group_name).and_return(group_id)
|
47
|
+
allow(group_id).to receive(:id).and_return(group_id)
|
48
|
+
equivalent_rule = Rule.new(options.merge(group: { group_name: group_name }))
|
49
|
+
expect(subject.equal?(equivalent_rule)).to be_truthy
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "#authorize!" do
|
55
|
+
let(:security_group_api) { double("Security Group API") }
|
56
|
+
context "outbound rule" do
|
57
|
+
let(:direction) { :outbound }
|
58
|
+
it "authorizes an egress rule for aws" do
|
59
|
+
expect(security_group_api).to receive(:authorize_egress).with(ip_range, hash_including(protocol: protocol, ports: port_range))
|
60
|
+
subject.authorize!(security_group_api)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "does not authorize an ingress rule for aws" do
|
64
|
+
allow(security_group_api).to receive(:authorize_egress)
|
65
|
+
expect(security_group_api).to_not receive(:authorize_ingress)
|
66
|
+
subject.authorize!(security_group_api)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "inbound rule" do
|
71
|
+
let(:direction) { :inbound }
|
72
|
+
it "authorizes an ingress rule for aws" do
|
73
|
+
expect(security_group_api).to receive(:authorize_ingress).with(protocol, port_range, ip_range)
|
74
|
+
subject.authorize!(security_group_api)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "does not authorize an egress rule for aws" do
|
78
|
+
allow(security_group_api).to receive(:authorize_ingress)
|
79
|
+
expect(security_group_api).to_not receive(:authorize_egress)
|
80
|
+
subject.authorize!(security_group_api)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "group rule" do
|
85
|
+
let(:direction) { :inbound }
|
86
|
+
let(:group_id) { 'sec-group' }
|
87
|
+
let(:options) {
|
88
|
+
{
|
89
|
+
direction: direction,
|
90
|
+
group: { group_id: group_id },
|
91
|
+
protocol: protocol,
|
92
|
+
port_range: port_range,
|
93
|
+
api_object: api_object,
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
it "passes the group_id as a hash" do
|
98
|
+
expect(security_group_api).to receive(:authorize_ingress).with(
|
99
|
+
protocol, port_range, { group_id: group_id }
|
100
|
+
)
|
101
|
+
subject.authorize!(security_group_api)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "rescues an api error" do
|
106
|
+
allow(security_group_api).to receive(:authorize_egress).and_raise(StandardError)
|
107
|
+
expect(subject).to receive(:say).twice
|
108
|
+
expect { subject.authorize!(security_group_api) }.to_not raise_error
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "#revoke!" do
|
113
|
+
it "calls revoke on it's api object" do
|
114
|
+
expect(api_object).to receive(:revoke)
|
115
|
+
subject.revoke!
|
116
|
+
end
|
117
|
+
|
118
|
+
it "rescues an api error" do
|
119
|
+
allow(api_object).to receive(:revoke).and_raise(StandardError)
|
120
|
+
expect(subject).to receive(:say).twice
|
121
|
+
expect { subject.revoke! }.to_not raise_error
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "#group_id" do
|
126
|
+
context "given a string" do
|
127
|
+
let(:group) { "sec-group" }
|
128
|
+
it "returns the passed in string as the security group id" do
|
129
|
+
expect(subject.group_id(group)).to equal(group)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "given a hash with group_id" do
|
134
|
+
let(:group) { { group_id: "sec-group" } }
|
135
|
+
it "returns the group id" do
|
136
|
+
expect(subject.group_id(group)).to equal(group[:group_id])
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "given a hash with group_name" do
|
141
|
+
let(:group_name) { 'sec-group' }
|
142
|
+
let(:group) { {group_id: group_id, group_name: group_name} }
|
143
|
+
|
144
|
+
it "returns the matching group id" do
|
145
|
+
allow(SecurityGroup).to receive(:lookup).with(group[:group_name]).and_return(group_id)
|
146
|
+
expect(subject.group_id(group)).to equal(group_id)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context ".rules_from_api" do
|
152
|
+
subject { Rule }
|
153
|
+
let(:rules) { [double(port_range: 123, protocol: :tcp, ip_ranges: ['0.0.0.0/0'], groups: [double(id: 'sec-group')])] }
|
154
|
+
let(:direction) { :outbound }
|
155
|
+
|
156
|
+
it "returns an array of rules" do
|
157
|
+
expect(subject.rules_from_api(rules, direction)).to be_an_array_of(Rule)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context ".rules_from_api" do
|
162
|
+
subject { Rule }
|
163
|
+
let(:api_rule) { double(port_range: 123, protocol: :tcp, ip_ranges: ['0.0.0.0/0'], groups: [double(id: 'sec-group')]) }
|
164
|
+
let(:rules) { [api_rule] }
|
165
|
+
let(:direction) { :outbound }
|
166
|
+
|
167
|
+
it "returns an array of rules" do
|
168
|
+
expect(subject.rules_from_api(rules, direction)).to be_an_array_of(Rule)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context ".rules_from_config" do
|
173
|
+
subject { Rule }
|
174
|
+
let(:config_rule) { { port_range: 123, protocol: :tcp, ip_ranges: ['0.0.0.0/0'], groups: [double(id: 'sec-group')] } }
|
175
|
+
let(:direction) { :outbound }
|
176
|
+
let(:rules) { {outbound: [config_rule]} }
|
177
|
+
|
178
|
+
it "returns an array of rules" do
|
179
|
+
expect(subject.rules_from_config(rules, direction)).to be_an_array_of(Rule)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
require 'ec2-security-czar/security_group'
|
3
|
+
|
4
|
+
module Ec2SecurityCzar
|
5
|
+
describe SecurityGroup do
|
6
|
+
let(:outbound_rule) {
|
7
|
+
{
|
8
|
+
zone: "Test Outbound",
|
9
|
+
justification: "Test outbound justification",
|
10
|
+
groups: [ 'test-outbound-group-id' ],
|
11
|
+
protocol: :udp,
|
12
|
+
port_range: '666'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
let(:inbound_rule) {
|
16
|
+
{
|
17
|
+
zone: "Test Inbound",
|
18
|
+
justification: "Test inbound justification",
|
19
|
+
groups: [ 'test-inbound-group-id' ],
|
20
|
+
protocol: :tcp,
|
21
|
+
port_range: '999'
|
22
|
+
}
|
23
|
+
}
|
24
|
+
let(:api) { double("API", name: 'test') }
|
25
|
+
let(:config) { { outbound: [outbound_rule], inbound: [inbound_rule] } }
|
26
|
+
let(:filename) { 'the/config/file' }
|
27
|
+
let(:file) { "Raw File" }
|
28
|
+
let(:parsed_file) { { derp: :herp } }
|
29
|
+
let(:environment) { 'environment' }
|
30
|
+
let(:region) { 'us-east-1'}
|
31
|
+
let(:ec2) { double }
|
32
|
+
|
33
|
+
|
34
|
+
before do
|
35
|
+
allow(SecurityGroup).to receive(:ec2) {ec2}
|
36
|
+
allow(SecurityGroup).to receive(:region) {region}
|
37
|
+
allow(SecurityGroup).to receive(:environment) {environment}
|
38
|
+
allow(File).to receive(:read).and_return(file)
|
39
|
+
allow_any_instance_of(SecurityGroup).to receive(:config_filename).and_return(filename)
|
40
|
+
allow(File).to receive(:exists?).with(filename).and_return(true)
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#update_rules" do
|
44
|
+
let(:delete_inbound) { double("Inbound rule to be deleted") }
|
45
|
+
let(:delete_outbound) { double("Outbound rule to be deleted") }
|
46
|
+
let(:addition_inbound) { double("Inbound rule to be added") }
|
47
|
+
let(:addition_outbound) { double("Outbound rule to be added") }
|
48
|
+
|
49
|
+
before do
|
50
|
+
allow(ERB).to receive(:new).and_return(double(:result => parsed_file))
|
51
|
+
allow(YAML).to receive(:load).and_return(parsed_file)
|
52
|
+
allow(subject).to receive(:new_rules).with(:outbound).and_return([addition_outbound])
|
53
|
+
allow(subject).to receive(:new_rules).with(:inbound).and_return([addition_inbound])
|
54
|
+
allow(subject).to receive(:current_rules).with(:outbound).and_return([delete_outbound])
|
55
|
+
allow(subject).to receive(:current_rules).with(:inbound).and_return([delete_inbound])
|
56
|
+
allow(subject).to receive(:say)
|
57
|
+
allow(SecurityGroup).to receive(:lookup) {api}
|
58
|
+
end
|
59
|
+
|
60
|
+
subject { SecurityGroup.new(api, environment) }
|
61
|
+
|
62
|
+
it "revokes rules that have been deleted" do
|
63
|
+
allow(addition_outbound).to receive(:authorize!)
|
64
|
+
allow(addition_inbound).to receive(:authorize!)
|
65
|
+
expect(delete_inbound).to receive(:revoke!)
|
66
|
+
expect(delete_outbound).to receive(:revoke!)
|
67
|
+
subject.update_rules
|
68
|
+
end
|
69
|
+
|
70
|
+
it "authorizes rules that have been added" do
|
71
|
+
allow(delete_inbound).to receive(:revoke!)
|
72
|
+
allow(delete_outbound).to receive(:revoke!)
|
73
|
+
expect(addition_outbound).to receive(:authorize!).with(api)
|
74
|
+
expect(addition_inbound).to receive(:authorize!).with(api)
|
75
|
+
subject.update_rules
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "#load_rules" do
|
80
|
+
let(:environment) { 'parsed' }
|
81
|
+
let(:erb_file) { "--- \nenvironment: <%= environment %> \n" }
|
82
|
+
|
83
|
+
before do
|
84
|
+
allow(File).to receive(:read).with(filename).and_return(erb_file)
|
85
|
+
end
|
86
|
+
|
87
|
+
subject { SecurityGroup.new(api, environment) }
|
88
|
+
|
89
|
+
it "passes the environment into the erb rendering" do
|
90
|
+
expect(SecurityGroupConfig).to receive(:[]).at_least(:once).with(hash_including('environment' => 'parsed'))
|
91
|
+
subject.send(:load_rules)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
context "#security_group_definition_files" do
|
97
|
+
let(:environment) { 'parsed' }
|
98
|
+
let(:erb_file) { "--- \nenvironment: <%= environment %> \n" }
|
99
|
+
|
100
|
+
before do
|
101
|
+
allow(File).to receive(:read).with(filename).and_return(erb_file)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "returns an array of file names with out the extension" do
|
105
|
+
allow(Dir).to receive(:[]).and_return(["config/aws_keys.yml", "config/foo.yml", "config/bar.yml"])
|
106
|
+
expect(SecurityGroup.send(:security_group_definition_files)).to eq(["config/foo.yml","config/bar.yml"])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "#config_security_groups" do
|
111
|
+
|
112
|
+
let(:file_region_1) {'us-east-1'}
|
113
|
+
let(:file_region_2) {'us-west-2'}
|
114
|
+
let(:erb_file_1) { "--- \nenvironment: <%= environment %> \n region: <%= file_region_1 %>\n" }
|
115
|
+
let(:erb_file_2) { "--- \nenvironment: <%= environment %> \n region: <%= file_region_2 %>\n" }
|
116
|
+
|
117
|
+
before do
|
118
|
+
allow(SecurityGroup).to receive(:get_security_group_region).and_return(file_region_1,file_region_2)
|
119
|
+
allow(File).to receive(:read).with(filename).and_return([erb_file_1, erb_file_2])
|
120
|
+
end
|
121
|
+
|
122
|
+
context "with no region specified" do
|
123
|
+
it "retrusn groups in the default region" do
|
124
|
+
allow(Dir).to receive(:[]).and_return(["config/aws_keys.yml", "config/foo.yml", "config/bar.yml"])
|
125
|
+
expect(SecurityGroup.send(:config_security_groups)).to eq(["foo"])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "with a region specified" do
|
130
|
+
let(:region) { 'us-west-2' }
|
131
|
+
|
132
|
+
it "returns groups in the specified region" do
|
133
|
+
allow(Dir).to receive(:[]).and_return(["config/aws_keys.yml", "config/foo.yml", "config/bar.yml"])
|
134
|
+
expect(SecurityGroup.send(:config_security_groups)).to eq(["bar"])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "#missing_security_groups" do
|
140
|
+
let(:environment) { 'parsed' }
|
141
|
+
let(:erb_file) { "--- \nenvironment: <%= environment %> \n" }
|
142
|
+
let(:security_group_1) { double }
|
143
|
+
let(:security_group_2) { double }
|
144
|
+
|
145
|
+
before do
|
146
|
+
allow(File).to receive(:read).with(filename).and_return(erb_file)
|
147
|
+
allow(SecurityGroup).to receive(:config_security_groups).and_return(["foo","bar"])
|
148
|
+
allow(security_group_1).to receive(:name).and_return("foo")
|
149
|
+
allow(security_group_2).to receive(:name).and_return("bar")
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns empty if config_security_groups is the same as security_groups" do
|
153
|
+
allow(SecurityGroup).to receive(:from_aws).and_return([security_group_1, security_group_2])
|
154
|
+
expect(SecurityGroup.send(:missing_security_groups)).to eq([])
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns groups in config_security_groups not in security_groups" do
|
158
|
+
allow(SecurityGroup).to receive(:from_aws).and_return([security_group_2])
|
159
|
+
expect(SecurityGroup.send(:missing_security_groups)).to eq(["foo"])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context ".lookup" do
|
164
|
+
before do
|
165
|
+
allow(security_group).to receive(:name) {security_group_name}
|
166
|
+
allow(security_group).to receive(:id) {security_group_id}
|
167
|
+
allow(SecurityGroup).to receive(:security_groups).and_return([security_group])
|
168
|
+
SecurityGroup.instance_variable_set(:@security_group_hash, nil)
|
169
|
+
end
|
170
|
+
|
171
|
+
let(:security_group_name) { 'sec-group-name' }
|
172
|
+
let(:security_group_id) { 'sec-group' }
|
173
|
+
let(:security_group) { double }
|
174
|
+
|
175
|
+
it "returns the group corresponding to the group name" do
|
176
|
+
expect(SecurityGroup.lookup(security_group_name)).to eq(security_group)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns the group name corresponding to the group id" do
|
180
|
+
expect(SecurityGroup.lookup(security_group_id)).to eq(security_group)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context ".from_aws" do
|
185
|
+
before do
|
186
|
+
allow(SecurityGroup).to receive(:security_groups) {nil}
|
187
|
+
end
|
188
|
+
it "delegates to the ec2 object" do
|
189
|
+
expect(ec2).to receive(:security_groups)
|
190
|
+
SecurityGroup.from_aws
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context ".create_missing_security_groups" do
|
195
|
+
let(:security_groups) { double }
|
196
|
+
let(:environment) { 'parsed' }
|
197
|
+
let(:security_group_name) {'sec-group-name'}
|
198
|
+
let(:security_group) { double }
|
199
|
+
let(:configs) {{vpc: "vpc", description: "description"}}
|
200
|
+
|
201
|
+
before do
|
202
|
+
allow(ec2).to receive(:security_groups) {security_groups}
|
203
|
+
allow(SecurityGroup).to receive(:missing_security_groups).and_return(['sec-group-name'])
|
204
|
+
allow(SecurityGroup).to receive(:new).with(security_group_name,environment).and_return(security_group)
|
205
|
+
allow(security_group).to receive(:config).and_return(configs)
|
206
|
+
allow(SecurityGroup).to receive(:say)
|
207
|
+
end
|
208
|
+
|
209
|
+
it "create missing security groups" do
|
210
|
+
expect(security_groups).to receive(:create).with('sec-group-name', {vpc: "vpc", description: "description"})
|
211
|
+
SecurityGroup.send(:create_missing_security_groups, environment)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context ".update_rules" do
|
216
|
+
let(:security_group) { double }
|
217
|
+
let(:security_groups) { [security_group] }
|
218
|
+
|
219
|
+
before do
|
220
|
+
SecurityGroup.instance_variable_set(:@environment, "environment")
|
221
|
+
allow(SecurityGroup).to receive(:security_groups) {security_groups}
|
222
|
+
allow(SecurityGroup).to receive(:new).with('sec-group-name','environment').and_return(security_group)
|
223
|
+
allow(security_group).to receive(:name) {'sec-group-name'}
|
224
|
+
end
|
225
|
+
|
226
|
+
it "calls #update_rules" do
|
227
|
+
expect(security_group).to receive(:update_rules)
|
228
|
+
SecurityGroup.send(:update_rules)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context ".update_security_groups" do
|
233
|
+
it "calls everything it's supposed to" do
|
234
|
+
expect(SecurityGroup).to receive(:create_missing_security_groups)
|
235
|
+
expect(SecurityGroup).to receive(:update_rules)
|
236
|
+
SecurityGroup.send(:update_security_groups, ec2, environment, region)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|