kuber_kit 0.4.0 → 0.4.5
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/Gemfile.lock +17 -3
- data/TODO.md +2 -4
- data/example/configurations/review.rb +1 -0
- data/kuber_kit.gemspec +1 -0
- data/lib/kuber_kit.rb +9 -0
- data/lib/kuber_kit/actions/configuration_loader.rb +20 -19
- data/lib/kuber_kit/actions/image_compiler.rb +2 -0
- data/lib/kuber_kit/actions/kubectl_describe.rb +56 -0
- data/lib/kuber_kit/actions/service_deployer.rb +35 -16
- data/lib/kuber_kit/cli.rb +29 -11
- data/lib/kuber_kit/container.rb +4 -0
- data/lib/kuber_kit/core/configuration.rb +28 -24
- data/lib/kuber_kit/core/configuration_definition.rb +17 -10
- data/lib/kuber_kit/core/configuration_factory.rb +11 -9
- data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +3 -1
- data/lib/kuber_kit/service_deployer/service_list_resolver.rb +11 -4
- data/lib/kuber_kit/service_deployer/strategies/docker.rb +24 -7
- data/lib/kuber_kit/service_deployer/strategies/docker_compose.rb +4 -4
- data/lib/kuber_kit/shell/commands/docker_commands.rb +46 -6
- data/lib/kuber_kit/shell/commands/kubectl_commands.rb +11 -10
- data/lib/kuber_kit/ui/interactive.rb +5 -11
- data/lib/kuber_kit/ui/simple.rb +2 -3
- data/lib/kuber_kit/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dfc1d29b7283361acaed01c9ddd08a29d121020c75af2d6ec7e4245d347021fb
|
|
4
|
+
data.tar.gz: 7e9063497954963223629beaa6d6ec914851c5e8c9633fa35d50986a95149aec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0dd8904d21b8ca6648111856a6a5d8b4b3d1950a5db786f108f2906bdfc2388c6f515b4d833ce87f30f3c5098ebd1807aa0e3ef832903a4bec180b66788f3dc
|
|
7
|
+
data.tar.gz: b9cb8446b31460a27571b8a91defbf7882ff0ecf1d8d97dd581edaa496d2f60dae58b4bd8bd6fad091c5448a16830cee48259821751211e4e6751d2128d88fe2
|
data/Gemfile.lock
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
kuber_kit (0.4.
|
|
4
|
+
kuber_kit (0.4.5)
|
|
5
5
|
cli-ui
|
|
6
6
|
contracts-lite
|
|
7
7
|
dry-auto_inject
|
|
8
8
|
net-ssh
|
|
9
9
|
thor
|
|
10
|
+
tty-prompt
|
|
10
11
|
|
|
11
12
|
GEM
|
|
12
13
|
remote: https://rubygems.org/
|
|
13
14
|
specs:
|
|
14
15
|
cli-ui (1.4.0)
|
|
15
16
|
coderay (1.1.3)
|
|
16
|
-
concurrent-ruby (1.1.
|
|
17
|
+
concurrent-ruby (1.1.8)
|
|
17
18
|
contracts-lite (0.15.0)
|
|
18
19
|
diff-lcs (1.4.4)
|
|
19
20
|
docile (1.3.2)
|
|
@@ -29,6 +30,8 @@ GEM
|
|
|
29
30
|
concurrent-ruby (~> 1.0)
|
|
30
31
|
method_source (1.0.0)
|
|
31
32
|
net-ssh (6.1.0)
|
|
33
|
+
pastel (0.8.0)
|
|
34
|
+
tty-color (~> 0.5)
|
|
32
35
|
pry (0.13.1)
|
|
33
36
|
coderay (~> 1.1)
|
|
34
37
|
method_source (~> 1.0)
|
|
@@ -52,7 +55,18 @@ GEM
|
|
|
52
55
|
simplecov_json_formatter (~> 0.1)
|
|
53
56
|
simplecov-html (0.12.3)
|
|
54
57
|
simplecov_json_formatter (0.1.2)
|
|
55
|
-
thor (1.0
|
|
58
|
+
thor (1.1.0)
|
|
59
|
+
tty-color (0.6.0)
|
|
60
|
+
tty-cursor (0.7.1)
|
|
61
|
+
tty-prompt (0.23.0)
|
|
62
|
+
pastel (~> 0.8)
|
|
63
|
+
tty-reader (~> 0.8)
|
|
64
|
+
tty-reader (0.9.0)
|
|
65
|
+
tty-cursor (~> 0.7)
|
|
66
|
+
tty-screen (~> 0.8)
|
|
67
|
+
wisper (~> 2.0)
|
|
68
|
+
tty-screen (0.8.1)
|
|
69
|
+
wisper (2.0.1)
|
|
56
70
|
|
|
57
71
|
PLATFORMS
|
|
58
72
|
ruby
|
data/TODO.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
-
|
|
1
|
+
- add kit get method for interactive kubernetes
|
|
2
|
+
- do not show result for images list, if list is too large
|
|
2
3
|
- kit status should show the list of services and their status, with ability to select & view logs
|
|
3
|
-
- list services and require confirmation before deployment
|
|
4
|
-
- add kit logs support, should work similar to kit attach
|
|
5
|
-
- allow deploying only services enabled for specific configuration
|
|
6
4
|
- find a way to always deploy some service, e.g. for migrations and env_files
|
|
7
5
|
- template should be able to set default attributes
|
|
8
6
|
- template should be able to depend on image?
|
data/kuber_kit.gemspec
CHANGED
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.add_dependency "thor"
|
|
29
29
|
spec.add_dependency "cli-ui"
|
|
30
30
|
spec.add_dependency "net-ssh"
|
|
31
|
+
spec.add_dependency "tty-prompt"
|
|
31
32
|
|
|
32
33
|
spec.add_development_dependency "bundler", "~> 1.17"
|
|
33
34
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/kuber_kit.rb
CHANGED
|
@@ -167,6 +167,7 @@ module KuberKit
|
|
|
167
167
|
autoload :KubectlApplier, 'actions/kubectl_applier'
|
|
168
168
|
autoload :KubectlAttacher, 'actions/kubectl_attacher'
|
|
169
169
|
autoload :KubectlConsole, 'actions/kubectl_console'
|
|
170
|
+
autoload :KubectlDescribe, 'actions/kubectl_describe'
|
|
170
171
|
autoload :KubectlLogs, 'actions/kubectl_logs'
|
|
171
172
|
end
|
|
172
173
|
|
|
@@ -254,6 +255,14 @@ module KuberKit
|
|
|
254
255
|
KuberKit::Core::ContextHelper::BaseHelper.class_exec(&proc)
|
|
255
256
|
end
|
|
256
257
|
|
|
258
|
+
def user
|
|
259
|
+
@user ||= ENV["KUBER_KIT_USERNAME"] || `whoami`.chomp
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def user_id
|
|
263
|
+
@user_id ||= `id -u #{user}`.chomp
|
|
264
|
+
end
|
|
265
|
+
|
|
257
266
|
def configure(&proc)
|
|
258
267
|
yield(Container["configs"])
|
|
259
268
|
end
|
|
@@ -17,7 +17,8 @@ class KuberKit::Actions::ConfigurationLoader
|
|
|
17
17
|
services_path = options[:services_path] || File.join(root_path, configs.services_dirname)
|
|
18
18
|
infra_path = options[:infra_path] || File.join(root_path, configs.infra_dirname)
|
|
19
19
|
configurations_path = options[:configurations_path] || File.join(root_path, configs.configurations_dirname)
|
|
20
|
-
configuration_name =
|
|
20
|
+
configuration_name = options[:configuration] || ENV["KUBER_KIT_CONFIGURATION"]
|
|
21
|
+
load_inventory = options.fetch(:load_inventory, true)
|
|
21
22
|
|
|
22
23
|
ui.print_debug "ConfigurationLoader", "Launching kuber_kit with:"
|
|
23
24
|
ui.print_debug "ConfigurationLoader", " Root path: #{root_path.to_s.yellow}"
|
|
@@ -40,25 +41,27 @@ class KuberKit::Actions::ConfigurationLoader
|
|
|
40
41
|
load_configurations(configurations_path, configuration_name)
|
|
41
42
|
load_infrastructure(infra_path)
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
artifacts
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
if load_inventory
|
|
45
|
+
ui.create_task("Updating artifacts") do |task|
|
|
46
|
+
artifacts = KuberKit.current_configuration.artifacts.values
|
|
47
|
+
artifacts_updater.update(local_shell, artifacts)
|
|
48
|
+
task.update_title("Updated #{artifacts.count} artifacts")
|
|
49
|
+
end
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
ui.create_task("Loading image definitions") do |task|
|
|
52
|
+
files = image_store.load_definitions(images_path)
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
configs.additional_images_paths.each do |path|
|
|
55
|
+
files += image_store.load_definitions(path)
|
|
56
|
+
end
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
task.update_title("Loaded #{files.count} image definitions")
|
|
59
|
+
end
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
ui.create_task("Loading service definitions") do |task|
|
|
62
|
+
files = service_store.load_definitions(services_path)
|
|
63
|
+
task.update_title("Loaded #{files.count} service definitions")
|
|
64
|
+
end
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
true
|
|
@@ -84,9 +87,7 @@ class KuberKit::Actions::ConfigurationLoader
|
|
|
84
87
|
|
|
85
88
|
if configuration_store.count > 1 && configuration_name.nil?
|
|
86
89
|
options = all_configurations.map(&:configuration_name).map(&:to_s)
|
|
87
|
-
ui.prompt("Please select configuration name (or set it using -C option)", options)
|
|
88
|
-
configuration_name = selection
|
|
89
|
-
end
|
|
90
|
+
configuration_name = ui.prompt("Please select configuration name (or set it using -C option)", options)
|
|
90
91
|
end
|
|
91
92
|
|
|
92
93
|
KuberKit.set_configuration_name(configuration_name)
|
|
@@ -3,6 +3,7 @@ class KuberKit::Actions::ImageCompiler
|
|
|
3
3
|
"image_compiler.image_dependency_resolver",
|
|
4
4
|
"image_compiler.build_server_pool_factory",
|
|
5
5
|
"shell.local_shell",
|
|
6
|
+
"configs",
|
|
6
7
|
"ui",
|
|
7
8
|
image_compiler: "image_compiler.action_handler",
|
|
8
9
|
]
|
|
@@ -15,6 +16,7 @@ class KuberKit::Actions::ImageCompiler
|
|
|
15
16
|
compiled_images = []
|
|
16
17
|
compilation_result = {}
|
|
17
18
|
image_dependency_resolver.each_with_deps(image_names) do |dep_image_names|
|
|
19
|
+
ui.print_debug("ImageCompiler", "Scheduling to compile: #{dep_image_names.inspect}. Limit: #{configs.compile_simultaneous_limit}")
|
|
18
20
|
result = compile_simultaneously(dep_image_names, build_id, build_server_pool)
|
|
19
21
|
compiled_images += dep_image_names
|
|
20
22
|
compilation_result = compilation_result.merge(result)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class KuberKit::Actions::KubectlDescribe
|
|
2
|
+
include KuberKit::Import[
|
|
3
|
+
"shell.kubectl_commands",
|
|
4
|
+
"shell.local_shell",
|
|
5
|
+
"ui"
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
Contract Maybe[String], Hash => Any
|
|
9
|
+
def call(resource_name, options)
|
|
10
|
+
kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
|
|
11
|
+
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
|
12
|
+
|
|
13
|
+
if !resource_name
|
|
14
|
+
resource_name = get_resource_name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
args = nil
|
|
18
|
+
if options[:follow]
|
|
19
|
+
args = "-f"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
kubectl_commands.describe(
|
|
23
|
+
local_shell, resource_name,
|
|
24
|
+
args: args,
|
|
25
|
+
kubeconfig_path: kubeconfig_path,
|
|
26
|
+
namespace: deployer_namespace
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
true
|
|
30
|
+
rescue KuberKit::Error => e
|
|
31
|
+
ui.print_error("Error", e.message)
|
|
32
|
+
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_resource_name
|
|
37
|
+
deployments = kubectl_commands.get_resources(local_shell, "deployments", jsonpath: ".items[*].metadata.name")
|
|
38
|
+
options = deployments.split(" ").map{|d| "deploy/#{d}" }
|
|
39
|
+
options += ["ingresses", "pods"]
|
|
40
|
+
option = ui.prompt("Please select resource to describe", options)
|
|
41
|
+
|
|
42
|
+
if option == "ingresses"
|
|
43
|
+
ingresses = kubectl_commands.get_resources(local_shell, "ingresses", jsonpath: ".items[*].metadata.name")
|
|
44
|
+
options = ingresses.split(" ").map{|d| "ingresses/#{d}" }
|
|
45
|
+
return ui.prompt("Please select ingress to describe", options)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if option == "pods"
|
|
49
|
+
ingresses = kubectl_commands.get_resources(local_shell, "pods", jsonpath: ".items[*].metadata.name")
|
|
50
|
+
options = ingresses.split(" ").map{|d| "pods/#{d}" }
|
|
51
|
+
return ui.prompt("Please select pod to describe", options)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
option
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -9,22 +9,33 @@ class KuberKit::Actions::ServiceDeployer
|
|
|
9
9
|
]
|
|
10
10
|
|
|
11
11
|
Contract KeywordArgs[
|
|
12
|
-
services:
|
|
13
|
-
tags:
|
|
14
|
-
skip_compile:
|
|
12
|
+
services: Maybe[ArrayOf[String]],
|
|
13
|
+
tags: Maybe[ArrayOf[String]],
|
|
14
|
+
skip_compile: Maybe[Bool],
|
|
15
|
+
require_confirmation: Maybe[Bool],
|
|
15
16
|
] => Any
|
|
16
|
-
def call(services:, tags:, skip_compile: false)
|
|
17
|
+
def call(services:, tags:, skip_compile: false, require_confirmation: false)
|
|
17
18
|
if services.empty? && tags.empty?
|
|
18
19
|
services, tags = show_tags_selection
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
service_names = service_list_resolver.resolve(
|
|
22
|
-
services:
|
|
23
|
-
tags:
|
|
23
|
+
services: services || [],
|
|
24
|
+
tags: tags || [],
|
|
25
|
+
enabled_services: KuberKit.current_configuration.enabled_services.map(&:to_s)
|
|
24
26
|
)
|
|
25
27
|
|
|
26
28
|
unless service_names.any?
|
|
27
29
|
ui.print_warning "ServiceDeployer", "No service found with given options, nothing will be deployed."
|
|
30
|
+
return false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
services_list = service_names.map(&:to_s).map(&:yellow).join(", ")
|
|
34
|
+
ui.print_info "ServiceDeployer", "The following services will be deployed: #{services_list}"
|
|
35
|
+
|
|
36
|
+
if require_confirmation
|
|
37
|
+
result = ui.prompt("Please confirm to continue deployment", ["confirm".green, "cancel".red])
|
|
38
|
+
return false unless ["confirm".green, "confirm", "yes"].include?(result)
|
|
28
39
|
end
|
|
29
40
|
|
|
30
41
|
services = service_names.map do |service_name|
|
|
@@ -33,7 +44,11 @@ class KuberKit::Actions::ServiceDeployer
|
|
|
33
44
|
|
|
34
45
|
images_names = services.map(&:images).flatten.uniq
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
unless skip_compile
|
|
48
|
+
compile_result = compile_images(images_names)
|
|
49
|
+
return false unless compile_result
|
|
50
|
+
end
|
|
51
|
+
|
|
37
52
|
deployment_result = deploy_services(service_names)
|
|
38
53
|
|
|
39
54
|
{ services: service_names, deployment: deployment_result }
|
|
@@ -65,7 +80,8 @@ class KuberKit::Actions::ServiceDeployer
|
|
|
65
80
|
end
|
|
66
81
|
|
|
67
82
|
def compile_images(images_names)
|
|
68
|
-
|
|
83
|
+
return true if images_names.empty?
|
|
84
|
+
image_compiler.call(images_names, {})
|
|
69
85
|
end
|
|
70
86
|
|
|
71
87
|
def show_tags_selection()
|
|
@@ -82,12 +98,12 @@ class KuberKit::Actions::ServiceDeployer
|
|
|
82
98
|
.sort
|
|
83
99
|
.map(&:to_s)
|
|
84
100
|
|
|
85
|
-
ui.prompt("Please select which tag to deploy", tags)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
selected_tag = ui.prompt("Please select which tag to deploy", tags)
|
|
102
|
+
|
|
103
|
+
if selected_tag == specific_service_option
|
|
104
|
+
show_service_selection
|
|
105
|
+
else
|
|
106
|
+
[[], [selected_tag]]
|
|
91
107
|
end
|
|
92
108
|
end
|
|
93
109
|
|
|
@@ -100,8 +116,11 @@ class KuberKit::Actions::ServiceDeployer
|
|
|
100
116
|
.sort
|
|
101
117
|
.map(&:to_s)
|
|
102
118
|
|
|
103
|
-
|
|
104
|
-
return [[
|
|
119
|
+
if services.empty?
|
|
120
|
+
return [[], []]
|
|
105
121
|
end
|
|
122
|
+
|
|
123
|
+
selected_service = ui.prompt("Please select which service to deploy", services)
|
|
124
|
+
[[selected_service], []]
|
|
106
125
|
end
|
|
107
126
|
end
|
data/lib/kuber_kit/cli.rb
CHANGED
|
@@ -15,6 +15,7 @@ class KuberKit::CLI < Thor
|
|
|
15
15
|
def compile(image_names_str)
|
|
16
16
|
setup(options)
|
|
17
17
|
|
|
18
|
+
started_at = Time.now.to_i
|
|
18
19
|
image_names = image_names_str.split(",").map(&:strip).map(&:to_sym)
|
|
19
20
|
|
|
20
21
|
if KuberKit::Container['actions.configuration_loader'].call(options)
|
|
@@ -22,29 +23,37 @@ class KuberKit::CLI < Thor
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
if result
|
|
25
|
-
|
|
26
|
+
time = (Time.now.to_i - started_at)
|
|
27
|
+
print_result("Image compilation finished! (#{time}s)", result: result)
|
|
26
28
|
else
|
|
27
29
|
exit 1
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
desc "deploy CONTEXT_NAME", "Deploy CONTEXT_NAME with kubectl"
|
|
32
|
-
method_option :services,
|
|
33
|
-
method_option :tags,
|
|
34
|
-
method_option :skip_compile,
|
|
33
|
+
desc "deploy -t CONTEXT_NAME", "Deploy CONTEXT_NAME with kubectl"
|
|
34
|
+
method_option :services, :type => :array, aliases: ["-s"], repeatable: true
|
|
35
|
+
method_option :tags, :type => :array, aliases: ["-t"], repeatable: true
|
|
36
|
+
method_option :skip_compile, :type => :boolean, aliases: ["-B"]
|
|
37
|
+
method_option :require_confirmation, :type => :boolean, aliases: ["-r"]
|
|
35
38
|
def deploy
|
|
36
39
|
setup(options)
|
|
37
40
|
|
|
38
41
|
if KuberKit::Container['actions.configuration_loader'].call(options)
|
|
42
|
+
require_confirmation = options[:require_confirmation] ||
|
|
43
|
+
KuberKit.current_configuration.deployer_require_confirimation ||
|
|
44
|
+
false
|
|
45
|
+
started_at = Time.now.to_i
|
|
39
46
|
result = KuberKit::Container['actions.service_deployer'].call(
|
|
40
|
-
services:
|
|
41
|
-
tags:
|
|
42
|
-
skip_compile:
|
|
47
|
+
services: (options[:services] || []).flatten.uniq,
|
|
48
|
+
tags: (options[:tags] || []).flatten.uniq,
|
|
49
|
+
skip_compile: options[:skip_compile] || false,
|
|
50
|
+
require_confirmation: require_confirmation
|
|
43
51
|
)
|
|
44
52
|
end
|
|
45
53
|
|
|
46
54
|
if result
|
|
47
|
-
|
|
55
|
+
time = (Time.now.to_i - started_at)
|
|
56
|
+
print_result("Service deployment finished! (#{time}s)", result: result)
|
|
48
57
|
else
|
|
49
58
|
exit 1
|
|
50
59
|
end
|
|
@@ -99,7 +108,7 @@ class KuberKit::CLI < Thor
|
|
|
99
108
|
def console(pod_name = nil)
|
|
100
109
|
setup(options)
|
|
101
110
|
|
|
102
|
-
if KuberKit::Container['actions.configuration_loader'].call(options)
|
|
111
|
+
if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
|
|
103
112
|
KuberKit::Container['actions.kubectl_console'].call(pod_name, options)
|
|
104
113
|
end
|
|
105
114
|
end
|
|
@@ -109,11 +118,20 @@ class KuberKit::CLI < Thor
|
|
|
109
118
|
def logs(pod_name = nil)
|
|
110
119
|
setup(options)
|
|
111
120
|
|
|
112
|
-
if KuberKit::Container['actions.configuration_loader'].call(options)
|
|
121
|
+
if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
|
|
113
122
|
KuberKit::Container['actions.kubectl_logs'].call(pod_name, options)
|
|
114
123
|
end
|
|
115
124
|
end
|
|
116
125
|
|
|
126
|
+
desc "describe RESOURCE_NAME", "Show description for RESOURCE_NAME using kubectl"
|
|
127
|
+
def describe(pod_name = nil)
|
|
128
|
+
setup(options)
|
|
129
|
+
|
|
130
|
+
if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
|
|
131
|
+
KuberKit::Container['actions.kubectl_describe'].call(pod_name, options)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
117
135
|
desc "version", "Print current version"
|
|
118
136
|
def version
|
|
119
137
|
puts KuberKit::VERSION
|
data/lib/kuber_kit/container.rb
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
class KuberKit::Core::Configuration
|
|
2
2
|
attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path,
|
|
3
|
-
:
|
|
4
|
-
:
|
|
3
|
+
:services_attributes, :enabled_services, :build_servers, :global_build_vars,
|
|
4
|
+
:deployer_strategy, :deployer_namespace, :deployer_require_confirimation
|
|
5
5
|
|
|
6
6
|
Contract KeywordArgs[
|
|
7
|
-
name:
|
|
8
|
-
artifacts:
|
|
9
|
-
registries:
|
|
10
|
-
env_files:
|
|
11
|
-
templates:
|
|
12
|
-
kubeconfig_path:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
name: Symbol,
|
|
8
|
+
artifacts: Hash,
|
|
9
|
+
registries: Hash,
|
|
10
|
+
env_files: Hash,
|
|
11
|
+
templates: Hash,
|
|
12
|
+
kubeconfig_path: Maybe[String],
|
|
13
|
+
services_attributes: HashOf[Symbol => Hash],
|
|
14
|
+
enabled_services: ArrayOf[Symbol],
|
|
15
|
+
build_servers: ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer],
|
|
16
|
+
global_build_vars: HashOf[Symbol => Any],
|
|
17
|
+
deployer_strategy: Symbol,
|
|
18
|
+
deployer_namespace: Maybe[Symbol],
|
|
19
|
+
deployer_require_confirimation: Bool,
|
|
18
20
|
] => Any
|
|
19
21
|
def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@name
|
|
23
|
-
@artifacts
|
|
24
|
-
@registries
|
|
25
|
-
@env_files
|
|
26
|
-
@templates
|
|
27
|
-
@kubeconfig_path
|
|
28
|
-
@
|
|
29
|
-
@deployer_namespace = deployer_namespace
|
|
30
|
-
@build_servers = build_servers
|
|
22
|
+
services_attributes:, enabled_services:, build_servers:, global_build_vars:,
|
|
23
|
+
deployer_strategy:, deployer_namespace:, deployer_require_confirimation:)
|
|
24
|
+
@name = name
|
|
25
|
+
@artifacts = artifacts
|
|
26
|
+
@registries = registries
|
|
27
|
+
@env_files = env_files
|
|
28
|
+
@templates = templates
|
|
29
|
+
@kubeconfig_path = kubeconfig_path
|
|
30
|
+
@build_servers = build_servers
|
|
31
31
|
@services_attributes = services_attributes
|
|
32
|
+
@enabled_services = enabled_services
|
|
32
33
|
@global_build_vars = global_build_vars
|
|
34
|
+
@deployer_strategy = deployer_strategy
|
|
35
|
+
@deployer_namespace = deployer_namespace
|
|
36
|
+
@deployer_require_confirimation = deployer_require_confirimation
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
def service_attributes(service_name)
|
|
@@ -17,18 +17,19 @@ class KuberKit::Core::ConfigurationDefinition
|
|
|
17
17
|
|
|
18
18
|
def to_attrs
|
|
19
19
|
OpenStruct.new(
|
|
20
|
-
name:
|
|
21
|
-
artifacts:
|
|
22
|
-
registries:
|
|
23
|
-
env_files:
|
|
24
|
-
templates:
|
|
25
|
-
kubeconfig_path:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
enabled_services: @enabled_services,
|
|
29
|
-
build_servers: @build_servers,
|
|
20
|
+
name: @configuration_name,
|
|
21
|
+
artifacts: @artifacts,
|
|
22
|
+
registries: @registries,
|
|
23
|
+
env_files: @env_files,
|
|
24
|
+
templates: @templates,
|
|
25
|
+
kubeconfig_path: @kubeconfig_path,
|
|
26
|
+
enabled_services: @enabled_services,
|
|
27
|
+
build_servers: @build_servers,
|
|
30
28
|
services_attributes: @services_attributes,
|
|
31
29
|
global_build_vars: @global_build_vars,
|
|
30
|
+
deployer_strategy: @deployer_strategy,
|
|
31
|
+
deployer_namespace: @deployer_namespace,
|
|
32
|
+
deployer_require_confirimation: @deployer_require_confirimation || false,
|
|
32
33
|
)
|
|
33
34
|
end
|
|
34
35
|
|
|
@@ -94,6 +95,12 @@ class KuberKit::Core::ConfigurationDefinition
|
|
|
94
95
|
self
|
|
95
96
|
end
|
|
96
97
|
|
|
98
|
+
def deployer_require_confirimation
|
|
99
|
+
@deployer_require_confirimation = true
|
|
100
|
+
|
|
101
|
+
self
|
|
102
|
+
end
|
|
103
|
+
|
|
97
104
|
def enabled_services(services)
|
|
98
105
|
if services.is_a?(Hash)
|
|
99
106
|
@enabled_services += services.keys.map(&:to_sym)
|
|
@@ -20,17 +20,19 @@ class KuberKit::Core::ConfigurationFactory
|
|
|
20
20
|
build_servers = fetch_build_servers(configuration_attrs.build_servers)
|
|
21
21
|
|
|
22
22
|
KuberKit::Core::Configuration.new(
|
|
23
|
-
name:
|
|
24
|
-
artifacts:
|
|
25
|
-
registries:
|
|
26
|
-
env_files:
|
|
27
|
-
templates:
|
|
28
|
-
kubeconfig_path:
|
|
29
|
-
|
|
30
|
-
deployer_namespace: configuration_attrs.deployer_namespace,
|
|
31
|
-
build_servers: build_servers,
|
|
23
|
+
name: configuration_attrs.name,
|
|
24
|
+
artifacts: artifacts,
|
|
25
|
+
registries: registries,
|
|
26
|
+
env_files: env_files,
|
|
27
|
+
templates: templates,
|
|
28
|
+
kubeconfig_path: configuration_attrs.kubeconfig_path,
|
|
29
|
+
build_servers: build_servers,
|
|
32
30
|
services_attributes: configuration_attrs.services_attributes,
|
|
31
|
+
enabled_services: configuration_attrs.enabled_services,
|
|
33
32
|
global_build_vars: configuration_attrs.global_build_vars || {},
|
|
33
|
+
deployer_strategy: configuration_attrs.deployer_strategy || configs.deployer_strategy,
|
|
34
|
+
deployer_namespace: configuration_attrs.deployer_namespace,
|
|
35
|
+
deployer_require_confirimation: configuration_attrs.deployer_require_confirimation,
|
|
34
36
|
)
|
|
35
37
|
end
|
|
36
38
|
|
|
@@ -20,7 +20,9 @@ class KuberKit::ImageCompiler::ImageDependencyResolver
|
|
|
20
20
|
next_dependencies = get_next(image_names, resolved: resolved_dependencies, limit: compile_limit)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
(image_names - resolved_dependencies).each_slice(compile_limit) do |group|
|
|
24
|
+
block.call(group)
|
|
25
|
+
end
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
Contract Or[Symbol, ArrayOf[Symbol]], KeywordArgs[
|
|
@@ -4,10 +4,11 @@ class KuberKit::ServiceDeployer::ServiceListResolver
|
|
|
4
4
|
]
|
|
5
5
|
|
|
6
6
|
Contract KeywordArgs[
|
|
7
|
-
services:
|
|
8
|
-
tags:
|
|
7
|
+
services: Optional[ArrayOf[String]],
|
|
8
|
+
tags: Optional[ArrayOf[String]],
|
|
9
|
+
enabled_services: Optional[ArrayOf[String]]
|
|
9
10
|
] => ArrayOf[String]
|
|
10
|
-
def resolve(services: [], tags: [])
|
|
11
|
+
def resolve(services: [], tags: [], enabled_services: [])
|
|
11
12
|
all_definitions = service_store.all_definitions.values
|
|
12
13
|
|
|
13
14
|
included_services, excluded_services = split_by_inclusion(services)
|
|
@@ -29,7 +30,13 @@ class KuberKit::ServiceDeployer::ServiceListResolver
|
|
|
29
30
|
matches_any?(service_tags, excluded_tags)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
included_definitions.map(&:service_name).map(&:to_s)
|
|
33
|
+
included_services = included_definitions.map(&:service_name).map(&:to_s)
|
|
34
|
+
|
|
35
|
+
if enabled_services.any?
|
|
36
|
+
included_services = included_services.select{ |s| enabled_services.include?(s) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
included_services
|
|
33
40
|
end
|
|
34
41
|
|
|
35
42
|
Contract Array => Array
|
|
@@ -10,8 +10,10 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
|
10
10
|
:image_name,
|
|
11
11
|
:detached,
|
|
12
12
|
:command_name,
|
|
13
|
-
:
|
|
14
|
-
:delete_if_exists
|
|
13
|
+
:custom_args,
|
|
14
|
+
:delete_if_exists,
|
|
15
|
+
:volumes,
|
|
16
|
+
:networks,
|
|
15
17
|
]
|
|
16
18
|
|
|
17
19
|
Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
|
|
@@ -23,8 +25,11 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
container_name = strategy_options.fetch(:container_name, service.uri)
|
|
26
|
-
command_name = strategy_options.fetch(:command_name,
|
|
27
|
-
|
|
28
|
+
command_name = strategy_options.fetch(:command_name, nil)
|
|
29
|
+
custom_args = strategy_options.fetch(:custom_args, nil)
|
|
30
|
+
networks = strategy_options.fetch(:networks, [])
|
|
31
|
+
volumes = strategy_options.fetch(:volumes, [])
|
|
32
|
+
hostname = strategy_options.fetch(:hostname, container_name)
|
|
28
33
|
|
|
29
34
|
image_name = strategy_options.fetch(:image_name, nil)
|
|
30
35
|
if image_name.nil?
|
|
@@ -37,15 +42,27 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
|
37
42
|
docker_commands.delete_container(shell, container_name)
|
|
38
43
|
end
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
custom_args = Array(custom_args)
|
|
41
46
|
if container_name
|
|
42
|
-
|
|
47
|
+
custom_args << "--name #{container_name}"
|
|
48
|
+
end
|
|
49
|
+
if hostname
|
|
50
|
+
custom_args << "--hostname #{hostname}"
|
|
51
|
+
end
|
|
52
|
+
networks.each do |network|
|
|
53
|
+
docker_commands.create_network(shell, network)
|
|
54
|
+
custom_args << "--network #{network}"
|
|
55
|
+
end
|
|
56
|
+
volumes.each do |volume|
|
|
57
|
+
volume_name, _ = volume.split(":")
|
|
58
|
+
docker_commands.create_volume(shell, volume_name) unless volume_name.start_with?("/")
|
|
59
|
+
custom_args << "--volume #{volume}"
|
|
43
60
|
end
|
|
44
61
|
|
|
45
62
|
docker_commands.run(
|
|
46
63
|
shell, image.remote_registry_url,
|
|
47
64
|
command: command_name,
|
|
48
|
-
args:
|
|
65
|
+
args: custom_args,
|
|
49
66
|
detached: !!strategy_options[:detached]
|
|
50
67
|
)
|
|
51
68
|
end
|
|
@@ -8,7 +8,7 @@ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDe
|
|
|
8
8
|
STRATEGY_OPTIONS = [
|
|
9
9
|
:service_name,
|
|
10
10
|
:command_name,
|
|
11
|
-
:
|
|
11
|
+
:custom_args,
|
|
12
12
|
:detached
|
|
13
13
|
]
|
|
14
14
|
|
|
@@ -25,13 +25,13 @@ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDe
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
service_name = strategy_options.fetch(:service_name, service.name.to_s)
|
|
28
|
-
command_name = strategy_options.fetch(:command_name,
|
|
29
|
-
|
|
28
|
+
command_name = strategy_options.fetch(:command_name, nil)
|
|
29
|
+
custom_args = strategy_options.fetch(:custom_args, nil)
|
|
30
30
|
|
|
31
31
|
docker_compose_commands.run(shell, config_path,
|
|
32
32
|
service: service_name,
|
|
33
33
|
command: command_name,
|
|
34
|
-
args:
|
|
34
|
+
args: custom_args,
|
|
35
35
|
detached: !!strategy_options[:detached]
|
|
36
36
|
)
|
|
37
37
|
end
|
|
@@ -30,15 +30,11 @@ class KuberKit::Shell::Commands::DockerCommands
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def container_exists?(shell, container_name, status: nil)
|
|
33
|
-
result =
|
|
33
|
+
result = get_containers(shell, container_name, status: status)
|
|
34
34
|
result && result != ""
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def
|
|
38
|
-
shell.exec!(%Q{docker rm -f #{container_name}})
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def get_container_id(shell, container_name, only_healthy: false, status: nil)
|
|
37
|
+
def get_containers(shell, container_name, only_healthy: false, status: nil)
|
|
42
38
|
command_parts = []
|
|
43
39
|
command_parts << "docker ps -a -q"
|
|
44
40
|
|
|
@@ -52,4 +48,48 @@ class KuberKit::Shell::Commands::DockerCommands
|
|
|
52
48
|
|
|
53
49
|
shell.exec!(command_parts.join(" "))
|
|
54
50
|
end
|
|
51
|
+
|
|
52
|
+
def delete_container(shell, container_name)
|
|
53
|
+
shell.exec!("docker rm -f #{container_name}")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create_network(shell, name)
|
|
57
|
+
unless network_exists?(shell, name)
|
|
58
|
+
shell.exec!("docker network create #{name}")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def network_exists?(shell, network_name)
|
|
63
|
+
result = get_networks(shell, network_name)
|
|
64
|
+
result && result != ""
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def get_networks(shell, network_name)
|
|
68
|
+
command_parts = []
|
|
69
|
+
command_parts << "docker network ls"
|
|
70
|
+
command_parts << "--filter=\"name=#{network_name}\""
|
|
71
|
+
command_parts << "--format \"{{.Name}}\""
|
|
72
|
+
|
|
73
|
+
shell.exec!(command_parts.join(" "))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def create_volume(shell, name)
|
|
77
|
+
unless volume_exists?(shell, name)
|
|
78
|
+
shell.exec!("docker volume create #{name}")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def volume_exists?(shell, volume_name)
|
|
83
|
+
result = get_volumes(shell, volume_name)
|
|
84
|
+
result && result != ""
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def get_volumes(shell, volume_name)
|
|
88
|
+
command_parts = []
|
|
89
|
+
command_parts << "docker volume ls"
|
|
90
|
+
command_parts << "--filter=\"name=#{volume_name}\""
|
|
91
|
+
command_parts << "--format \"{{.Name}}\""
|
|
92
|
+
|
|
93
|
+
shell.exec!(command_parts.join(" "))
|
|
94
|
+
end
|
|
55
95
|
end
|
|
@@ -14,7 +14,7 @@ class KuberKit::Shell::Commands::KubectlCommands
|
|
|
14
14
|
command_parts << "-n #{namespace}"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
command_parts += Array(command_list)
|
|
17
|
+
command_parts += Array(command_list).compact
|
|
18
18
|
|
|
19
19
|
if interactive
|
|
20
20
|
shell.interactive!(command_parts.join(" "))
|
|
@@ -41,15 +41,11 @@ class KuberKit::Shell::Commands::KubectlCommands
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def logs(shell, pod_name, args: nil, kubeconfig_path: nil, namespace: nil)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if args
|
|
48
|
-
command_parts << args
|
|
49
|
-
end
|
|
44
|
+
kubectl_run(shell, ["logs", args, pod_name], kubeconfig_path: kubeconfig_path, interactive: true, namespace: namespace)
|
|
45
|
+
end
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
kubectl_run(shell,
|
|
47
|
+
def describe(shell, resource_name, args: nil, kubeconfig_path: nil, namespace: nil)
|
|
48
|
+
kubectl_run(shell, ["describe", args, resource_name], kubeconfig_path: kubeconfig_path, interactive: true, namespace: namespace)
|
|
53
49
|
end
|
|
54
50
|
|
|
55
51
|
def get_resources(shell, resource_type, field_selector: nil, jsonpath: ".items[*].metadata.name", kubeconfig_path: nil, namespace: nil)
|
|
@@ -64,7 +60,12 @@ class KuberKit::Shell::Commands::KubectlCommands
|
|
|
64
60
|
command_parts << "-o jsonpath='{#{jsonpath}}'"
|
|
65
61
|
end
|
|
66
62
|
|
|
67
|
-
kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
|
63
|
+
result = kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
|
64
|
+
|
|
65
|
+
# Hide warnings manually, until appropriate kubectl option will be available
|
|
66
|
+
result = result.split("\n").reject{|n| n.start_with?("Warning:") }.join("\n") if result.is_a?(String)
|
|
67
|
+
|
|
68
|
+
result
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
def resource_exists?(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'cli/ui'
|
|
2
|
+
require "tty-prompt"
|
|
2
3
|
|
|
3
4
|
class KuberKit::UI::Interactive
|
|
4
5
|
include KuberKit::Import[
|
|
@@ -42,17 +43,10 @@ class KuberKit::UI::Interactive
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def prompt(text, options, &callback)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
else
|
|
50
|
-
handler.option(option) do |selection|
|
|
51
|
-
selection
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
46
|
+
prompt = TTY::Prompt.new
|
|
47
|
+
prompt.select(text, options, filter: true, per_page: 10)
|
|
48
|
+
rescue TTY::Reader::InputInterrupt
|
|
49
|
+
raise KuberKit::Error.new("Selection cancelled.")
|
|
56
50
|
end
|
|
57
51
|
|
|
58
52
|
private
|
data/lib/kuber_kit/ui/simple.rb
CHANGED
|
@@ -97,10 +97,9 @@ class KuberKit::UI::Simple
|
|
|
97
97
|
print_debug("Result", "---------------------------")
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
def prompt(text, options
|
|
101
|
-
print_info("Select", text)
|
|
100
|
+
def prompt(text, options)
|
|
101
|
+
print_info("Select", text + "(#{options.join(', ')})")
|
|
102
102
|
result = $stdin.gets.chomp
|
|
103
|
-
callback.call(result) if callback
|
|
104
103
|
result
|
|
105
104
|
end
|
|
106
105
|
|
data/lib/kuber_kit/version.rb
CHANGED
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.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Iskander Khaziev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-02-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: contracts-lite
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: tty-prompt
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: bundler
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -194,6 +208,7 @@ files:
|
|
|
194
208
|
- lib/kuber_kit/actions/kubectl_applier.rb
|
|
195
209
|
- lib/kuber_kit/actions/kubectl_attacher.rb
|
|
196
210
|
- lib/kuber_kit/actions/kubectl_console.rb
|
|
211
|
+
- lib/kuber_kit/actions/kubectl_describe.rb
|
|
197
212
|
- lib/kuber_kit/actions/kubectl_logs.rb
|
|
198
213
|
- lib/kuber_kit/actions/service_deployer.rb
|
|
199
214
|
- lib/kuber_kit/actions/service_reader.rb
|