vominator 0.0.1
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 +25 -0
- data/.rspec +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +116 -0
- data/Rakefile +12 -0
- data/bin/vominate +12 -0
- data/circle.yml +5 -0
- data/lib/ec2.rb +12 -0
- data/lib/ec2/instances.rb +362 -0
- data/lib/ec2/security_groups.rb +314 -0
- data/lib/ec2/ssm.rb +81 -0
- data/lib/vominator/aws.rb +15 -0
- data/lib/vominator/constants.rb +53 -0
- data/lib/vominator/ec2.rb +308 -0
- data/lib/vominator/instances.rb +34 -0
- data/lib/vominator/route53.rb +125 -0
- data/lib/vominator/security_groups.rb +26 -0
- data/lib/vominator/ssm.rb +57 -0
- data/lib/vominator/version.rb +3 -0
- data/lib/vominator/vominator.rb +74 -0
- data/lib/vominator/vpc.rb +82 -0
- data/lib/vpc.rb +8 -0
- data/lib/vpc/create.rb +188 -0
- data/spec/lib/instances_spec.rb +2 -0
- data/spec/lib/vominator/aws_spec.rb +6 -0
- data/spec/lib/vominator/ec2_spec.rb +783 -0
- data/spec/lib/vominator/instances_spec.rb +96 -0
- data/spec/lib/vominator/route53_spec.rb +64 -0
- data/spec/lib/vominator/ssm_spec.rb +95 -0
- data/spec/lib/vominator/vominator_spec.rb +209 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/support/matchers/exit_with_code.rb +24 -0
- data/test/puke/cloud-configs/.gitkeep +0 -0
- data/test/puke/cloud-configs/cloud-config-example.erb +63 -0
- data/test/puke/config.yaml +16 -0
- data/test/puke/products/sample-api/instances.yaml +37 -0
- data/test/puke/products/sample-api/security_groups.yaml +19 -0
- data/test/vominator.yaml +7 -0
- data/vominator.gemspec +34 -0
- 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
|