yadecli 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +172 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +13 -0
- data/bin/yadecli +10 -0
- data/config-example.yml +14 -0
- data/lib/.DS_Store +0 -0
- data/lib/yadecli/.DS_Store +0 -0
- data/lib/yadecli/cli/application.rb +40 -0
- data/lib/yadecli/cli/composer.rb +68 -0
- data/lib/yadecli/cli/host.rb +28 -0
- data/lib/yadecli/cli/module.rb +24 -0
- data/lib/yadecli/cli/project.rb +42 -0
- data/lib/yadecli/cli/task.rb +21 -0
- data/lib/yadecli/client/authentication_client.rb +24 -0
- data/lib/yadecli/client/base_client.rb +78 -0
- data/lib/yadecli/client/composer_container_client.rb +27 -0
- data/lib/yadecli/client/composer_project_client.rb +27 -0
- data/lib/yadecli/client/composer_service_client.rb +27 -0
- data/lib/yadecli/client/domain_client.rb +23 -0
- data/lib/yadecli/client/host_client.rb +45 -0
- data/lib/yadecli/client/maven_build_step_client.rb +23 -0
- data/lib/yadecli/client/maven_build_task_client.rb +23 -0
- data/lib/yadecli/client/nvm_runtime_client.rb +23 -0
- data/lib/yadecli/client/project_client.rb +28 -0
- data/lib/yadecli/client/project_module_client.rb +35 -0
- data/lib/yadecli/client/pyenv_runtime_client.rb +23 -0
- data/lib/yadecli/client/role_client.rb +23 -0
- data/lib/yadecli/client/rvm_runtime_client.rb +23 -0
- data/lib/yadecli/client/sdk_package_client.rb +28 -0
- data/lib/yadecli/client/vcs_client.rb +23 -0
- data/lib/yadecli/config/app_config.rb +69 -0
- data/lib/yadecli/io/user_input.rb +21 -0
- data/lib/yadecli/model/composer_container.rb +19 -0
- data/lib/yadecli/model/composer_project.rb +30 -0
- data/lib/yadecli/model/composer_service.rb +19 -0
- data/lib/yadecli/model/domain.rb +24 -0
- data/lib/yadecli/model/git_status.rb +8 -0
- data/lib/yadecli/model/host.rb +24 -0
- data/lib/yadecli/model/ide_type.rb +7 -0
- data/lib/yadecli/model/installation_status.rb +7 -0
- data/lib/yadecli/model/maven_build_step.rb +19 -0
- data/lib/yadecli/model/maven_build_task.rb +19 -0
- data/lib/yadecli/model/nvm_runtime.rb +18 -0
- data/lib/yadecli/model/project.rb +26 -0
- data/lib/yadecli/model/project_module.rb +29 -0
- data/lib/yadecli/model/pyenv_runtime.rb +18 -0
- data/lib/yadecli/model/role.rb +24 -0
- data/lib/yadecli/model/rvm_runtime.rb +18 -0
- data/lib/yadecli/model/sdk_package.rb +18 -0
- data/lib/yadecli/model/vcs.rb +19 -0
- data/lib/yadecli/service/authentication_service.rb +31 -0
- data/lib/yadecli/service/build_step_service.rb +24 -0
- data/lib/yadecli/service/build_task_service.rb +70 -0
- data/lib/yadecli/service/composer_service.rb +395 -0
- data/lib/yadecli/service/connect_service.rb +19 -0
- data/lib/yadecli/service/host_service.rb +191 -0
- data/lib/yadecli/service/module_service.rb +78 -0
- data/lib/yadecli/service/project_service.rb +198 -0
- data/lib/yadecli/util/cli_util.rb +22 -0
- data/lib/yadecli/util/file_util.rb +46 -0
- data/lib/yadecli/util/nvm_util.rb +14 -0
- data/lib/yadecli/util/pyenv_util.rb +14 -0
- data/lib/yadecli/util/rvm_util.rb +38 -0
- data/lib/yadecli/util/sdk_util.rb +23 -0
- data/lib/yadecli/util/system_util.rb +22 -0
- data/lib/yadecli/version.rb +3 -0
- data/lib/yadecli.rb +69 -0
- data/scripts/nvm-install-node.sh +6 -0
- data/scripts/rvm-gemset-import.sh +8 -0
- data/scripts/rvm-install-ruby.sh +6 -0
- data/scripts/sdk-install-candidate.sh +6 -0
- data/scripts/setup-terminal.sh +3 -0
- data/scripts/start-ide.sh +3 -0
- data/yadecli.gemspec +55 -0
- metadata +379 -0
@@ -0,0 +1,395 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
require 'tty-command'
|
5
|
+
require 'tty-prompt'
|
6
|
+
require 'tty-table'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'yaml'
|
9
|
+
require 'uri'
|
10
|
+
require 'dotenv'
|
11
|
+
|
12
|
+
# composer service
|
13
|
+
module Yadecli
|
14
|
+
module Service
|
15
|
+
class ComposerService
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@composer_project_client = Yadecli::Client::ComposerProjectClient.new
|
19
|
+
@composer_service_client = Yadecli::Client::ComposerServiceClient.new
|
20
|
+
@composer_container_client = Yadecli::Client::ComposerContainerClient.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
CliUtil.print_header('YadeCli Composer Setup',
|
25
|
+
['Answer the following questions to setup Composer on this host:', ''])
|
26
|
+
|
27
|
+
AppConfig[:git_username] = UserInput.ask(' * Gitlab Username?', :git_username)
|
28
|
+
AppConfig[:git_password] = UserInput.ask(' * Gitlab Password?', :git_password)
|
29
|
+
AppConfig[:git_token] = UserInput.ask(' * Gitlab Api Token?', :git_token)
|
30
|
+
AppConfig[:docker_registry_url] = UserInput.ask(' * Docker Registry Url?', :docker_registry_url)
|
31
|
+
AppConfig[:docker_registry_username] = UserInput.ask(' * Docker Registry Username?', :docker_registry_username)
|
32
|
+
AppConfig[:docker_registry_password] = UserInput.ask(' * Docker Registry Password?', :docker_registry_password)
|
33
|
+
|
34
|
+
AppConfig.write!
|
35
|
+
end
|
36
|
+
|
37
|
+
# list composer projects from gitlab
|
38
|
+
def list
|
39
|
+
CliUtil.print_header('YadeCli Composer List',
|
40
|
+
['This are the available Yade composer projects you can install', ''])
|
41
|
+
|
42
|
+
composer_projects = @composer_project_client.list
|
43
|
+
|
44
|
+
# print table
|
45
|
+
table = TTY::Table.new header: ['Id', 'Name', 'Services', 'Installed', 'Branch', 'Git Url']
|
46
|
+
|
47
|
+
# add as rows to table
|
48
|
+
composer_projects.each do |p|
|
49
|
+
project_id = p.id
|
50
|
+
project_name = p.name
|
51
|
+
project_installed = p.installed?
|
52
|
+
|
53
|
+
composer_services = @composer_service_client.get_by_composer_project_id(project_id)
|
54
|
+
service_names = composer_services.collect(&:name).join(', ')
|
55
|
+
if project_installed
|
56
|
+
branch_name = FileUtil.git_current_branch(p.install_dir)
|
57
|
+
else
|
58
|
+
branch_name = '-'
|
59
|
+
end
|
60
|
+
|
61
|
+
table << [project_id, project_name, service_names , project_installed, branch_name, p.gitUrl]
|
62
|
+
end
|
63
|
+
|
64
|
+
renderer = TTY::Table::Renderer::ASCII.new(table, padding: [0, 1])
|
65
|
+
puts renderer.render
|
66
|
+
|
67
|
+
puts ''
|
68
|
+
puts 'You can install any of the listed project with the following command:'
|
69
|
+
puts ''
|
70
|
+
puts ' bin/yadecli composer install <name> <branch> [--pull] [--setup] [--clean]'.colorize(:mode => :bold)
|
71
|
+
puts ''
|
72
|
+
end
|
73
|
+
|
74
|
+
# install composer project with name
|
75
|
+
def install(name, options)
|
76
|
+
CliUtil.print_header('YadeCli Composer Install',
|
77
|
+
["Going to install Yade composer project #{name}", ''])
|
78
|
+
|
79
|
+
composer_project = @composer_project_client.get_by_name(name)
|
80
|
+
|
81
|
+
# # delete already installed when option --clean given
|
82
|
+
# uninstall(options, true) if options[:clean]
|
83
|
+
|
84
|
+
# # truncate log file
|
85
|
+
# File.open(@log_file, 'w') { |file| file.truncate(0) }
|
86
|
+
|
87
|
+
# check preconditions
|
88
|
+
check_install_preconditions(options)
|
89
|
+
|
90
|
+
# check already installed
|
91
|
+
already_installed = composer_project.installed?
|
92
|
+
|
93
|
+
# ask for branch if not given from commandline
|
94
|
+
# @branch = UserInput.select_branch(composer_project) if @branch == nil || (@name.nil? && !already_installed)
|
95
|
+
|
96
|
+
if already_installed
|
97
|
+
puts "Composer project #{name} already installed.".colorize(color: :blue, mode: :bold)
|
98
|
+
puts ' ↳ Doing a git pull.'
|
99
|
+
|
100
|
+
pull_repository(composer_project, options)
|
101
|
+
else
|
102
|
+
puts "Composer project #{name} will be installed.".colorize(color: :blue, mode: :bold)
|
103
|
+
puts ' ↳ Doing a git clone.'
|
104
|
+
|
105
|
+
clone_repository(composer_project)
|
106
|
+
end
|
107
|
+
|
108
|
+
puts ''
|
109
|
+
if already_installed
|
110
|
+
puts " Successfully updated '#{composer_project.name}' at #{composer_project.install_dir}."
|
111
|
+
else
|
112
|
+
puts " Successfully installed '#{composer_project.name}' to #{composer_project.install_dir}."
|
113
|
+
end
|
114
|
+
|
115
|
+
composer_services = @composer_service_client.get_by_composer_project_id(composer_project.id)
|
116
|
+
service_names = composer_services.collect(&:name).join(' | ')
|
117
|
+
|
118
|
+
puts ''
|
119
|
+
puts ' Use the following commands to manage the service(s)'
|
120
|
+
puts " Start : bin/yadecli composer start #{composer_project.name} #{service_names}"
|
121
|
+
puts " Stop : bin/yadecli composer stop #{composer_project.name} #{service_names}"
|
122
|
+
|
123
|
+
pull_container(composer_project) if options[:pull]
|
124
|
+
|
125
|
+
# if options[:setup]
|
126
|
+
# if SystemUtil.os == :linux
|
127
|
+
# setup_services
|
128
|
+
# else
|
129
|
+
# puts ''
|
130
|
+
# puts 'WARNING: Setting up services on systems other then linux is not supported.'.colorize(:yellow)
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
end
|
134
|
+
|
135
|
+
# switch to branch
|
136
|
+
def switch(project_name, target_branch, options)
|
137
|
+
CliUtil.print_header('Composer Switch',
|
138
|
+
["Going to switch branch of composer project #{project_name} to #{target_branch}", ''])
|
139
|
+
|
140
|
+
composer_project = @composer_project_client.get_by_name(project_name)
|
141
|
+
|
142
|
+
message = "Switching to branch #{target_branch}"
|
143
|
+
message += ' and pull changes' if options[:pull]
|
144
|
+
|
145
|
+
print message
|
146
|
+
|
147
|
+
cmdline = "git fetch && git checkout -B #{target_branch}"
|
148
|
+
cmdline += " && git pull origin #{target_branch}" if options[:pull]
|
149
|
+
|
150
|
+
begin
|
151
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
152
|
+
|
153
|
+
cmd.run(cmdline, chdir: composer_project.install_dir)
|
154
|
+
|
155
|
+
puts ' done'.colorize(:green)
|
156
|
+
rescue TTY::Command::ExitError => e
|
157
|
+
puts ' failed'.colorize(:red)
|
158
|
+
puts e
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# uninstall a composer project
|
163
|
+
def uninstall(name, options, suppress_header = false)
|
164
|
+
CliUtil.print_header('YadeCli Composer Uninstall',
|
165
|
+
["Going to uninstall composer project #{name}", '']) unless suppress_header
|
166
|
+
|
167
|
+
composer_project = @composer_project_client.get_by_name(name)
|
168
|
+
|
169
|
+
# unless CliUtil.check_root
|
170
|
+
# puts ''
|
171
|
+
# puts 'ERROR: The composer uninstall must run with sudo.'.colorize(:red)
|
172
|
+
# exit 2
|
173
|
+
# end
|
174
|
+
|
175
|
+
answer = false
|
176
|
+
unless options[:yes]
|
177
|
+
prompt = TTY::Prompt.new
|
178
|
+
answer = prompt.yes?("Do you really want to uninstall the #{composer_project.name} composer project?".colorize(:mode => :bold))
|
179
|
+
end
|
180
|
+
|
181
|
+
if options[:yes] || answer
|
182
|
+
FileUtils.rm_rf(composer_project.install_dir)
|
183
|
+
# FileUtils.rm_f("/etc/systemd/system/#{@name}.service")
|
184
|
+
else
|
185
|
+
puts 'There is nothing more I can do for you. Bye.'
|
186
|
+
exit(1)
|
187
|
+
end
|
188
|
+
|
189
|
+
puts ''
|
190
|
+
puts 'Composer project successfully uninstalled'.colorize(:color => :green, :mode => :bold)
|
191
|
+
puts ''
|
192
|
+
end
|
193
|
+
|
194
|
+
# starts the composer service with the given name
|
195
|
+
def start_service(project_name, service_name)
|
196
|
+
CliUtil.print_header('YadeCli Composer Start',
|
197
|
+
['Going to start composer service:',
|
198
|
+
" ↳ Composer Project : #{project_name}",
|
199
|
+
" ↳ Service Name : #{service_name}"])
|
200
|
+
|
201
|
+
begin
|
202
|
+
composer_project = @composer_project_client.get_by_name(project_name)
|
203
|
+
composer_services = @composer_service_client.get_by_composer_project_id(composer_project.id)
|
204
|
+
|
205
|
+
# load project dotenv
|
206
|
+
dotenv_file = "#{composer_project.install_dir}/.env"
|
207
|
+
Dotenv.load(dotenv_file)
|
208
|
+
|
209
|
+
# check required envs are set fom .env file or system environment variables
|
210
|
+
|
211
|
+
composer_service = composer_services.select { |s| s.name == service_name }.first
|
212
|
+
|
213
|
+
composer_service.requiredEnvs&.split(',').each do |re|
|
214
|
+
if ENV[re] == nil
|
215
|
+
puts ''
|
216
|
+
puts "Unable to start service. Required environment variable #{re} is not set.".colorize(:red)
|
217
|
+
puts "Either specify the variable and a value in #{dotenv_file} or as a system environment variable an try to run again.".colorize(:red)
|
218
|
+
|
219
|
+
exit 1
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
composer_containers = @composer_container_client.get_by_composer_service_id(composer_service.id)
|
224
|
+
|
225
|
+
cmdline = "docker-compose up -d #{composer_containers.map(&:name).join(' ')}"
|
226
|
+
|
227
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
228
|
+
|
229
|
+
puts ''
|
230
|
+
print "Executing command '#{cmdline}'... "
|
231
|
+
|
232
|
+
cmd.run(cmdline, chdir: composer_project.install_dir)
|
233
|
+
|
234
|
+
puts 'done'.colorize(:green)
|
235
|
+
rescue TTY::Command::ExitError => e
|
236
|
+
puts 'failed'.colorize(:red)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# stops the composer service with the given name
|
241
|
+
def stop_service(project_name, service_name, options)
|
242
|
+
CliUtil.print_header('Composer Service Stop',['Going to stop composer service:',
|
243
|
+
" ↳ Composer Project : #{project_name}",
|
244
|
+
" ↳ Service Name : #{service_name}"])
|
245
|
+
|
246
|
+
begin
|
247
|
+
composer_project = @composer_project_client.get_by_name(project_name)
|
248
|
+
composer_services = @composer_service_client.get_by_composer_project_id(composer_project.id)
|
249
|
+
|
250
|
+
composer_service = composer_services.select { |s| s.name == service_name }.first
|
251
|
+
|
252
|
+
composer_containers = @composer_container_client.get_by_composer_service_id(composer_service.id)
|
253
|
+
|
254
|
+
container_names = composer_containers.map(&:name).join(' ')
|
255
|
+
|
256
|
+
cmdline = "docker-compose stop #{container_names}"
|
257
|
+
cmdline += " && docker-compose rm -f #{container_names}" if options[:rm]
|
258
|
+
cmdline += ' && docker-compose down -v' if options[:down]
|
259
|
+
|
260
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
261
|
+
|
262
|
+
puts ''
|
263
|
+
print "Executing command '#{cmdline}'... "
|
264
|
+
|
265
|
+
cmd.run(cmdline, chdir: composer_project.install_dir)
|
266
|
+
|
267
|
+
puts 'done'.colorize(:green)
|
268
|
+
rescue TTY::Command::ExitError => e
|
269
|
+
puts 'failed'.colorize(:red)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# log the containers output of the composer service with the given name
|
274
|
+
def log_service(project_name, service_name, options)
|
275
|
+
CliUtil.print_header('Composer Service Log',["Going to show logs for composer service #{service_name}.",
|
276
|
+
'Hit ctrl + c to stopp when you use the -f option'])
|
277
|
+
|
278
|
+
sleep 1
|
279
|
+
|
280
|
+
composer_project = @composer_project_client.get_by_name(project_name)
|
281
|
+
composer_services = @composer_service_client.get_by_composer_project_id(composer_project.id)
|
282
|
+
|
283
|
+
composer_service = composer_services.select { |s| s.name == service_name }.first
|
284
|
+
|
285
|
+
composer_containers = @composer_container_client.get_by_composer_service_id(composer_service.id)
|
286
|
+
|
287
|
+
container_names = composer_containers.map(&:name).join(' ')
|
288
|
+
|
289
|
+
begin
|
290
|
+
cmdline = 'docker-compose logs'
|
291
|
+
cmdline += ' -f' if options[:follow]
|
292
|
+
cmdline += " #{container_names}"
|
293
|
+
|
294
|
+
cmd = TTY::Command.new(uuid: false)
|
295
|
+
|
296
|
+
cmd.run(cmdline, chdir: install_dir)
|
297
|
+
rescue TTY::Command::ExitError => e
|
298
|
+
puts e
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
private
|
303
|
+
|
304
|
+
# pull container
|
305
|
+
def pull_container(composer_project)
|
306
|
+
# make shure we are logged in to the docker registry
|
307
|
+
docker_login
|
308
|
+
|
309
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
310
|
+
|
311
|
+
puts ''
|
312
|
+
puts 'Pulling docker images:'.colorize(color: :blue)
|
313
|
+
|
314
|
+
doco = YAML.load_file("#{composer_project.install_dir}/docker-compose.yml")
|
315
|
+
|
316
|
+
has_failed_pulls = false
|
317
|
+
doco['services'].each do |k, v|
|
318
|
+
cmdline = "docker-compose pull #{k}"
|
319
|
+
|
320
|
+
print " ↳ #{cmdline}... "
|
321
|
+
begin
|
322
|
+
cmd.run(cmdline, chdir: composer_project.install_dir)
|
323
|
+
|
324
|
+
puts 'done'.colorize(:green)
|
325
|
+
rescue TTY::Command::ExitError => e
|
326
|
+
puts 'failed'.colorize(:red)
|
327
|
+
has_failed_pulls = true
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
puts ''
|
332
|
+
puts 'Successfully pulled all docker containers.'.colorize(:green) unless has_failed_pulls
|
333
|
+
puts "Failed to pull for at least on container. See log at #{Dir.pwd}/composer.log".colorize(:red) if has_failed_pulls
|
334
|
+
puts ''
|
335
|
+
end
|
336
|
+
|
337
|
+
# docker login
|
338
|
+
def docker_login
|
339
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
340
|
+
|
341
|
+
cmdline = "docker login #{AppConfig[:docker_registry_url]} -u #{AppConfig[:docker_registry_username]} -p #{AppConfig[:docker_registry_password]}"
|
342
|
+
|
343
|
+
cmd.run(cmdline, only_output_on_error: true)
|
344
|
+
end
|
345
|
+
|
346
|
+
# clone repository
|
347
|
+
def clone_repository(composer_project)
|
348
|
+
username = AppConfig[:git_username]
|
349
|
+
password = AppConfig[:git_password]
|
350
|
+
|
351
|
+
git_url = URI.parse(composer_project.gitUrl)
|
352
|
+
|
353
|
+
scheme = git_url.scheme
|
354
|
+
host = git_url.host
|
355
|
+
path = git_url.path
|
356
|
+
|
357
|
+
url_with_auth = "#{scheme}://#{username}:#{password}@#{host}#{path}"
|
358
|
+
|
359
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
360
|
+
cmdline = "git clone --depth=1 #{url_with_auth} #{composer_project.install_dir}"
|
361
|
+
|
362
|
+
cmd.run(cmdline, only_output_on_error: true)
|
363
|
+
end
|
364
|
+
|
365
|
+
# pull repository
|
366
|
+
def pull_repository(composer_project, options)
|
367
|
+
if options[:yes]
|
368
|
+
answer = true
|
369
|
+
else
|
370
|
+
puts ''
|
371
|
+
answer = TTY::Prompt.new.yes?('Do you want to pull the changes for the repository?')
|
372
|
+
end
|
373
|
+
|
374
|
+
if answer
|
375
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
376
|
+
cmd.run('git pull', only_output_on_error: true, chdir: composer_project.install_dir)
|
377
|
+
else
|
378
|
+
puts 'There is nothing more I can do for you. Bye.'
|
379
|
+
exit(1)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
# check install preconditions
|
384
|
+
def check_install_preconditions(options)
|
385
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
386
|
+
|
387
|
+
cmd.run('test -x /usr/bin/docker') if SystemUtil.os == 'linux'
|
388
|
+
cmd.run('test -x /usr/local/bin/docker') if SystemUtil.os == 'macosx'
|
389
|
+
|
390
|
+
cmd.run('test -x /usr/local/bin/docker-compose')
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# yadecli cli
|
4
|
+
module Yadecli
|
5
|
+
module Service
|
6
|
+
|
7
|
+
# connect
|
8
|
+
class ConnectService
|
9
|
+
def connect(url)
|
10
|
+
CliUtil.print_header('Yade Connect',
|
11
|
+
["Going to connect to yade backend at #{url}", ''])
|
12
|
+
|
13
|
+
AppConfig[:url] = url
|
14
|
+
|
15
|
+
AppConfig.write!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tty-table'
|
4
|
+
require 'net/ssh'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
# yadecli cli
|
8
|
+
module Yadecli
|
9
|
+
module Service
|
10
|
+
|
11
|
+
# host service
|
12
|
+
class HostService
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@host_client = Yadecli::Client::HostClient.new
|
16
|
+
@domain_client = Yadecli::Client::DomainClient.new
|
17
|
+
@role_client = Yadecli::Client::RoleClient.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# list the available hosts
|
21
|
+
def list
|
22
|
+
CliUtil.print_header'Yade List Hosts', ['This are the available hosts', '']
|
23
|
+
|
24
|
+
hosts = @host_client.list
|
25
|
+
|
26
|
+
table = TTY::Table.new header: ['Name', 'Domain', 'Role', 'Ip', 'OsType', 'Environment']
|
27
|
+
|
28
|
+
hosts.each do |h|
|
29
|
+
domain_id = h.domainId
|
30
|
+
domain = @domain_client.get(domain_id)
|
31
|
+
|
32
|
+
role_id = h.roleId
|
33
|
+
role = @role_client.get(role_id)
|
34
|
+
|
35
|
+
table << [h.name, domain.name, role.name, h.ip, h.osType, h.environmentType]
|
36
|
+
end
|
37
|
+
|
38
|
+
puts table.render(:ascii, width: 100, resize: true, padding: [0, 1])
|
39
|
+
puts ''
|
40
|
+
end
|
41
|
+
|
42
|
+
# bootstrap a host
|
43
|
+
def bootstrap(host_fqdn, options)
|
44
|
+
CliUtil.print_header'Yade bootstrap Host',
|
45
|
+
["Going to bootstrap Yade host #{host_fqdn}", '']
|
46
|
+
|
47
|
+
master_host = @host_client.master
|
48
|
+
host = @host_client.host_by_fqdn(host_fqdn)
|
49
|
+
|
50
|
+
domain_id = host.domainId
|
51
|
+
domain = @domain_client.get(domain_id)
|
52
|
+
|
53
|
+
role_id = host.roleId
|
54
|
+
role = @role_client.get(role_id)
|
55
|
+
|
56
|
+
username = 'administrator'
|
57
|
+
port = 22
|
58
|
+
|
59
|
+
Net::SSH.start(host.hostName, username, port: port) do |ssh|
|
60
|
+
checkout_dir = "/home/#{username}/.yade"
|
61
|
+
local_repo = "#{checkout_dir}/yade-puppet-bootstrap"
|
62
|
+
|
63
|
+
# clone or update
|
64
|
+
output = ssh.exec!("mkdir -p #{checkout_dir}")
|
65
|
+
puts output if options[:verbose]
|
66
|
+
|
67
|
+
output = ssh.exec!("git clone -b test --depth 1 https://gitlab.com/yadedev/yade-puppet-bootstrap.git #{local_repo} || (cd #{local_repo} ; git pull)")
|
68
|
+
puts output if options[:verbose]
|
69
|
+
|
70
|
+
# setup
|
71
|
+
if options[:setup]
|
72
|
+
output = ssh.exec!("mkdir -p #{local_repo}")
|
73
|
+
puts output if options[:verbose]
|
74
|
+
|
75
|
+
output = ssh.exec!("sudo #{local_repo}/scripts/ubuntu/setup-managed-host.sh #{host.hostName} #{domain.name} #{host.ip}")
|
76
|
+
puts output if options[:verbose]
|
77
|
+
|
78
|
+
output = ssh.exec!("sudo #{local_repo}/scripts/ubuntu/local-bootstrap.sh \"mc nano\"")
|
79
|
+
puts output if options[:verbose]
|
80
|
+
|
81
|
+
output = ssh.exec!("sudo #{local_repo}/scripts/ubuntu/puppet-install.sh")
|
82
|
+
puts output if options[:verbose]
|
83
|
+
|
84
|
+
# noinspection RubyLiteralArrayInspection
|
85
|
+
modules = {
|
86
|
+
'puppetlabs/ntp': '7.1.1',
|
87
|
+
'saz/timezone': '4.1.1',
|
88
|
+
'cjtoolseram/puppetconf': '0.2.7',
|
89
|
+
'puppetlabs/puppet_authorization': '0.4.0',
|
90
|
+
'puppetlabs/puppetdb': '7.0.1',
|
91
|
+
'puppetlabs-puppetserver_gem': '1.0.0',
|
92
|
+
'puppet-r10k': '6.6.1',
|
93
|
+
'abrader-gms': '1.0.3',
|
94
|
+
'theforeman-puppet': '9.1.0',
|
95
|
+
#'theforeman-foreman': '9.2.0'
|
96
|
+
}
|
97
|
+
|
98
|
+
FileUtils.rm_rf 'modules'
|
99
|
+
FileUtils.mkdir_p 'modules'
|
100
|
+
|
101
|
+
modules.each do |mod, version|
|
102
|
+
cmd = "puppet module install --modulepath #{local_repo}/modules --version #{version} #{mod}"
|
103
|
+
|
104
|
+
output = ssh.exec!(cmd)
|
105
|
+
puts output if options[:verbose]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# provision
|
110
|
+
cmd_a = [
|
111
|
+
'FACTER_vagrant=1',
|
112
|
+
"FACTER_host_ip=#{host.ip}",
|
113
|
+
"FACTER_host_name=#{host.hostName}",
|
114
|
+
"FACTER_host_domain=#{domain.name}",
|
115
|
+
"FACTER_master_ip=#{master_host.ip}",
|
116
|
+
"FACTER_master_host_name=#{master_host.hostName}",
|
117
|
+
"FACTER_role=#{role.name}",
|
118
|
+
"FACTER_datacenter=#{host.datacenter}",
|
119
|
+
"FACTER_zone=#{host.zone}",
|
120
|
+
"FACTER_is_master=#{host.isMaster}",
|
121
|
+
"FACTER_username=#{username}",
|
122
|
+
'sudo --preserve-env puppet apply',
|
123
|
+
"--hiera_config=#{local_repo}/config/hiera.yml",
|
124
|
+
"--modulepath=#{local_repo}/modules:#{local_repo}/dist",
|
125
|
+
"#{local_repo}/environments/production/manifests/default.pp"
|
126
|
+
]
|
127
|
+
|
128
|
+
cmd_line = cmd_a.join(' ')
|
129
|
+
|
130
|
+
puts cmd_line if options[:verbose]
|
131
|
+
|
132
|
+
channel = ssh.open_channel do |ch|
|
133
|
+
ch.exec cmd_line do |ch, success|
|
134
|
+
raise "could not execute command" unless success
|
135
|
+
|
136
|
+
# "on_data" is called when the process writes something to stdout
|
137
|
+
ch.on_data do |c, data|
|
138
|
+
$stdout.print data if options[:verbose]
|
139
|
+
end
|
140
|
+
|
141
|
+
# "on_extended_data" is called when the process writes something to stderr
|
142
|
+
ch.on_extended_data do |c, type, data|
|
143
|
+
$stderr.print data if options[:verbose]
|
144
|
+
end
|
145
|
+
|
146
|
+
ch.on_close { puts "done!" }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
channel.wait
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# provision a host
|
155
|
+
def provision(host_fqdn, options)
|
156
|
+
CliUtil.print_header'Yade provision Host',
|
157
|
+
["Going to provision Yade host #{host_fqdn}", '']
|
158
|
+
|
159
|
+
host = @host_client.host_by_fqdn(host_fqdn)
|
160
|
+
|
161
|
+
username = 'administrator'
|
162
|
+
port = 22
|
163
|
+
|
164
|
+
Net::SSH.start(host.hostName, username, port: port) do |ssh|
|
165
|
+
# clone or update
|
166
|
+
cmd_line = "sudo puppet agent -t --environment=#{host.environmentType.downcase}"
|
167
|
+
|
168
|
+
channel = ssh.open_channel do |ch|
|
169
|
+
ch.exec cmd_line do |ch, success|
|
170
|
+
raise "could not execute command" unless success
|
171
|
+
|
172
|
+
# "on_data" is called when the process writes something to stdout
|
173
|
+
ch.on_data do |c, data|
|
174
|
+
$stdout.print data if options[:verbose]
|
175
|
+
end
|
176
|
+
|
177
|
+
# "on_extended_data" is called when the process writes something to stderr
|
178
|
+
ch.on_extended_data do |c, type, data|
|
179
|
+
$stderr.print data if options[:verbose]
|
180
|
+
end
|
181
|
+
|
182
|
+
ch.on_close { puts "done!" }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
channel.wait
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tty-table'
|
4
|
+
|
5
|
+
# yadecli cli
|
6
|
+
module Yadecli
|
7
|
+
module Service
|
8
|
+
|
9
|
+
# module service
|
10
|
+
class ModuleService
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@project_client = Yadecli::Client::ProjectClient.new
|
14
|
+
@module_client = Yadecli::Client::ProjectModuleClient.new
|
15
|
+
@vcs_client = Yadecli::Client::VcsClient.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# list the available modules for the project
|
19
|
+
def list(project_name)
|
20
|
+
CliUtil.print_header'YadeCli List Modules', ["This are the available modules for the Yade project #{project_name}", '']
|
21
|
+
|
22
|
+
project = @project_client.project_by_name(project_name)
|
23
|
+
|
24
|
+
puts "Project: #{project.name}".colorize(:mode => :bold)
|
25
|
+
|
26
|
+
project_modules = @module_client.modules_for_project(project.id)
|
27
|
+
|
28
|
+
rows = []
|
29
|
+
project_modules.each do |m|
|
30
|
+
module_name = m.name
|
31
|
+
is_installed = m.installed?
|
32
|
+
git_status = '-'
|
33
|
+
git_status = FileUtil.git_status(m.home) if is_installed
|
34
|
+
rows << [module_name, is_installed, git_status]
|
35
|
+
end
|
36
|
+
table = TTY::Table.new header: ['Module name', 'Installed', 'Git Status'], rows: rows
|
37
|
+
puts table.render(:ascii, padding: [0, 1])
|
38
|
+
puts ''
|
39
|
+
|
40
|
+
# puts "You can run 'yadecli module install <project_name> <module_name>' to install the module to the project src directory"
|
41
|
+
# puts ''
|
42
|
+
end
|
43
|
+
|
44
|
+
# install the module of a project
|
45
|
+
def install(project_name, module_name, options)
|
46
|
+
CliUtil.print_header'YadeCli Install Module',
|
47
|
+
["Going to install module #{module_name} for Yade project #{project_name}", '']
|
48
|
+
|
49
|
+
project = @project_client.project_by_name(project_name)
|
50
|
+
project_module = @module_client.module_for_project(project.id, module_name)
|
51
|
+
vcs = @vcs_client.get(project_module.vcsId)
|
52
|
+
|
53
|
+
if project_module.installed?
|
54
|
+
puts "The module with name #{module_name} is already installed"
|
55
|
+
|
56
|
+
if options[:yes]
|
57
|
+
do_update = true
|
58
|
+
else
|
59
|
+
puts ''
|
60
|
+
prompt = TTY::Prompt.new
|
61
|
+
do_update = prompt.yes?('Do you want to pull the changes for the project? ')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
cmd = TTY::Command.new(output: Yadecli.LOGGER)
|
66
|
+
|
67
|
+
if do_update
|
68
|
+
cmd_line = 'git pull'
|
69
|
+
cmd.run(cmd_line, chdir: project_module.home)
|
70
|
+
else
|
71
|
+
cmd_line = "git clone #{vcs.url} #{project_module.home}"
|
72
|
+
cmd.run(cmd_line)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|