orats 0.5.1 → 0.6.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 +4 -4
- data/README.md +11 -4
- data/lib/orats/cli.rb +34 -23
- data/lib/orats/commands/common.rb +82 -0
- data/lib/orats/commands/new/ansible.rb +105 -0
- data/lib/orats/commands/new/exec.rb +54 -0
- data/lib/orats/commands/new/foreman.rb +55 -0
- data/lib/orats/commands/new/rails.rb +107 -0
- data/lib/orats/commands/nuke.rb +72 -0
- data/lib/orats/commands/outdated/compare.rb +100 -0
- data/lib/orats/commands/outdated/exec.rb +46 -0
- data/lib/orats/commands/outdated/parse.rb +62 -0
- data/lib/orats/commands/play.rb +34 -0
- data/lib/orats/commands/ui.rb +52 -0
- data/lib/orats/templates/auth.rb +1 -3
- data/lib/orats/templates/base.rb +243 -11
- data/lib/orats/templates/includes/Galaxyfile +1 -1
- data/lib/orats/templates/includes/Gemfile +5 -1
- data/lib/orats/templates/includes/inventory/group_vars/all.yml +14 -9
- data/lib/orats/templates/play.rb +0 -3
- data/lib/orats/version.rb +1 -1
- metadata +13 -6
- data/lib/orats/command.rb +0 -107
- data/lib/orats/foreman.rb +0 -54
- data/lib/orats/shell.rb +0 -503
data/lib/orats/command.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'orats/version'
|
2
|
-
require 'orats/shell'
|
3
|
-
require 'orats/foreman'
|
4
|
-
|
5
|
-
module Orats
|
6
|
-
class Command
|
7
|
-
include Thor::Base
|
8
|
-
include Thor::Shell
|
9
|
-
include Thor::Actions
|
10
|
-
#source_root Dir.pwd
|
11
|
-
|
12
|
-
include Shell
|
13
|
-
include Foreman
|
14
|
-
|
15
|
-
attr_accessor :active_path
|
16
|
-
|
17
|
-
def initialize(app_name = '', options = {})
|
18
|
-
@app_name = app_name
|
19
|
-
@options = options
|
20
|
-
|
21
|
-
# required to mix in thor actions without having a base thor class
|
22
|
-
#@destination_stack = [self.class.source_root]
|
23
|
-
self.destination_root = Dir.pwd
|
24
|
-
@behavior = :invoke
|
25
|
-
end
|
26
|
-
|
27
|
-
def new
|
28
|
-
@active_path = @app_name
|
29
|
-
@active_path = services_path(@app_name)
|
30
|
-
|
31
|
-
rails_template 'base' do
|
32
|
-
gsub_postgres_info
|
33
|
-
git_commit 'Change the postgres information'
|
34
|
-
|
35
|
-
unless @options[:redis_password].empty?
|
36
|
-
gsub_redis_info
|
37
|
-
git_commit 'Add the redis password'
|
38
|
-
end
|
39
|
-
|
40
|
-
gsub_project_path
|
41
|
-
git_commit 'Add the development project path'
|
42
|
-
|
43
|
-
bundle_install
|
44
|
-
git_commit 'Add gem lock file'
|
45
|
-
|
46
|
-
bundle_binstubs
|
47
|
-
git_commit 'Add binstubs for the important gems'
|
48
|
-
|
49
|
-
spring_binstub
|
50
|
-
git_commit 'Springify all of the bins'
|
51
|
-
|
52
|
-
run_rake 'db:create:all db:migrate'
|
53
|
-
git_commit 'Add the database schema file'
|
54
|
-
end
|
55
|
-
|
56
|
-
if @options[:auth]
|
57
|
-
rails_template 'auth', '--skip ' do
|
58
|
-
run_rake 'db:migrate db:seed'
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
unless @options[:skip_extras]
|
63
|
-
ansible_init @app_name
|
64
|
-
end
|
65
|
-
|
66
|
-
@active_path = services_path(@app_name)
|
67
|
-
foreman_init
|
68
|
-
end
|
69
|
-
|
70
|
-
def play
|
71
|
-
play_app @app_name
|
72
|
-
end
|
73
|
-
|
74
|
-
def nuke
|
75
|
-
@active_path = @app_name
|
76
|
-
|
77
|
-
nuke_warning
|
78
|
-
|
79
|
-
nuke_data_details_warning unless @options[:skip_data]
|
80
|
-
|
81
|
-
confirmed_to_delete = yes?('Are you sure? (y/N)', :cyan)
|
82
|
-
|
83
|
-
if confirmed_to_delete
|
84
|
-
nuke_data unless @options[:skip_data]
|
85
|
-
|
86
|
-
nuke_directory
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def outdated
|
91
|
-
outdated_init
|
92
|
-
end
|
93
|
-
|
94
|
-
def version
|
95
|
-
puts "Orats version #{VERSION}"
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
def active_project
|
100
|
-
File.basename @active_path
|
101
|
-
end
|
102
|
-
|
103
|
-
def services_path(app_name)
|
104
|
-
@options[:skip_extras] ? app_name : "#{app_name}/services/#{active_project}"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
data/lib/orats/foreman.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
require 'timeout'
|
3
|
-
|
4
|
-
module Orats
|
5
|
-
module Foreman
|
6
|
-
def foreman_init
|
7
|
-
|
8
|
-
@options[:skip_foreman_start] ? message = 'Start your' : message = 'Starting'
|
9
|
-
|
10
|
-
puts '', '='*80
|
11
|
-
say_status 'action', "\e[1m#{message} server with the following commands:\e[0m", :cyan
|
12
|
-
say_status 'command', "cd #{@active_path}", :magenta
|
13
|
-
say_status 'command', 'bundle exec foreman start', :magenta
|
14
|
-
puts '='*80, ''
|
15
|
-
|
16
|
-
attempt_to_start unless @options[:skip_foreman_start]
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def attempt_to_start
|
22
|
-
while port_taken? do
|
23
|
-
puts
|
24
|
-
say_status 'error', "\e[1mAnother application is using port 3000\n\e[0m", :red
|
25
|
-
puts '-'*80
|
26
|
-
|
27
|
-
exit 1 if no?('Would you like to try running the server again? (y/N)', :cyan)
|
28
|
-
end
|
29
|
-
|
30
|
-
puts
|
31
|
-
|
32
|
-
run_from @active_path, 'bundle exec foreman start'
|
33
|
-
end
|
34
|
-
|
35
|
-
def port_taken?
|
36
|
-
begin
|
37
|
-
Timeout::timeout(5) do
|
38
|
-
begin
|
39
|
-
s = TCPSocket.new('localhost', 3000)
|
40
|
-
s.close
|
41
|
-
|
42
|
-
return true
|
43
|
-
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
44
|
-
return false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
rescue Timeout::Error
|
48
|
-
false
|
49
|
-
end
|
50
|
-
|
51
|
-
false
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/lib/orats/shell.rb
DELETED
@@ -1,503 +0,0 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
require 'open-uri'
|
3
|
-
|
4
|
-
module Orats
|
5
|
-
module Shell
|
6
|
-
def run_from(path, command)
|
7
|
-
run "cd #{path} && #{command} && cd -"
|
8
|
-
end
|
9
|
-
|
10
|
-
def log_message(type, message)
|
11
|
-
puts
|
12
|
-
say_status type, "#{message}...", :yellow
|
13
|
-
puts '-'*80, ''; sleep 0.25
|
14
|
-
end
|
15
|
-
|
16
|
-
def log_status(type, message, color)
|
17
|
-
puts
|
18
|
-
say_status type, set_color(message, :bold), color
|
19
|
-
end
|
20
|
-
|
21
|
-
def log_status_under(type, message, color)
|
22
|
-
say_status type, message, color
|
23
|
-
puts
|
24
|
-
end
|
25
|
-
|
26
|
-
def log_results(results, message)
|
27
|
-
log_status 'results', results, :magenta
|
28
|
-
log_status_under 'message', message, :white
|
29
|
-
end
|
30
|
-
|
31
|
-
def git_commit(message)
|
32
|
-
run_from @active_path, "git add -A && git commit -m '#{message}'"
|
33
|
-
end
|
34
|
-
|
35
|
-
def gsub_postgres_info
|
36
|
-
log_message 'root', 'Changing the postgres information'
|
37
|
-
|
38
|
-
gsub_file "#{@active_path}/.env", 'DATABASE_HOST: localhost', "DATABASE_HOST: #{@options[:pg_location]}"
|
39
|
-
gsub_file "#{@active_path}/.env", ': postgres', ": #{@options[:pg_username]}"
|
40
|
-
gsub_file "#{@active_path}/.env", ': supersecrets', ": #{@options[:pg_password]}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def gsub_redis_info
|
44
|
-
log_message 'root', 'Adding the redis password'
|
45
|
-
|
46
|
-
gsub_file "#{@active_path}/config/initializers/sidekiq.rb", '//', "//:#{ENV['CACHE_PASSWORD']}@"
|
47
|
-
gsub_file "#{@active_path}/.env", 'HE_PASSWORD: ', "HE_PASSWORD: #{@options[:redis_password]}"
|
48
|
-
gsub_file "#{@active_path}/.env", 'CACHE_HOST: localhost', "CACHE_HOST: #{@options[:redis_location]}"
|
49
|
-
gsub_file "#{@active_path}/config/application.rb", '# pass', 'pass'
|
50
|
-
end
|
51
|
-
|
52
|
-
def gsub_project_path
|
53
|
-
log_message 'root', 'Changing the project path'
|
54
|
-
|
55
|
-
gsub_file "#{@active_path}/.env", ': /full/path/to/your/project', ": #{File.expand_path(@active_path)}"
|
56
|
-
end
|
57
|
-
|
58
|
-
def run_rake(command)
|
59
|
-
log_message 'shell', 'Running rake commands'
|
60
|
-
|
61
|
-
run_from @active_path, "bundle exec rake #{command}"
|
62
|
-
end
|
63
|
-
|
64
|
-
def bundle_install
|
65
|
-
log_message 'shell', 'Running bundle install, this may take a while'
|
66
|
-
|
67
|
-
run_from @active_path, 'bundle install'
|
68
|
-
end
|
69
|
-
|
70
|
-
def bundle_binstubs
|
71
|
-
log_message 'shell', 'Running bundle binstubs for a few gems'
|
72
|
-
|
73
|
-
run_from @active_path, 'bundle binstubs whenever puma sidekiq'
|
74
|
-
end
|
75
|
-
|
76
|
-
def spring_binstub
|
77
|
-
log_message 'shell', 'Running spring binstub'
|
78
|
-
|
79
|
-
run_from @active_path, 'bundle exec spring binstub --all'
|
80
|
-
end
|
81
|
-
|
82
|
-
def nuke_warning
|
83
|
-
puts
|
84
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete this directory:\e[0m", :red
|
85
|
-
say_status 'path', "#{File.expand_path(@app_name)}", :yellow
|
86
|
-
puts
|
87
|
-
end
|
88
|
-
|
89
|
-
def rails_directories
|
90
|
-
rails_gemfiles = run("find #{@active_path} -type f -name Gemfile | xargs grep -lE \"gem 'rails'|gem \\\"rails\\\"\"", capture: true)
|
91
|
-
gemfile_paths = rails_gemfiles.split("\n")
|
92
|
-
|
93
|
-
gemfile_paths.map { |gemfile| File.dirname(gemfile) }
|
94
|
-
end
|
95
|
-
|
96
|
-
def nuke_data_details_warning
|
97
|
-
rails_projects = []
|
98
|
-
|
99
|
-
rails_directories.each do |rails_dir|
|
100
|
-
rails_projects << File.basename(rails_dir)
|
101
|
-
end
|
102
|
-
|
103
|
-
project_names = rails_projects.join(', ')
|
104
|
-
|
105
|
-
puts
|
106
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete all postgres databases for:\e[0m", :red
|
107
|
-
say_status 'databases', project_names, :yellow
|
108
|
-
puts
|
109
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete all redis namespaces for:\e[0m", :red
|
110
|
-
say_status 'namespace', project_names, :yellow
|
111
|
-
puts
|
112
|
-
end
|
113
|
-
|
114
|
-
def nuke_data
|
115
|
-
rails_directories.each do |directory|
|
116
|
-
log_message 'root', 'Removing postgres databases'
|
117
|
-
run_from directory, 'bundle exec rake db:drop:all'
|
118
|
-
nuke_redis File.basename(directory)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def can_play?
|
123
|
-
log_message 'shell', 'Checking for the ansible binary'
|
124
|
-
|
125
|
-
has_ansible = run('which ansible', capture: true)
|
126
|
-
|
127
|
-
dependency_error 'Cannot access ansible',
|
128
|
-
'Are you sure you have ansible setup correctly?',
|
129
|
-
'http://docs.ansible.com/intro_installation.html`' if has_ansible.empty?
|
130
|
-
|
131
|
-
!has_ansible.empty?
|
132
|
-
end
|
133
|
-
|
134
|
-
def rails_template(command, flags = '')
|
135
|
-
exit_if_cannot_rails
|
136
|
-
exit_if_exists unless flags.index(/--skip/)
|
137
|
-
|
138
|
-
run "rails new #{@active_path} #{flags} --skip-bundle --template #{File.expand_path File.dirname(__FILE__)}/templates/#{command}.rb"
|
139
|
-
yield if block_given?
|
140
|
-
end
|
141
|
-
|
142
|
-
def play_app(path)
|
143
|
-
return unless can_play?
|
144
|
-
|
145
|
-
@active_path = path
|
146
|
-
rails_template 'play'
|
147
|
-
end
|
148
|
-
|
149
|
-
def ansible_init(path)
|
150
|
-
log_message 'shell', 'Creating ansible inventory'
|
151
|
-
run "mkdir #{path}/inventory"
|
152
|
-
run "mkdir #{path}/inventory/group_vars"
|
153
|
-
copy_from_includes 'inventory/hosts', path
|
154
|
-
copy_from_includes 'inventory/group_vars/all.yml', path
|
155
|
-
|
156
|
-
secrets_path = "#{path}/secrets"
|
157
|
-
log_message 'shell', 'Creating ansible secrets'
|
158
|
-
run "mkdir #{secrets_path}"
|
159
|
-
|
160
|
-
save_secret_string "#{secrets_path}/postgres_password"
|
161
|
-
|
162
|
-
if @options[:redis_password].empty?
|
163
|
-
run "touch #{secrets_path}/redis_password"
|
164
|
-
else
|
165
|
-
save_secret_string "#{secrets_path}/redis_password"
|
166
|
-
gsub_file "#{path}/inventory/group_vars/all.yml", 'redis_password: false', 'redis_password: true'
|
167
|
-
end
|
168
|
-
|
169
|
-
save_secret_string "#{secrets_path}/mail_password"
|
170
|
-
save_secret_string "#{secrets_path}/rails_token"
|
171
|
-
save_secret_string "#{secrets_path}/devise_token"
|
172
|
-
save_secret_string "#{secrets_path}/devise_pepper_token"
|
173
|
-
|
174
|
-
log_message 'shell', 'Modifying secrets path in group_vars/all.yml'
|
175
|
-
gsub_file "#{path}/inventory/group_vars/all.yml", '~/tmp/testproj/secrets/', File.expand_path(secrets_path)
|
176
|
-
|
177
|
-
log_message 'shell', 'Modifying the place holder app name in group_vars/all.yml'
|
178
|
-
gsub_file "#{path}/inventory/group_vars/all.yml", 'testproj', File.basename(path)
|
179
|
-
gsub_file "#{path}/inventory/group_vars/all.yml", 'TESTPROJ', File.basename(path).upcase
|
180
|
-
|
181
|
-
log_message 'shell', 'Creating ssh keypair'
|
182
|
-
run "ssh-keygen -t rsa -P '' -f #{secrets_path}/id_rsa"
|
183
|
-
|
184
|
-
log_message 'shell', 'Creating self signed ssl certificates'
|
185
|
-
run create_rsa_certificate(secrets_path, 'sslkey.key', 'sslcert.crt')
|
186
|
-
|
187
|
-
log_message 'shell', 'Creating monit pem file'
|
188
|
-
run "#{create_rsa_certificate(secrets_path, 'monit.pem', 'monit.pem')} && openssl gendh 512 >> #{secrets_path}/monit.pem"
|
189
|
-
|
190
|
-
install_role_dependencies unless @options[:skip_galaxy]
|
191
|
-
end
|
192
|
-
|
193
|
-
def outdated_init
|
194
|
-
latest_gem_version = compare_gem_version
|
195
|
-
|
196
|
-
github_repo = "https://raw.githubusercontent.com/nickjj/orats/#{latest_gem_version}/lib/orats"
|
197
|
-
|
198
|
-
galaxy_url = "#{github_repo}/templates/includes/Galaxyfile"
|
199
|
-
playbook_url = "#{github_repo}/templates/play.rb"
|
200
|
-
inventory_url = "#{github_repo}/templates/includes/inventory/group_vars/all.yml"
|
201
|
-
|
202
|
-
remote_galaxy_contents = url_to_string(galaxy_url)
|
203
|
-
remote_playbook_contents = url_to_string(playbook_url)
|
204
|
-
remote_inventory_contents = url_to_string(inventory_url)
|
205
|
-
|
206
|
-
compare_remote_role_version_to_local remote_galaxy_contents
|
207
|
-
|
208
|
-
local_playbook = compare_remote_to_local('playbook',
|
209
|
-
'roles',
|
210
|
-
playbook_file_stats(remote_playbook_contents),
|
211
|
-
playbook_file_stats(IO.read(playbook_file_path)))
|
212
|
-
|
213
|
-
local_inventory = compare_remote_to_local('inventory',
|
214
|
-
'variables',
|
215
|
-
inventory_file_stats(remote_inventory_contents),
|
216
|
-
inventory_file_stats(IO.read(inventory_file_path)))
|
217
|
-
|
218
|
-
unless @options[:playbook].empty?
|
219
|
-
compare_user_to_local('playbook', 'roles', @options[:playbook], local_playbook) do
|
220
|
-
playbook_file_stats IO.read(@options[:playbook])
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
unless @options[:inventory].empty?
|
225
|
-
compare_user_to_local('inventory', 'variables', @options[:inventory], local_inventory) do
|
226
|
-
inventory_file_stats IO.read(@options[:inventory])
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
private
|
232
|
-
|
233
|
-
def inventory_file_stats(file)
|
234
|
-
# pluck out all of the values contained with {{ }}
|
235
|
-
ansible_variable_list = file.scan(/\{\{([^{{}}]*)\}\}/)
|
236
|
-
|
237
|
-
# remove the leading space
|
238
|
-
ansible_variable_list.map! { |line| line.first[0] = '' }
|
239
|
-
|
240
|
-
# match every line that is not a comment and contains a colon
|
241
|
-
inventory_variable_list = file.scan(/^[^#].*:/)
|
242
|
-
|
243
|
-
inventory_variable_list.map! do |line|
|
244
|
-
# only strip lines that need it
|
245
|
-
line.strip! if line.include?(' ') || line.include?("\n")
|
246
|
-
|
247
|
-
# get rid of the trailing colon
|
248
|
-
line.chomp(':')
|
249
|
-
|
250
|
-
# if a value of a certain variable has a colon then the regex
|
251
|
-
# picks this up as a match. only take the variable name
|
252
|
-
# if this happens to occur
|
253
|
-
line.split(':').first if line.include?(':')
|
254
|
-
end
|
255
|
-
|
256
|
-
(ansible_variable_list + inventory_variable_list).uniq
|
257
|
-
end
|
258
|
-
|
259
|
-
def playbook_file_stats(file)
|
260
|
-
# match every line that is not a comment and has a role defined
|
261
|
-
roles_list = file.scan(/^.*role:.*/)
|
262
|
-
|
263
|
-
roles_list.map! do |line|
|
264
|
-
# only strip lines that need it
|
265
|
-
line.strip! if line.include?(' ') || line.include?("\n")
|
266
|
-
|
267
|
-
role_parts = line.split('role:')
|
268
|
-
|
269
|
-
line = role_parts[1]
|
270
|
-
|
271
|
-
if line.include?(',')
|
272
|
-
line = line.split(',').first
|
273
|
-
end
|
274
|
-
|
275
|
-
line.strip! if line.include?(' ')
|
276
|
-
end
|
277
|
-
|
278
|
-
roles_list.reject! { |line| line.start_with?('#') }
|
279
|
-
|
280
|
-
roles_list.uniq
|
281
|
-
end
|
282
|
-
|
283
|
-
def compare_gem_version
|
284
|
-
latest_gem_contents = `gem list orats --remote`.split.last
|
285
|
-
|
286
|
-
if latest_gem_contents.include?('ERROR')
|
287
|
-
say_status 'error', "\e[1mError running `gem list orats --remote`:\e[0m", :red
|
288
|
-
say_status 'msg', 'Chances are their API is down, try again soon', :yellow
|
289
|
-
exit 1
|
290
|
-
end
|
291
|
-
|
292
|
-
latest_gem_version = "v#{latest_gem_contents.split.first[1...-1]}"
|
293
|
-
|
294
|
-
log_status 'gem', 'Comparing this version of orats to the latest orats version:', :green
|
295
|
-
log_status_under 'version', "Latest: #{latest_gem_version}, Yours: v#{VERSION}", :yellow
|
296
|
-
|
297
|
-
latest_gem_version
|
298
|
-
end
|
299
|
-
|
300
|
-
def compare_remote_role_version_to_local(remote_galaxy_contents)
|
301
|
-
remote_galaxy_list = remote_galaxy_contents.split
|
302
|
-
local_galaxy_contents = IO.read(galaxy_file_path)
|
303
|
-
local_galaxy_list = local_galaxy_contents.split
|
304
|
-
|
305
|
-
galaxy_difference = remote_galaxy_list - local_galaxy_list
|
306
|
-
|
307
|
-
local_role_count = local_galaxy_list.size
|
308
|
-
different_roles = galaxy_difference.size
|
309
|
-
|
310
|
-
log_status 'roles', "Comparing this version of orats' roles to the latest version:", :green
|
311
|
-
|
312
|
-
if different_roles == 0
|
313
|
-
log_status_under 'message', "All #{local_role_count} roles are up to date", :yellow
|
314
|
-
else
|
315
|
-
log_status_under 'message', "There are #{different_roles} differences", :yellow
|
316
|
-
|
317
|
-
galaxy_difference.each do |role_line|
|
318
|
-
name = role_line.split(',').first
|
319
|
-
status = 'outdated'
|
320
|
-
color = :yellow
|
321
|
-
|
322
|
-
unless local_galaxy_contents.include?(name)
|
323
|
-
status = 'missing'
|
324
|
-
color = :red
|
325
|
-
end
|
326
|
-
|
327
|
-
say_status status, name, color
|
328
|
-
end
|
329
|
-
|
330
|
-
log_results 'The latest version of orats may benefit you:', 'Check github to see if the changes interest you'
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
def compare_remote_to_local(label, keyword, remote_list, local_list)
|
335
|
-
list_difference = remote_list - local_list
|
336
|
-
|
337
|
-
remote_count = list_difference.size#log_unmatched remote_list, local_list, 'remote', :yellow
|
338
|
-
|
339
|
-
log_status label, "Comparing this version of orats' #{label} to the latest version:", :green
|
340
|
-
log_status_under 'file', label == 'playbook' ? 'site.yml' : 'all.yml', :yellow
|
341
|
-
|
342
|
-
list_difference.each do |line|
|
343
|
-
say_status 'missing', line, :red unless local_list.include?(line)
|
344
|
-
end
|
345
|
-
|
346
|
-
if remote_count > 0
|
347
|
-
log_results "#{remote_count} new #{keyword} are available:", 'You may benefit from upgrading to the latest orats'
|
348
|
-
else
|
349
|
-
log_results 'Everything appears to be in order:', "No missing #{keyword} were found"
|
350
|
-
end
|
351
|
-
|
352
|
-
local_list
|
353
|
-
end
|
354
|
-
|
355
|
-
def compare_user_to_local(label, keyword, user_path, local_list)
|
356
|
-
if File.exist?(user_path) && File.file?(user_path)
|
357
|
-
user_list = yield
|
358
|
-
|
359
|
-
just_file_name = user_path.split('/').last
|
360
|
-
|
361
|
-
log_status label, "Comparing this version of orats' #{label} to #{just_file_name}:", :blue
|
362
|
-
log_status_under 'path', user_path, :cyan
|
363
|
-
|
364
|
-
missing_count = log_unmatched local_list, user_list, 'missing', :red
|
365
|
-
extra_count = log_unmatched user_list, local_list, 'extra', :yellow
|
366
|
-
|
367
|
-
if missing_count > 0
|
368
|
-
log_results "#{missing_count} #{keyword} are missing:", "Your ansible run will likely fail with this #{label}"
|
369
|
-
else
|
370
|
-
log_results 'Everything appears to be in order:', "No missing #{keyword} were found"
|
371
|
-
end
|
372
|
-
|
373
|
-
if extra_count > 0
|
374
|
-
log_results "#{extra_count} extra #{keyword} were detected:", "No problem but remember to add them to a future #{keyword}"
|
375
|
-
else
|
376
|
-
log_results "No extra #{keyword} were found:", "Extra #{keyword} are fine but you have none"
|
377
|
-
end
|
378
|
-
else
|
379
|
-
log_status label, "Comparing this version of orats' #{label} to ???:", :blue
|
380
|
-
puts
|
381
|
-
say_status 'error', "\e[1mError comparing #{label}:\e[0m", :red
|
382
|
-
say_status 'path', user_path, :yellow
|
383
|
-
say_status 'help', 'Make sure you supply a file name', :white
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
def url_to_string(url)
|
388
|
-
begin
|
389
|
-
file_contents = open(url).read
|
390
|
-
rescue OpenURI::HTTPError => ex
|
391
|
-
say_status 'error', "\e[1mError browsing #{url}:\e[0m", :red
|
392
|
-
say_status 'msg', ex, :yellow
|
393
|
-
exit 1
|
394
|
-
end
|
395
|
-
|
396
|
-
file_contents
|
397
|
-
end
|
398
|
-
|
399
|
-
def log_unmatched(compare, against, label, color)
|
400
|
-
count = 0
|
401
|
-
|
402
|
-
compare.each do |item|
|
403
|
-
unless against.include?(item)
|
404
|
-
say_status label, item, color
|
405
|
-
count += 1
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
count
|
410
|
-
end
|
411
|
-
|
412
|
-
def create_rsa_certificate(secrets_path, keyout, out)
|
413
|
-
"openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -subj '/C=US/ST=Foo/L=Bar/O=Baz/CN=qux.com' -keyout #{secrets_path}/#{keyout} -out #{secrets_path}/#{out}"
|
414
|
-
end
|
415
|
-
|
416
|
-
def galaxy_file_path
|
417
|
-
"#{File.expand_path File.dirname(__FILE__)}/templates/includes/Galaxyfile"
|
418
|
-
end
|
419
|
-
|
420
|
-
def inventory_file_path
|
421
|
-
"#{File.expand_path File.dirname(__FILE__)}/templates/includes/inventory/group_vars/all.yml"
|
422
|
-
end
|
423
|
-
|
424
|
-
def playbook_file_path
|
425
|
-
"#{File.expand_path File.dirname(__FILE__)}/templates/play.rb"
|
426
|
-
end
|
427
|
-
|
428
|
-
def install_role_dependencies
|
429
|
-
log_message 'shell', 'Updating ansible roles from the galaxy'
|
430
|
-
|
431
|
-
galaxy_install = "ansible-galaxy install -r #{galaxy_file_path} --force"
|
432
|
-
galaxy_out = run(galaxy_install, capture: true)
|
433
|
-
|
434
|
-
if galaxy_out.include?('you do not have permission')
|
435
|
-
if @options[:sudo_password].empty?
|
436
|
-
sudo_galaxy_command = 'sudo'
|
437
|
-
else
|
438
|
-
sudo_galaxy_command = "echo #{@options[:sudo_password]} | sudo -S"
|
439
|
-
end
|
440
|
-
|
441
|
-
run("#{sudo_galaxy_command} #{galaxy_install}")
|
442
|
-
end
|
443
|
-
end
|
444
|
-
|
445
|
-
def save_secret_string(file)
|
446
|
-
File.open(file, 'w+') { |f| f.write(SecureRandom.hex(64)) }
|
447
|
-
end
|
448
|
-
|
449
|
-
def copy_from_includes(file, destination_root_path)
|
450
|
-
base_path = "#{File.expand_path File.dirname(__FILE__)}/templates/includes"
|
451
|
-
|
452
|
-
log_message 'shell', "Creating #{file}"
|
453
|
-
run "cp #{base_path}/#{file} #{destination_root_path}/#{file}"
|
454
|
-
end
|
455
|
-
|
456
|
-
def nuke_redis(namespace)
|
457
|
-
log_message 'root', 'Removing redis keys'
|
458
|
-
|
459
|
-
run "redis-cli KEYS '#{namespace}:*' | xargs --delim='\n' redis-cli DEL"
|
460
|
-
end
|
461
|
-
|
462
|
-
def nuke_directory
|
463
|
-
log_message 'root', 'Deleting directory'
|
464
|
-
|
465
|
-
run "rm -rf #{@active_path}"
|
466
|
-
end
|
467
|
-
|
468
|
-
def dependency_error(message, question, answer)
|
469
|
-
puts
|
470
|
-
say_status 'error', "\e[1m#{message}\e[0m", :red
|
471
|
-
say_status 'question', question, :yellow
|
472
|
-
say_status 'answer', answer, :cyan
|
473
|
-
puts '-'*80
|
474
|
-
puts
|
475
|
-
end
|
476
|
-
|
477
|
-
def exit_if_cannot_rails
|
478
|
-
log_message 'shell', 'Checking for rails'
|
479
|
-
|
480
|
-
has_rails = run('which rails', capture: true)
|
481
|
-
|
482
|
-
dependency_error 'Cannot access rails',
|
483
|
-
'Are you sure you have rails setup correctly?',
|
484
|
-
'You can install it by running `gem install rails`' if has_rails.empty?
|
485
|
-
|
486
|
-
exit 1 if has_rails.empty?
|
487
|
-
end
|
488
|
-
|
489
|
-
def exit_if_exists
|
490
|
-
log_message 'shell', 'Checking if a file or directory already exists'
|
491
|
-
|
492
|
-
if Dir.exist?(@active_path) || File.exist?(@active_path)
|
493
|
-
puts
|
494
|
-
say_status 'aborting', "\e[1mA file or directory already exists at this location:\e[0m", :red
|
495
|
-
say_status 'location', @active_path, :yellow
|
496
|
-
puts '-'*80
|
497
|
-
puts
|
498
|
-
|
499
|
-
exit 1
|
500
|
-
end
|
501
|
-
end
|
502
|
-
end
|
503
|
-
end
|