vominator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +116 -0
  7. data/Rakefile +12 -0
  8. data/bin/vominate +12 -0
  9. data/circle.yml +5 -0
  10. data/lib/ec2.rb +12 -0
  11. data/lib/ec2/instances.rb +362 -0
  12. data/lib/ec2/security_groups.rb +314 -0
  13. data/lib/ec2/ssm.rb +81 -0
  14. data/lib/vominator/aws.rb +15 -0
  15. data/lib/vominator/constants.rb +53 -0
  16. data/lib/vominator/ec2.rb +308 -0
  17. data/lib/vominator/instances.rb +34 -0
  18. data/lib/vominator/route53.rb +125 -0
  19. data/lib/vominator/security_groups.rb +26 -0
  20. data/lib/vominator/ssm.rb +57 -0
  21. data/lib/vominator/version.rb +3 -0
  22. data/lib/vominator/vominator.rb +74 -0
  23. data/lib/vominator/vpc.rb +82 -0
  24. data/lib/vpc.rb +8 -0
  25. data/lib/vpc/create.rb +188 -0
  26. data/spec/lib/instances_spec.rb +2 -0
  27. data/spec/lib/vominator/aws_spec.rb +6 -0
  28. data/spec/lib/vominator/ec2_spec.rb +783 -0
  29. data/spec/lib/vominator/instances_spec.rb +96 -0
  30. data/spec/lib/vominator/route53_spec.rb +64 -0
  31. data/spec/lib/vominator/ssm_spec.rb +95 -0
  32. data/spec/lib/vominator/vominator_spec.rb +209 -0
  33. data/spec/spec_helper.rb +103 -0
  34. data/spec/support/matchers/exit_with_code.rb +24 -0
  35. data/test/puke/cloud-configs/.gitkeep +0 -0
  36. data/test/puke/cloud-configs/cloud-config-example.erb +63 -0
  37. data/test/puke/config.yaml +16 -0
  38. data/test/puke/products/sample-api/instances.yaml +37 -0
  39. data/test/puke/products/sample-api/security_groups.yaml +19 -0
  40. data/test/vominator.yaml +7 -0
  41. data/vominator.gemspec +34 -0
  42. metadata +259 -0
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'vominator/instances'
3
+
4
+ describe Vominator::Instances do
5
+ describe 'get_instances' do
6
+ context 'when I pass a valid environment and product' do
7
+ let (:instances) {Vominator::Instances.get_instances('test', 'sample-api')}
8
+
9
+ subject { instances }
10
+
11
+ it 'should not raise an error' do
12
+ expect { instances }.to_not raise_error
13
+ end
14
+
15
+ it 'should contain 3 sample api instances' do
16
+ # noinspection RubyResolve
17
+ expect(instances).to contain_exactly({'sample-api-1' => nil,
18
+ 'type' => {
19
+ 'prod' => 'm3.medium',
20
+ 'staging' => 'm3.medium'},
21
+ 'ami'=>'ami-123123',
22
+ 'family'=>'linux',
23
+ 'ip'=>'10.OCTET.41.21',
24
+ 'az'=>'us-east-1c',
25
+ 'environment'=>['staging'],
26
+ 'security_groups'=>['sample-api-server'],
27
+ 'chef_recipes'=>['srv_sample_api']
28
+ },
29
+ {'sample-api-2' => nil,
30
+ 'type' => {
31
+ 'prod' => 'm3.medium',
32
+ 'staging' => 'm3.medium'},
33
+ 'family'=>'linux',
34
+ 'ip'=>'10.OCTET.42.21',
35
+ 'az'=>'us-east-1d',
36
+ 'security_groups'=>['sample-api-server'],
37
+ 'chef_recipes'=>['srv_sample_api']
38
+ },
39
+ {'sample-api-3' => nil,
40
+ 'type' => {
41
+ 'prod' => 'm3.medium',
42
+ 'staging' => 'm3.medium'},
43
+ 'family'=>'linux',
44
+ 'ip'=>'10.OCTET.43.21',
45
+ 'az'=>'us-east-1e',
46
+ 'security_groups'=>['sample-api-server'],
47
+ 'chef_recipes'=>['srv_sample_api']
48
+ })
49
+ end
50
+ end
51
+
52
+ context 'when I pass a filter' do
53
+ let (:instances) {Vominator::Instances.get_instances('test', 'sample-api', ['sample-api-1'])}
54
+
55
+ subject { instances }
56
+
57
+ it 'it should filter the results' do
58
+ expect(instances).to contain_exactly({'sample-api-1' => nil,
59
+ 'type' => {
60
+ 'prod' => 'm3.medium',
61
+ 'staging' => 'm3.medium'},
62
+ 'ami'=>'ami-123123',
63
+ 'family'=>'linux',
64
+ 'ip'=>'10.OCTET.41.21',
65
+ 'az'=>'us-east-1c',
66
+ 'environment'=>['staging'],
67
+ 'security_groups'=>['sample-api-server'],
68
+ 'chef_recipes'=>['srv_sample_api']
69
+ })
70
+
71
+ end
72
+ end
73
+ context 'when I pass an invalid environment or product' do
74
+ xit 'it should do something'
75
+ end
76
+
77
+ end
78
+
79
+ describe 'generate_cloud_config' do
80
+ context 'when I pass a valid hostname, environment, family, roles, and recipes' do
81
+ let (:cloud_config) { Vominator::Instances.generate_cloud_config('sample-api-1', 'test', 'linux', ['role1'], ['recipe1'] )}
82
+
83
+ subject { cloud_config }
84
+ it 'should return a rendered cloud_config' do
85
+ expect {cloud_config}.to_not raise_error
86
+ expect(cloud_config).to include('sample-api-1.test')
87
+ expect(cloud_config).to include('role1')
88
+ expect(cloud_config).to include('recipe1')
89
+ end
90
+ end
91
+
92
+ context 'when I pass invalid parameters' do
93
+ xit 'it should do something'
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'vominator/route53'
3
+
4
+ describe Vominator::Route53 do
5
+ before(:all) do
6
+ @puke_variables = Vominator.get_puke_variables('test')
7
+ Aws.config[:stub_responses] = true
8
+ @r53 = Aws::Route53::Client.new
9
+ @r53.stub_responses(:list_resource_record_sets, { :is_truncated => false, :max_items => 50, :resource_record_sets => [
10
+ { :name => 'sample-api-1.test.example.com.', :type => 'A', :resource_records => [{ :value => '10.203.41.21'}] },
11
+ { :name => 'sample-api-2.test.example.com.', :type => 'A', :resource_records => [{ :value => '10.203.42.21'}] },
12
+ { :name => 'sample-api-3.test.example.com.', :type => 'A', :resource_records => [{ :value => '10.203.43.21'}] }
13
+ ]}
14
+ )
15
+ end
16
+
17
+ describe 'get_records' do
18
+ context 'when I pass a valid route53 client and an invalid zone file' do
19
+ xit 'should do something'
20
+ end
21
+
22
+ context 'when I pass an invalid route53 client and a valid zone file' do
23
+ xit 'should do something'
24
+ end
25
+
26
+ context 'when I pass an invalid route53 client and an invalid zone file' do
27
+ xit 'should do something'
28
+ end
29
+
30
+ context 'when I pass a valid route53 client and zone file' do
31
+ let(:records) { Vominator::Route53.get_records(@r53,"/hostedzone/#{@puke_variables['zone']}", 2)}
32
+
33
+ subject { records }
34
+
35
+ it { is_expected.to include('sample-api-1.test.example.com.') }
36
+ it { is_expected.to include('sample-api-2.test.example.com.') }
37
+ it { is_expected.to include('sample-api-3.test.example.com.') }
38
+ end
39
+ end
40
+
41
+ describe 'create_record' do
42
+ context 'when I pass a valid route53 client, zone, fqdn, and ip' do
43
+ let (:response) { Vominator::Route53.create_record(@r53,"#{@puke_variables['zone']}", 'sample-api-1.test.example.com', '10.203.41.21')}
44
+
45
+ subject { response }
46
+
47
+ it 'should return true' do
48
+ @r53.stub_responses(:change_resource_record_sets, :change_info => { :status => 'PENDING', :id => '12345', :submitted_at => Time.now})
49
+ end
50
+ end
51
+ end
52
+
53
+ describe 'delete_record' do
54
+ context 'When I pass a valid route53 client, zone, fqdn, and ip' do
55
+ let (:response) { Vominator::Route53.delete_record(@r53, "#{@puke_variables['zone']}",'sample-api-1.test.example.com', '10.203.41.21')}
56
+
57
+ subject { response }
58
+
59
+ it 'should return true' do
60
+ @r53.stub_responses(:change_resource_record_sets, :change_info => { :status => 'PENDING', :id => '12345', :submitted_at => Time.now})
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'vominator/ssm'
3
+
4
+ describe Vominator::SSM do
5
+ before(:each) do
6
+ Aws.config[:stub_responses] = true
7
+ @ssm = Aws::SSM::Client.new
8
+ end
9
+
10
+ describe 'get_documents' do
11
+ context 'when I pass a valid client' do
12
+ let (:documents) { Vominator::SSM.get_documents(@ssm,2)}
13
+
14
+ subject { documents }
15
+
16
+ it 'returns an array of document names' do
17
+ @ssm.stub_responses(:list_documents, {:next_token => 'abcd', :document_identifiers => [{:name => 'document1'},{:name => 'document2'}]},
18
+ {:next_token => nil, :document_identifiers => [{:name => 'document3'},{:name => 'document4'}]})
19
+
20
+ expect {documents}.to_not raise_error
21
+ expect(documents.count).to eq 4
22
+ expect(documents).to include('document3')
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'describe_document' do
28
+ context 'when I pass a valid client and name' do
29
+ let (:document) { Vominator::SSM.describe_document(@ssm,'document-3')}
30
+
31
+ subject { document }
32
+
33
+ it 'returns details about a document' do
34
+ @ssm.stub_responses(:describe_document, :document => {:created_date => Time.now, :name => 'document-3', :status => 'active', :sha_1 => 'abcd'})
35
+ expect { document}.to_not raise_error
36
+ expect(document.name).to match 'document-3'
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'get_document' do
42
+ context 'when I pass a valid client and name' do
43
+ let (:document) { Vominator::SSM.get_document(@ssm, 'document-3')}
44
+
45
+ subject { document }
46
+
47
+ it 'returns the document' do
48
+ @ssm.stub_responses(:get_document, {:content => '{"schemaVersion":"1.0","description":"test policy"}', :name => 'document-3'})
49
+ expect { document }.to_not raise_error
50
+ expect(document.name).to match 'document-3'
51
+ expect(document.content).to match '{"schemaVersion":"1.0","description":"test policy"}'
52
+ end
53
+ end
54
+ end
55
+ describe 'put_document' do
56
+ context 'when I pass a valid client, name, and data' do
57
+ let (:document) { Vominator::SSM.put_document(@ssm, 'document-5','{"schemaVersion":"1.0","description":"test policy"}') }
58
+
59
+ subject { document }
60
+
61
+ it 'creates the document' do
62
+ @ssm.stub_responses(:describe_document, :document => {:created_date => Time.now, :name => 'document-5', :status => 'active', :sha_1 => 'abcd'})
63
+ expect { document }.to_not raise_error
64
+ end
65
+ end
66
+ end
67
+
68
+ describe 'associated' do
69
+ context 'when I pass a valid client, name and instance_id and is associated to the instance' do
70
+ let (:association) { Vominator::SSM.associated?(@ssm, 'document-1','i-123456')}
71
+
72
+ subject { association }
73
+
74
+ it 'returns true' do
75
+ @ssm.stub_responses(:describe_association, :association_description => {:date => Time.now, :instance_id => 'i-123456', :name => 'document-1', :status => {:name => 'Success', :date => Time.now, :message => 'It worked'}})
76
+ expect { association }.to_not raise_error
77
+ expect(association).to be true
78
+ end
79
+ end
80
+ end
81
+
82
+ describe 'create_association' do
83
+ context 'when I pass a valid client, name, and instance_id' do
84
+ let (:association) { Vominator::SSM.create_association(@ssm, 'document-1','i-123456')}
85
+
86
+ subject { association }
87
+
88
+ it 'returns true' do
89
+ @ssm.stub_responses(:describe_association, :association_description => {:date => Time.now, :instance_id => 'i-123456', :name => 'document-1', :status => {:name => 'Success', :date => Time.now, :message => 'It worked'}})
90
+ expect { association }.to_not raise_error
91
+ expect(association).to be true
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,209 @@
1
+ require 'spec_helper'
2
+ require 'vominator/vominator'
3
+
4
+ describe Vominator do
5
+
6
+ describe 'get_config' do
7
+ context 'when I pass an invalid config file' do
8
+ let(:vominator_config) { Vominator.get_config('/badpath') }
9
+
10
+ subject { vominator_config }
11
+
12
+ it 'should exit' do
13
+ cached_vominator_config = ENV.delete('VOMINATOR_CONFIG')
14
+ expect{ subject }.to exit_with_code(1)
15
+ ENV['VOMINATOR_CONFIG'] = cached_vominator_config
16
+ end
17
+
18
+ end
19
+
20
+ context 'when I pass a valid config file' do
21
+ let(:vominator_config) { Vominator.get_config('test/vominator.yaml') }
22
+
23
+ subject { vominator_config }
24
+
25
+ it { is_expected.not_to be false }
26
+ it { is_expected.to include('access_key_id' => 'DUMMY_ACCESS_KEY') }
27
+ it { is_expected.to include('secret_access_key' => 'DUMMY_SECRET_KEY') }
28
+ it { is_expected.to include('configuration_path' => 'test/puke') }
29
+ it { is_expected.to include('key_pair_name' => 'ci@example.com') }
30
+ it { is_expected.to include('chef_client_key' => 'ci.pem') }
31
+ it { is_expected.to include('chef_client_name' => 'ci') }
32
+ end
33
+ end
34
+
35
+ describe 'get_puke_config' do
36
+
37
+ context 'when I pass an invalid directory' do
38
+ let (:puke_config) { Vominator.get_puke_config('/badpath')}
39
+
40
+ subject { puke_config }
41
+
42
+ it 'should raise an error' do
43
+ expect { puke_config }.to raise_error
44
+ end
45
+ end
46
+
47
+ context 'when I pass a valid directory' do
48
+ let (:puke_config) { Vominator.get_puke_config(VOMINATOR_CONFIG['configuration_path'])}
49
+
50
+ subject { puke_config }
51
+
52
+ it 'should not raise an error' do
53
+ expect { puke_config }.to_not raise_error
54
+ end
55
+ end
56
+ end
57
+
58
+ describe 'get_key_pair' do
59
+ context 'when I pass a valid Vominator config' do
60
+ vominator_config = Vominator.get_config('test/vominator.yaml')
61
+ let (:key_pair) { Vominator.get_key_pair(vominator_config) }
62
+
63
+ subject { key_pair }
64
+
65
+ it 'should return a key_pair name' do
66
+ expect { key_pair }.to_not raise_error
67
+ expect(key_pair).to match 'ci@example.com'
68
+ end
69
+ end
70
+ end
71
+ describe 'get_puke_variables' do
72
+
73
+ context 'when I pass an invalid environment' do
74
+ let (:puke_variables) { Vominator.get_puke_variables('invalid_environment')}
75
+
76
+ subject { puke_variables }
77
+
78
+ xit 'should raise an error' do
79
+ expect { puke_variables }.to raise_error
80
+ end
81
+ end
82
+
83
+ context 'when I pass a valid environment' do
84
+ let (:puke_variables) { Vominator.get_puke_variables('test')}
85
+
86
+ subject { puke_variables }
87
+
88
+ it 'should not raise an error' do
89
+ expect { puke_variables }.to_not raise_error
90
+ end
91
+ end
92
+ end
93
+
94
+ describe 'yesno' do
95
+ context 'default is yes' do
96
+ let (:yesno) { Vominator.yesno? }
97
+ context 'when I say yes' do
98
+ it 'should prompt the user and return true' do
99
+ expect($terminal).to receive(:ask).with('Continue? [Y/n] ').and_return('y')
100
+ expect(yesno).to be_truthy
101
+ end
102
+ end
103
+
104
+ context 'when I say no' do
105
+ it 'should prompt the user and return false' do
106
+ expect($terminal).to receive(:ask).with('Continue? [Y/n] ').and_return('n')
107
+ expect(yesno).to be_falsey
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'default is no' do
113
+ let (:yesno) { Vominator.yesno?(default: false) }
114
+ context 'when I say yes' do
115
+ it 'should prompt the user and return true' do
116
+ expect($terminal).to receive(:ask).with('Continue? [y/N] ').and_return('y')
117
+ expect(yesno).to be_truthy
118
+ end
119
+ end
120
+
121
+ context 'when I say no' do
122
+ it 'should prompt the user and return false' do
123
+ expect($terminal).to receive(:ask).with('Continue? [y/N] ').and_return('n')
124
+ expect(yesno).to be_falsey
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ describe Vominator::Logger do
132
+ describe 'info' do
133
+ context 'when I pass a log message' do
134
+ message = 'This is a test message'
135
+ let (:info_log) { Vominator::Logger.info(message) }
136
+
137
+ subject { info_log }
138
+
139
+ it 'should print the log message' do
140
+ expect { info_log }.to output("#{message}\n").to_stdout
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'test' do
146
+ context 'when I pass a log message' do
147
+ message = 'This is a test message'
148
+ let (:test_log) { Vominator::Logger.test(message) }
149
+
150
+ subject { test_log }
151
+
152
+ it 'should print the log message' do
153
+ expect { test_log }.to output("\e[36m#{message}\e[0m\n").to_stdout
154
+ end
155
+ end
156
+ end
157
+
158
+ describe 'error' do
159
+ context 'when I pass a log message' do
160
+ message = 'This is a test message'
161
+ let (:error_log) { Vominator::Logger.error(message) }
162
+
163
+ subject { error_log }
164
+
165
+ it 'should print the log message' do
166
+ expect { error_log }.to output("\e[31m#{message}\e[0m\n").to_stdout
167
+ end
168
+ end
169
+ end
170
+
171
+ describe 'fatal' do
172
+ context 'when I pass a log message' do
173
+ message = 'This is a test message'
174
+ let (:fatal_log) { Vominator::Logger.fatal(message) }
175
+
176
+ subject { fatal_log }
177
+
178
+ it 'should print the log message and exit' do
179
+ expect { fatal_log }.to exit_with_code(1).and output("\e[31m#{message}\e[0m\n").to_stdout
180
+ end
181
+ end
182
+ end
183
+
184
+ describe 'success' do
185
+ context 'when I pass a log message' do
186
+ message = 'This is a test message'
187
+ let (:success_log) { Vominator::Logger.success(message) }
188
+
189
+ subject { success_log }
190
+
191
+ it 'should print the log message' do
192
+ expect { success_log }.to output("\e[32m#{message}\e[0m\n").to_stdout
193
+ end
194
+ end
195
+ end
196
+
197
+ describe 'warning' do
198
+ context 'when I pass a log message' do
199
+ message = 'This is a test message'
200
+ let (:warning_log) { Vominator::Logger.warning(message) }
201
+
202
+ subject { warning_log }
203
+
204
+ it 'should print the log message' do
205
+ expect { warning_log }.to output("\e[33m#{message}\e[0m\n").to_stdout
206
+ end
207
+ end
208
+ end
209
+ end