kuber_kit 0.1.4 → 0.1.9

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -2
  3. data/README.md +16 -3
  4. data/TODO.md +4 -4
  5. data/example/app_data/env_file.yml +10 -0
  6. data/example/configurations/review.rb +2 -1
  7. data/example/images/app_sources/Dockerfile +1 -1
  8. data/example/images/ruby_app/image.rb +4 -4
  9. data/example/infrastructure/build_servers.rb +8 -0
  10. data/example/infrastructure/templates.rb +5 -0
  11. data/example/services/env_file.rb +6 -0
  12. data/kuber_kit.gemspec +1 -0
  13. data/lib/kuber_kit.rb +50 -23
  14. data/lib/kuber_kit/actions/configuration_loader.rb +5 -0
  15. data/lib/kuber_kit/actions/env_file_reader.rb +8 -5
  16. data/lib/kuber_kit/actions/image_compiler.rb +18 -22
  17. data/lib/kuber_kit/actions/kubectl_applier.rb +6 -1
  18. data/lib/kuber_kit/actions/service_deployer.rb +13 -3
  19. data/lib/kuber_kit/actions/service_reader.rb +9 -6
  20. data/lib/kuber_kit/actions/template_reader.rb +5 -0
  21. data/lib/kuber_kit/cli.rb +12 -6
  22. data/lib/kuber_kit/configs.rb +24 -22
  23. data/lib/kuber_kit/container.rb +39 -19
  24. data/lib/kuber_kit/core/artifacts/artifact_store.rb +12 -23
  25. data/lib/kuber_kit/core/build_servers/abstract_build_server.rb +21 -0
  26. data/lib/kuber_kit/core/build_servers/build_server.rb +24 -0
  27. data/lib/kuber_kit/core/build_servers/build_server_store.rb +18 -0
  28. data/lib/kuber_kit/core/configuration.rb +14 -4
  29. data/lib/kuber_kit/core/configuration_definition.rb +22 -1
  30. data/lib/kuber_kit/core/configuration_factory.rb +11 -1
  31. data/lib/kuber_kit/core/configuration_store.rb +14 -24
  32. data/lib/kuber_kit/core/context_helper/base_helper.rb +12 -7
  33. data/lib/kuber_kit/core/context_helper/context_helper_factory.rb +11 -8
  34. data/lib/kuber_kit/core/context_helper/service_helper.rb +9 -4
  35. data/lib/kuber_kit/core/env_files/env_file_store.rb +8 -23
  36. data/lib/kuber_kit/core/image_store.rb +8 -18
  37. data/lib/kuber_kit/core/registries/registry_store.rb +8 -23
  38. data/lib/kuber_kit/core/service.rb +19 -3
  39. data/lib/kuber_kit/core/service_definition.rb +7 -0
  40. data/lib/kuber_kit/core/service_factory.rb +5 -1
  41. data/lib/kuber_kit/core/service_store.rb +13 -23
  42. data/lib/kuber_kit/core/store.rb +48 -0
  43. data/lib/kuber_kit/core/templates/template_store.rb +12 -23
  44. data/lib/kuber_kit/env_file_reader/action_handler.rb +12 -0
  45. data/lib/kuber_kit/env_file_reader/reader.rb +4 -4
  46. data/lib/kuber_kit/env_file_reader/{abstract_env_file_reader.rb → strategies/abstract.rb} +1 -1
  47. data/lib/kuber_kit/env_file_reader/{artifact_file_reader.rb → strategies/artifact_file.rb} +1 -1
  48. data/lib/kuber_kit/image_compiler/action_handler.rb +21 -0
  49. data/lib/kuber_kit/image_compiler/build_server_pool.rb +30 -0
  50. data/lib/kuber_kit/image_compiler/build_server_pool_factory.rb +13 -0
  51. data/lib/kuber_kit/image_compiler/compiler.rb +2 -5
  52. data/lib/kuber_kit/image_compiler/image_build_dir_creator.rb +13 -7
  53. data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +25 -5
  54. data/lib/kuber_kit/preprocessing/file_preprocessor.rb +5 -4
  55. data/lib/kuber_kit/preprocessing/text_preprocessor.rb +1 -1
  56. data/lib/kuber_kit/service_deployer/action_handler.rb +16 -0
  57. data/lib/kuber_kit/service_deployer/deployer.rb +28 -6
  58. data/lib/kuber_kit/service_deployer/strategies/abstract.rb +1 -1
  59. data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +9 -4
  60. data/lib/kuber_kit/service_deployer/strategy_detector.rb +6 -0
  61. data/lib/kuber_kit/service_reader/action_handler.rb +13 -0
  62. data/lib/kuber_kit/{service_deployer/service_reader.rb → service_reader/reader.rb} +1 -1
  63. data/lib/kuber_kit/shell/abstract_shell.rb +4 -0
  64. data/lib/kuber_kit/shell/{bash_commands.rb → commands/bash_commands.rb} +1 -1
  65. data/lib/kuber_kit/shell/{docker_commands.rb → commands/docker_commands.rb} +1 -1
  66. data/lib/kuber_kit/shell/{git_commands.rb → commands/git_commands.rb} +1 -1
  67. data/lib/kuber_kit/shell/{kubectl_commands.rb → commands/kubectl_commands.rb} +1 -1
  68. data/lib/kuber_kit/shell/{rsync_commands.rb → commands/rsync_commands.rb} +9 -3
  69. data/lib/kuber_kit/shell/local_shell.rb +24 -5
  70. data/lib/kuber_kit/shell/ssh_session.rb +60 -0
  71. data/lib/kuber_kit/shell/ssh_shell.rb +77 -0
  72. data/lib/kuber_kit/tools/file_presence_checker.rb +6 -2
  73. data/lib/kuber_kit/version.rb +1 -1
  74. metadata +40 -13
  75. data/lib/kuber_kit/preprocessing/dir_preprocessor.rb +0 -19
  76. data/lib/kuber_kit/service_deployer/service_restarter.rb +0 -37
  77. data/lib/kuber_kit/tools/files_sync.rb +0 -10
@@ -0,0 +1,6 @@
1
+ class KuberKit::ServiceDeployer::StrategyDetector
2
+ Contract KuberKit::Core::Service => Symbol
3
+ def call(service)
4
+ KuberKit.current_configuration.deploy_strategy
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ class KuberKit::ServiceReader::ActionHandler
2
+ include KuberKit::Import[
3
+ "service_reader.reader",
4
+ "core.service_store",
5
+ ]
6
+
7
+ Contract KuberKit::Shell::AbstractShell, Symbol => Any
8
+ def call(shell, service_name)
9
+ service = service_store.get_service(service_name)
10
+
11
+ reader.read(shell, service)
12
+ end
13
+ end
@@ -1,4 +1,4 @@
1
- class KuberKit::ServiceDeployer::ServiceReader
1
+ class KuberKit::ServiceReader::Reader
2
2
  include KuberKit::Import[
3
3
  "core.template_store",
4
4
  "core.context_helper_factory",
@@ -17,4 +17,8 @@ class KuberKit::Shell::AbstractShell
17
17
  def recursive_list_files(path, name: nil)
18
18
  raise KuberKit::NotImplementedError, "must be implemented"
19
19
  end
20
+
21
+ def sync(local_path, remote_path, exclude: nil)
22
+ raise KuberKit::NotImplementedError, "must be implemented"
23
+ end
20
24
  end
@@ -1,4 +1,4 @@
1
- class KuberKit::Shell::BashCommands
1
+ class KuberKit::Shell::Commands::BashCommands
2
2
  def rm(shell, path)
3
3
  shell.exec!(%Q{rm "#{path}"})
4
4
  end
@@ -1,4 +1,4 @@
1
- class KuberKit::Shell::DockerCommands
1
+ class KuberKit::Shell::Commands::DockerCommands
2
2
  def build(shell, build_dir, args = [])
3
3
  default_args = ["--rm=true"]
4
4
  args_list = (default_args + args).join(" ")
@@ -1,4 +1,4 @@
1
- class KuberKit::Shell::GitCommands
1
+ class KuberKit::Shell::Commands::GitCommands
2
2
  def get_remote_url(shell, git_repo_path, remote_name: "origin")
3
3
  shell.exec! [
4
4
  "cd #{git_repo_path}",
@@ -1,7 +1,7 @@
1
1
  require 'json'
2
2
  require 'shellwords'
3
3
 
4
- class KuberKit::Shell::KubectlCommands
4
+ class KuberKit::Shell::Commands::KubectlCommands
5
5
  def apply_file(shell, file_path, kubeconfig_path: nil)
6
6
  command_parts = []
7
7
  if kubeconfig_path
@@ -1,11 +1,17 @@
1
- class KuberKit::Shell::RsyncCommands
2
- def rsync(shell, source_path, target_path, exclude: nil)
1
+ class KuberKit::Shell::Commands::RsyncCommands
2
+ def rsync(shell, source_path, target_path, target_host: nil, exclude: nil)
3
3
  # Add a trailing slash to directory to have behavior similar to CP command
4
4
  if path_is_directory?(source_path) && !source_path.end_with?("/")
5
5
  source_path = "#{source_path}/"
6
6
  end
7
7
 
8
- args = [source_path, target_path]
8
+ if target_host
9
+ destination = "#{target_host}:#{target_path}"
10
+ else
11
+ destination = target_path
12
+ end
13
+
14
+ args = [source_path, destination]
9
15
  if exclude
10
16
  args << "--exclude=#{exclude}"
11
17
  end
@@ -3,21 +3,24 @@ require 'fileutils'
3
3
  class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
4
4
  include KuberKit::Import[
5
5
  "tools.logger",
6
- "shell.command_counter"
6
+ "shell.command_counter",
7
+ "shell.rsync_commands",
7
8
  ]
8
9
 
9
- def exec!(command)
10
+ def exec!(command, log_command: true)
10
11
  command_number = command_counter.get_number.to_s.rjust(2, "0")
11
12
 
12
- logger.info("Executed command [#{command_number}]: #{command.to_s.cyan}")
13
+ if log_command
14
+ logger.info("Execute: [#{command_number}]: #{command.to_s.cyan}")
15
+ end
13
16
 
14
17
  result = nil
15
18
  IO.popen(command, err: [:child, :out]) do |io|
16
19
  result = io.read.chomp.strip
17
20
  end
18
21
 
19
- if result && result != ""
20
- logger.info("Finished command [#{command_number}] with result: \n#{result.grey}")
22
+ if result && result != "" && log_command
23
+ logger.info("Finished [#{command_number}] with result: \n#{result.grey}")
21
24
  end
22
25
 
23
26
  if $?.exitstatus != 0
@@ -27,6 +30,10 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
27
30
  result
28
31
  end
29
32
 
33
+ def sync(local_path, remote_path, exclude: nil)
34
+ rsync_commands.rsync(self, local_path, remote_path, exclude: exclude)
35
+ end
36
+
30
37
  def read(file_path)
31
38
  File.read(file_path)
32
39
  end
@@ -41,6 +48,18 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
41
48
  true
42
49
  end
43
50
 
51
+ def delete(file_path)
52
+ exec!("rm #{file_path}")
53
+ end
54
+
55
+ def file_exists?(file_path)
56
+ exec!("test -f #{file_path} && echo 'true' || echo 'false'", log_command: false) == 'true'
57
+ end
58
+
59
+ def dir_exists?(dir_path)
60
+ exec!("test -d #{dir_path} && echo 'true' || echo 'false'", log_command: false) == 'true'
61
+ end
62
+
44
63
  def recursive_list_files(path, name: nil)
45
64
  command = %Q{find -L #{path} -type f}
46
65
  command += " -name #{name}" if name
@@ -0,0 +1,60 @@
1
+ require 'net/ssh'
2
+
3
+ class KuberKit::Shell::SshSession
4
+ SshSessionError = Class.new(KuberKit::Error)
5
+
6
+ attr_reader :session, :host, :user, :port
7
+
8
+ def initialize(host:, user:, port:)
9
+ @host = host
10
+ @user = user
11
+ @port = port
12
+ @session = Net::SSH.start(host, user, {port: port})
13
+ end
14
+
15
+ def connected?
16
+ !!@session
17
+ end
18
+
19
+ def disconnect
20
+ return unless connected?
21
+ @session.close
22
+ @session = nil
23
+ end
24
+
25
+ def exec!(command)
26
+ stdout_data = ''
27
+ stderr_data = ''
28
+ exit_code = nil
29
+ channel = session.open_channel do |ch|
30
+ ch.exec(command) do |ch, success|
31
+ if !success
32
+ raise SshSessionError, "Shell command failed: #{command}\r\n#{stdout_data}\r\n#{stderr_data}"
33
+ end
34
+
35
+ channel.on_data do |ch,data|
36
+ stdout_data += data
37
+ end
38
+
39
+ channel.on_extended_data do |ch,type,data|
40
+ stderr_data += data
41
+ end
42
+
43
+ channel.on_request('exit-status') do |ch,data|
44
+ exit_code = data.read_long
45
+ end
46
+ end
47
+ end
48
+
49
+ channel.wait
50
+ session.loop
51
+
52
+ stdout_data = stdout_data.chomp.strip
53
+
54
+ if exit_code != 0
55
+ raise SshSessionError, "Shell command failed: #{command}\r\n#{stdout_data}\r\n#{stderr_data}"
56
+ end
57
+
58
+ stdout_data
59
+ end
60
+ end
@@ -0,0 +1,77 @@
1
+ require 'tempfile'
2
+
3
+ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell
4
+ include KuberKit::Import[
5
+ "tools.logger",
6
+ "shell.command_counter",
7
+ "shell.rsync_commands",
8
+ "shell.local_shell"
9
+ ]
10
+
11
+ def connect(host:, user:, port:)
12
+ @ssh_session = KuberKit::Shell::SshSession.new(host: host, user: user, port: port)
13
+ end
14
+
15
+ def connected?
16
+ @ssh_session && @ssh_session.connected?
17
+ end
18
+
19
+ def disconnect
20
+ @ssh_session.disconnect if @ssh_session
21
+ end
22
+
23
+ def exec!(command, log_command: true)
24
+ command_number = command_counter.get_number.to_s.rjust(2, "0")
25
+
26
+ if log_command
27
+ logger.info("#{ssh_session.host.green} > Execute: [#{command_number}]: #{command.to_s.cyan}")
28
+ end
29
+
30
+ result = ssh_session.exec!(command)
31
+
32
+ if result && result != "" && log_command
33
+ logger.info("#{ssh_session.host.green} > Finished [#{command_number}] with result: \n#{result.grey}")
34
+ end
35
+
36
+ result
37
+ rescue KuberKit::Shell::SshSession::SshSessionError => e
38
+ raise ShellError.new(e.message)
39
+ end
40
+
41
+ def sync(local_path, remote_path, exclude: nil)
42
+ rsync_commands.rsync(
43
+ local_shell, local_path, remote_path,
44
+ target_host: "#{ssh_session.user}@#{ssh_session.host}",
45
+ exclude: exclude
46
+ )
47
+ end
48
+
49
+ def read(file_path)
50
+ exec!("cat #{file_path}")
51
+ end
52
+
53
+ def write(file_path, content)
54
+ Tempfile.create do |file|
55
+ file << content
56
+ file.flush
57
+ sync(file.path, file_path)
58
+ end
59
+
60
+ logger.info("Created file #{file_path.to_s.cyan}\r\n#{content.grey}")
61
+
62
+ true
63
+ end
64
+
65
+ private
66
+ def ssh_session
67
+ unless connected?
68
+ raise ArgumentError, "ssh session is not created, please call #connect"
69
+ end
70
+
71
+ @ssh_session
72
+ end
73
+
74
+ def ensure_directory_exists(file_path)
75
+ exec!("mkdir -p #{file_path}")
76
+ end
77
+ end
@@ -1,6 +1,10 @@
1
1
  class KuberKit::Tools::FilePresenceChecker
2
2
  FileNotFound = Class.new(KuberKit::Error)
3
3
 
4
+ include KuberKit::Import[
5
+ "shell.local_shell"
6
+ ]
7
+
4
8
  def check_file!(file_path)
5
9
  unless file_exists?(file_path)
6
10
  raise FileNotFound, "File not found at path: #{file_path}"
@@ -9,7 +13,7 @@ class KuberKit::Tools::FilePresenceChecker
9
13
  end
10
14
 
11
15
  def file_exists?(file_path)
12
- File.exists?(file_path)
16
+ local_shell.file_exists?(file_path)
13
17
  end
14
18
 
15
19
  def check_dir!(dir_path)
@@ -20,6 +24,6 @@ class KuberKit::Tools::FilePresenceChecker
20
24
  end
21
25
 
22
26
  def dir_exists?(dir_path)
23
- Dir.exists?(dir_path)
27
+ local_shell.dir_exists?(dir_path)
24
28
  end
25
29
  end
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kuber_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Khaziev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-30 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts-lite
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-ssh
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -144,6 +158,7 @@ files:
144
158
  - TODO.md
145
159
  - bin/console
146
160
  - bin/kit
161
+ - example/app_data/env_file.yml
147
162
  - example/app_data/service.yml
148
163
  - example/app_data/test.env
149
164
  - example/app_data/test.txt
@@ -160,9 +175,11 @@ files:
160
175
  - example/images/ruby_app2/build_context/example_file.txt
161
176
  - example/images/ruby_app2/image.rb
162
177
  - example/infrastructure/artifacts.rb
178
+ - example/infrastructure/build_servers.rb
163
179
  - example/infrastructure/env_files.rb
164
180
  - example/infrastructure/registries.rb
165
181
  - example/infrastructure/templates.rb
182
+ - example/services/env_file.rb
166
183
  - example/services/ruby_app.rb
167
184
  - kuber_kit.gemspec
168
185
  - lib/kuber_kit.rb
@@ -184,6 +201,9 @@ files:
184
201
  - lib/kuber_kit/core/artifacts/artifact_store.rb
185
202
  - lib/kuber_kit/core/artifacts/git.rb
186
203
  - lib/kuber_kit/core/artifacts/local.rb
204
+ - lib/kuber_kit/core/build_servers/abstract_build_server.rb
205
+ - lib/kuber_kit/core/build_servers/build_server.rb
206
+ - lib/kuber_kit/core/build_servers/build_server_store.rb
187
207
  - lib/kuber_kit/core/configuration.rb
188
208
  - lib/kuber_kit/core/configuration_definition.rb
189
209
  - lib/kuber_kit/core/configuration_definition_factory.rb
@@ -209,43 +229,50 @@ files:
209
229
  - lib/kuber_kit/core/service_definition_factory.rb
210
230
  - lib/kuber_kit/core/service_factory.rb
211
231
  - lib/kuber_kit/core/service_store.rb
232
+ - lib/kuber_kit/core/store.rb
212
233
  - lib/kuber_kit/core/templates/abstract_template.rb
213
234
  - lib/kuber_kit/core/templates/artifact_file.rb
214
235
  - lib/kuber_kit/core/templates/template_store.rb
215
- - lib/kuber_kit/env_file_reader/abstract_env_file_reader.rb
216
- - lib/kuber_kit/env_file_reader/artifact_file_reader.rb
236
+ - lib/kuber_kit/env_file_reader/action_handler.rb
217
237
  - lib/kuber_kit/env_file_reader/reader.rb
238
+ - lib/kuber_kit/env_file_reader/strategies/abstract.rb
239
+ - lib/kuber_kit/env_file_reader/strategies/artifact_file.rb
218
240
  - lib/kuber_kit/extensions/colored_string.rb
219
241
  - lib/kuber_kit/extensions/contracts.rb
220
242
  - lib/kuber_kit/extensions/indocker_compat.rb
221
243
  - lib/kuber_kit/extensions/inspectable.rb
244
+ - lib/kuber_kit/image_compiler/action_handler.rb
245
+ - lib/kuber_kit/image_compiler/build_server_pool.rb
246
+ - lib/kuber_kit/image_compiler/build_server_pool_factory.rb
222
247
  - lib/kuber_kit/image_compiler/compiler.rb
223
248
  - lib/kuber_kit/image_compiler/image_build_dir_creator.rb
224
249
  - lib/kuber_kit/image_compiler/image_builder.rb
225
250
  - lib/kuber_kit/image_compiler/image_dependency_resolver.rb
226
251
  - lib/kuber_kit/image_compiler/version_tag_builder.rb
227
- - lib/kuber_kit/preprocessing/dir_preprocessor.rb
228
252
  - lib/kuber_kit/preprocessing/file_preprocessor.rb
229
253
  - lib/kuber_kit/preprocessing/text_preprocessor.rb
254
+ - lib/kuber_kit/service_deployer/action_handler.rb
230
255
  - lib/kuber_kit/service_deployer/deployer.rb
231
256
  - lib/kuber_kit/service_deployer/service_list_resolver.rb
232
- - lib/kuber_kit/service_deployer/service_reader.rb
233
- - lib/kuber_kit/service_deployer/service_restarter.rb
234
257
  - lib/kuber_kit/service_deployer/strategies/abstract.rb
235
258
  - lib/kuber_kit/service_deployer/strategies/kubernetes.rb
259
+ - lib/kuber_kit/service_deployer/strategy_detector.rb
260
+ - lib/kuber_kit/service_reader/action_handler.rb
261
+ - lib/kuber_kit/service_reader/reader.rb
236
262
  - lib/kuber_kit/shell/abstract_shell.rb
237
- - lib/kuber_kit/shell/bash_commands.rb
238
263
  - lib/kuber_kit/shell/command_counter.rb
239
- - lib/kuber_kit/shell/docker_commands.rb
240
- - lib/kuber_kit/shell/git_commands.rb
241
- - lib/kuber_kit/shell/kubectl_commands.rb
264
+ - lib/kuber_kit/shell/commands/bash_commands.rb
265
+ - lib/kuber_kit/shell/commands/docker_commands.rb
266
+ - lib/kuber_kit/shell/commands/git_commands.rb
267
+ - lib/kuber_kit/shell/commands/kubectl_commands.rb
268
+ - lib/kuber_kit/shell/commands/rsync_commands.rb
242
269
  - lib/kuber_kit/shell/local_shell.rb
243
- - lib/kuber_kit/shell/rsync_commands.rb
270
+ - lib/kuber_kit/shell/ssh_session.rb
271
+ - lib/kuber_kit/shell/ssh_shell.rb
244
272
  - lib/kuber_kit/template_reader/abstract_template_reader.rb
245
273
  - lib/kuber_kit/template_reader/artifact_file_reader.rb
246
274
  - lib/kuber_kit/template_reader/reader.rb
247
275
  - lib/kuber_kit/tools/file_presence_checker.rb
248
- - lib/kuber_kit/tools/files_sync.rb
249
276
  - lib/kuber_kit/tools/logger_factory.rb
250
277
  - lib/kuber_kit/ui.rb
251
278
  - lib/kuber_kit/ui/interactive.rb