ec2-security-czar 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|