kuber_kit 0.4.9 → 0.5.4
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/CHANGELOG.md +12 -0
- data/Gemfile.lock +2 -2
- data/TODO.md +5 -5
- data/example/configurations/review.rb +1 -1
- data/example/services/ruby_app.rb +1 -0
- data/lib/kuber_kit.rb +9 -0
- data/lib/kuber_kit/actions/kubectl_attacher.rb +2 -2
- data/lib/kuber_kit/actions/kubectl_console.rb +2 -2
- data/lib/kuber_kit/actions/kubectl_describe.rb +2 -2
- data/lib/kuber_kit/actions/kubectl_env.rb +19 -0
- data/lib/kuber_kit/actions/kubectl_get.rb +32 -0
- data/lib/kuber_kit/actions/kubectl_logs.rb +2 -2
- data/lib/kuber_kit/actions/service_checker.rb +37 -0
- data/lib/kuber_kit/actions/service_deployer.rb +79 -60
- data/lib/kuber_kit/cli.rb +28 -1
- data/lib/kuber_kit/configs.rb +2 -1
- data/lib/kuber_kit/container.rb +20 -0
- data/lib/kuber_kit/core/configuration.rb +4 -2
- data/lib/kuber_kit/core/configuration_definition.rb +7 -0
- data/lib/kuber_kit/core/configuration_factory.rb +1 -0
- data/lib/kuber_kit/core/dependencies/abstract_dependency_resolver.rb +75 -0
- data/lib/kuber_kit/core/image.rb +2 -1
- data/lib/kuber_kit/core/service.rb +4 -2
- data/lib/kuber_kit/core/service_definition.rb +13 -6
- data/lib/kuber_kit/core/service_factory.rb +1 -0
- data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +5 -53
- data/lib/kuber_kit/kubernetes/resource_selector.rb +33 -0
- data/lib/kuber_kit/kubernetes/resources_fetcher.rb +7 -30
- data/lib/kuber_kit/service_deployer/service_dependency_resolver.rb +14 -0
- data/lib/kuber_kit/service_deployer/service_list_resolver.rb +11 -6
- data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +9 -2
- data/lib/kuber_kit/shell/commands/kubectl_commands.rb +12 -4
- data/lib/kuber_kit/shell/local_shell.rb +15 -1
- data/lib/kuber_kit/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e99c1ae700ec8b59f9a832d3c9131e85c7d05a60548d8bca032d4ce2c9178b2
|
4
|
+
data.tar.gz: e4233e8cf40a7980477d85f341320536725efd169ac4120e74de6c7ad651e436
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10a3f4b72a0d3a09c9a49842642e6f7a0457a5cb243d0c469c9792c7fcc70ff483b9ffbd6ecc7c278d20b3b7e22f603e45ad3360e701b1a9cf9696cff64d46ce
|
7
|
+
data.tar.gz: f857ce1a307375486c51cfaa67c22a929826b54a1ad572dc5a5ac64fb4febfe680fa27f3adddadf2d2b3d68325cd5dee7ba47facdf672c427640d048c23c950f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
**0.5.4**
|
2
|
+
- Added disabled services support
|
3
|
+
|
4
|
+
**0.5.3**
|
5
|
+
- Change the symbol to exclude service from "-" to "!", you can pass "-s !auth_app" to exclude "auth_app"
|
6
|
+
- Added kit get command to find pods
|
7
|
+
|
8
|
+
**0.5.2**
|
9
|
+
- Added dependencies support to services
|
10
|
+
- Added an option to deploy all services in `kit deloy`
|
11
|
+
- Wait for rollout to finish during service deploy
|
12
|
+
- Deploy services in batches, not all of the simultaneously
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
kuber_kit (0.4
|
4
|
+
kuber_kit (0.5.4)
|
5
5
|
cli-ui
|
6
6
|
contracts-lite
|
7
7
|
dry-auto_inject
|
@@ -20,7 +20,7 @@ GEM
|
|
20
20
|
docile (1.3.2)
|
21
21
|
dry-auto_inject (0.7.0)
|
22
22
|
dry-container (>= 0.3.4)
|
23
|
-
dry-configurable (0.12.
|
23
|
+
dry-configurable (0.12.1)
|
24
24
|
concurrent-ruby (~> 1.0)
|
25
25
|
dry-core (~> 0.5, >= 0.5.0)
|
26
26
|
dry-container (0.7.2)
|
data/TODO.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
-
|
2
|
-
-
|
3
|
-
-
|
4
|
-
- find a way to always deploy some service, e.g. for migrations and env_files
|
1
|
+
- add kit get method for more interactive kubernetes
|
2
|
+
- env files should use a separate deployment method (with change detection)
|
3
|
+
- add automatical confirmation support for service deployer
|
5
4
|
- template should be able to set default attributes
|
6
5
|
- template should be able to depend on image?
|
7
6
|
- cleanup image builds older than some date
|
8
|
-
- add some rotation for deploy log
|
7
|
+
- add some rotation for deploy log
|
8
|
+
- kit status should show the list of services and their status, with ability to select & view logs
|
data/lib/kuber_kit.rb
CHANGED
@@ -46,6 +46,10 @@ module KuberKit
|
|
46
46
|
autoload :BuildServer, 'core/build_servers/build_server'
|
47
47
|
end
|
48
48
|
|
49
|
+
module Dependencies
|
50
|
+
autoload :AbstractDependencyResolver, 'core/dependencies/abstract_dependency_resolver'
|
51
|
+
end
|
52
|
+
|
49
53
|
module EnvFiles
|
50
54
|
autoload :EnvFileStore, 'core/env_files/env_file_store'
|
51
55
|
autoload :AbstractEnvFile, 'core/env_files/abstract_env_file'
|
@@ -145,6 +149,7 @@ module KuberKit
|
|
145
149
|
autoload :StrategyDetector, 'service_deployer/strategy_detector'
|
146
150
|
autoload :Deployer, 'service_deployer/deployer'
|
147
151
|
autoload :ServiceListResolver, 'service_deployer/service_list_resolver'
|
152
|
+
autoload :ServiceDependencyResolver, 'service_deployer/service_dependency_resolver'
|
148
153
|
|
149
154
|
module Strategies
|
150
155
|
autoload :Abstract, 'service_deployer/strategies/abstract'
|
@@ -165,12 +170,15 @@ module KuberKit
|
|
165
170
|
autoload :TemplateReader, 'actions/template_reader'
|
166
171
|
autoload :ServiceReader, 'actions/service_reader'
|
167
172
|
autoload :ServiceDeployer, 'actions/service_deployer'
|
173
|
+
autoload :ServiceChecker, 'actions/service_checker'
|
168
174
|
autoload :ConfigurationLoader, 'actions/configuration_loader'
|
169
175
|
autoload :KubectlApplier, 'actions/kubectl_applier'
|
170
176
|
autoload :KubectlAttacher, 'actions/kubectl_attacher'
|
171
177
|
autoload :KubectlConsole, 'actions/kubectl_console'
|
172
178
|
autoload :KubectlDescribe, 'actions/kubectl_describe'
|
179
|
+
autoload :KubectlGet, 'actions/kubectl_get'
|
173
180
|
autoload :KubectlLogs, 'actions/kubectl_logs'
|
181
|
+
autoload :KubectlEnv, 'actions/kubectl_env'
|
174
182
|
end
|
175
183
|
|
176
184
|
module Extensions
|
@@ -178,6 +186,7 @@ module KuberKit
|
|
178
186
|
end
|
179
187
|
|
180
188
|
module Kubernetes
|
189
|
+
autoload :ResourceSelector, 'kubernetes/resource_selector'
|
181
190
|
autoload :ResourcesFetcher, 'kubernetes/resources_fetcher'
|
182
191
|
end
|
183
192
|
|
@@ -2,7 +2,7 @@ class KuberKit::Actions::KubectlAttacher
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"shell.kubectl_commands",
|
4
4
|
"shell.local_shell",
|
5
|
-
"kubernetes.
|
5
|
+
"kubernetes.resource_selector",
|
6
6
|
"ui"
|
7
7
|
]
|
8
8
|
|
@@ -12,7 +12,7 @@ class KuberKit::Actions::KubectlAttacher
|
|
12
12
|
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
13
13
|
|
14
14
|
if !pod_name
|
15
|
-
pod_name =
|
15
|
+
pod_name = resource_selector.call("attach")
|
16
16
|
end
|
17
17
|
|
18
18
|
kubectl_commands.exec(
|
@@ -2,7 +2,7 @@ class KuberKit::Actions::KubectlConsole
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"shell.kubectl_commands",
|
4
4
|
"shell.local_shell",
|
5
|
-
"kubernetes.
|
5
|
+
"kubernetes.resource_selector",
|
6
6
|
"ui"
|
7
7
|
]
|
8
8
|
|
@@ -12,7 +12,7 @@ class KuberKit::Actions::KubectlConsole
|
|
12
12
|
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
13
13
|
|
14
14
|
if !pod_name
|
15
|
-
pod_name =
|
15
|
+
pod_name = resource_selector.call("attach")
|
16
16
|
end
|
17
17
|
|
18
18
|
kubectl_commands.exec(
|
@@ -2,7 +2,7 @@ class KuberKit::Actions::KubectlDescribe
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"shell.kubectl_commands",
|
4
4
|
"shell.local_shell",
|
5
|
-
"kubernetes.
|
5
|
+
"kubernetes.resource_selector",
|
6
6
|
"ui"
|
7
7
|
]
|
8
8
|
|
@@ -12,7 +12,7 @@ class KuberKit::Actions::KubectlDescribe
|
|
12
12
|
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
13
13
|
|
14
14
|
if !resource_name
|
15
|
-
resource_name =
|
15
|
+
resource_name = resource_selector.call("describe", include_ingresses: true, include_pods: true)
|
16
16
|
end
|
17
17
|
|
18
18
|
args = nil
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class KuberKit::Actions::KubectlEnv
|
2
|
+
include KuberKit::Import[
|
3
|
+
"shell.local_shell",
|
4
|
+
"ui"
|
5
|
+
]
|
6
|
+
|
7
|
+
Contract Hash => Any
|
8
|
+
def call(options)
|
9
|
+
configuration = KuberKit.current_configuration
|
10
|
+
kubeconfig_path = configuration.kubeconfig_path
|
11
|
+
ui.print_info("ENV", "export KUBECONFIG=#{kubeconfig_path}")
|
12
|
+
|
13
|
+
true
|
14
|
+
rescue KuberKit::Error => e
|
15
|
+
ui.print_error("Error", e.message)
|
16
|
+
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class KuberKit::Actions::KubectlGet
|
2
|
+
include KuberKit::Import[
|
3
|
+
"shell.kubectl_commands",
|
4
|
+
"shell.local_shell",
|
5
|
+
"kubernetes.resource_selector",
|
6
|
+
"ui"
|
7
|
+
]
|
8
|
+
|
9
|
+
Contract Maybe[String], Hash => Any
|
10
|
+
def call(resource_name, options)
|
11
|
+
kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
|
12
|
+
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
13
|
+
|
14
|
+
resources = kubectl_commands.get_resources(
|
15
|
+
local_shell, "pod",
|
16
|
+
kubeconfig_path: kubeconfig_path,
|
17
|
+
namespace: deployer_namespace
|
18
|
+
)
|
19
|
+
|
20
|
+
if resource_name
|
21
|
+
resources = resources.select{|r| r.include?(resource_name) }
|
22
|
+
end
|
23
|
+
|
24
|
+
ui.print_info("Pods", resources.join("\n"))
|
25
|
+
|
26
|
+
true
|
27
|
+
rescue KuberKit::Error => e
|
28
|
+
ui.print_error("Error", e.message)
|
29
|
+
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
@@ -2,7 +2,7 @@ class KuberKit::Actions::KubectlLogs
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"shell.kubectl_commands",
|
4
4
|
"shell.local_shell",
|
5
|
-
"kubernetes.
|
5
|
+
"kubernetes.resource_selector",
|
6
6
|
"ui"
|
7
7
|
]
|
8
8
|
|
@@ -12,7 +12,7 @@ class KuberKit::Actions::KubectlLogs
|
|
12
12
|
deployer_namespace = KuberKit.current_configuration.deployer_namespace
|
13
13
|
|
14
14
|
if !pod_name
|
15
|
-
pod_name =
|
15
|
+
pod_name = resource_selector.call("attach")
|
16
16
|
end
|
17
17
|
|
18
18
|
args = nil
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class KuberKit::Actions::ServiceChecker
|
2
|
+
include KuberKit::Import[
|
3
|
+
"kubernetes.resources_fetcher",
|
4
|
+
"shell.local_shell",
|
5
|
+
"core.service_store",
|
6
|
+
"ui",
|
7
|
+
]
|
8
|
+
|
9
|
+
Contract Hash => Any
|
10
|
+
def call(options)
|
11
|
+
services = service_store.all_definitions.values.map(&:service_name).map(&:to_s)
|
12
|
+
|
13
|
+
enabled_services = KuberKit.current_configuration.enabled_services.map(&:to_s)
|
14
|
+
if enabled_services.any?
|
15
|
+
services = services.select{ |s| enabled_services.include?(s) }
|
16
|
+
end
|
17
|
+
|
18
|
+
disabled_services = KuberKit.current_configuration.disabled_services.map(&:to_s)
|
19
|
+
if disabled_services.any?
|
20
|
+
services = services.select{ |s| !disabled_services.include?(s) }
|
21
|
+
end
|
22
|
+
|
23
|
+
resources = resources_fetcher.call("deployments") + resources_fetcher.call("cronjobs")
|
24
|
+
|
25
|
+
missing_services = services.select{ |s| !resources.include?(s.gsub("_", "-")) }
|
26
|
+
|
27
|
+
ui.print_warning("Warning", "This command will only check services deployed using k8s")
|
28
|
+
|
29
|
+
ui.print_info("Missing", missing_services.inspect)
|
30
|
+
|
31
|
+
{}
|
32
|
+
rescue KuberKit::Error => e
|
33
|
+
ui.print_error("Error", e.message)
|
34
|
+
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
@@ -2,9 +2,11 @@ class KuberKit::Actions::ServiceDeployer
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"actions.image_compiler",
|
4
4
|
"service_deployer.service_list_resolver",
|
5
|
+
"service_deployer.service_dependency_resolver",
|
5
6
|
"core.service_store",
|
6
7
|
"shell.local_shell",
|
7
8
|
"tools.process_cleaner",
|
9
|
+
"configs",
|
8
10
|
"ui",
|
9
11
|
service_deployer: "service_deployer.action_handler",
|
10
12
|
]
|
@@ -16,6 +18,8 @@ class KuberKit::Actions::ServiceDeployer
|
|
16
18
|
require_confirmation: Maybe[Bool],
|
17
19
|
] => Any
|
18
20
|
def call(services:, tags:, skip_compile: false, require_confirmation: false)
|
21
|
+
current_configuration = KuberKit.current_configuration
|
22
|
+
|
19
23
|
if services.empty? && tags.empty?
|
20
24
|
services, tags = show_tags_selection
|
21
25
|
end
|
@@ -23,15 +27,19 @@ class KuberKit::Actions::ServiceDeployer
|
|
23
27
|
service_names = service_list_resolver.resolve(
|
24
28
|
services: services || [],
|
25
29
|
tags: tags || [],
|
26
|
-
enabled_services:
|
27
|
-
|
30
|
+
enabled_services: current_configuration.enabled_services.map(&:to_s),
|
31
|
+
disabled_services: current_configuration.disabled_services.map(&:to_s)
|
32
|
+
).map(&:to_sym)
|
33
|
+
|
34
|
+
# Return the list of services with all dependencies.
|
35
|
+
all_service_names = service_dependency_resolver.get_all(service_names)
|
28
36
|
|
29
|
-
unless
|
37
|
+
unless all_service_names.any?
|
30
38
|
ui.print_warning "ServiceDeployer", "No service found with given options, nothing will be deployed."
|
31
39
|
return false
|
32
40
|
end
|
33
41
|
|
34
|
-
services_list =
|
42
|
+
services_list = all_service_names.map(&:to_s).map(&:yellow).join(", ")
|
35
43
|
ui.print_info "ServiceDeployer", "The following services will be deployed: #{services_list}"
|
36
44
|
|
37
45
|
if require_confirmation
|
@@ -39,7 +47,7 @@ class KuberKit::Actions::ServiceDeployer
|
|
39
47
|
return false unless ["confirm".green, "confirm", "yes"].include?(result)
|
40
48
|
end
|
41
49
|
|
42
|
-
services =
|
50
|
+
services = all_service_names.map do |service_name|
|
43
51
|
service_store.get_service(service_name.to_sym)
|
44
52
|
end
|
45
53
|
|
@@ -50,9 +58,16 @@ class KuberKit::Actions::ServiceDeployer
|
|
50
58
|
return false unless compile_result
|
51
59
|
end
|
52
60
|
|
53
|
-
|
61
|
+
deployed_services = []
|
62
|
+
deployment_result = {}
|
63
|
+
service_dependency_resolver.each_with_deps(service_names) do |dep_service_names|
|
64
|
+
ui.print_debug("ServiceDeployer", "Scheduling to compile: #{dep_service_names.inspect}. Limit: #{configs.deploy_simultaneous_limit}")
|
65
|
+
result = deploy_simultaneously(dep_service_names)
|
66
|
+
deployed_services += dep_service_names
|
67
|
+
deployment_result = deployment_result.merge(result)
|
68
|
+
end
|
54
69
|
|
55
|
-
{ services:
|
70
|
+
{ services: all_service_names, deployment: deployment_result }
|
56
71
|
rescue KuberKit::Error => e
|
57
72
|
ui.print_error("Error", e.message)
|
58
73
|
|
@@ -61,69 +76,73 @@ class KuberKit::Actions::ServiceDeployer
|
|
61
76
|
process_cleaner.clean
|
62
77
|
end
|
63
78
|
|
64
|
-
|
65
|
-
|
79
|
+
private
|
80
|
+
def deploy_simultaneously(service_names)
|
81
|
+
task_group = ui.create_task_group
|
66
82
|
|
67
|
-
|
83
|
+
deployer_result = {}
|
68
84
|
|
69
|
-
|
85
|
+
service_names.each do |service_name|
|
70
86
|
|
71
|
-
|
72
|
-
|
73
|
-
|
87
|
+
ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
|
88
|
+
task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
|
89
|
+
deployer_result[service_name] = service_deployer.call(local_shell, service_name.to_sym)
|
74
90
|
|
75
|
-
|
76
|
-
|
91
|
+
task.update_title("Deployed #{service_name.to_s.green}")
|
92
|
+
ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
|
93
|
+
end
|
77
94
|
end
|
78
|
-
end
|
79
95
|
|
80
|
-
|
96
|
+
task_group.wait
|
81
97
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
def compile_images(images_names)
|
86
|
-
return true if images_names.empty?
|
87
|
-
image_compiler.call(images_names, {})
|
88
|
-
end
|
98
|
+
deployer_result
|
99
|
+
end
|
89
100
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
tags = [specific_service_option]
|
94
|
-
tags += service_store
|
95
|
-
.all_definitions
|
96
|
-
.values
|
97
|
-
.map(&:to_service_attrs)
|
98
|
-
.map(&:tags)
|
99
|
-
.flatten
|
100
|
-
.uniq
|
101
|
-
.sort
|
102
|
-
.map(&:to_s)
|
103
|
-
|
104
|
-
selected_tag = ui.prompt("Please select which tag to deploy", tags)
|
105
|
-
|
106
|
-
if selected_tag == specific_service_option
|
107
|
-
show_service_selection
|
108
|
-
else
|
109
|
-
[[], [selected_tag]]
|
101
|
+
def compile_images(images_names)
|
102
|
+
return true if images_names.empty?
|
103
|
+
image_compiler.call(images_names, {})
|
110
104
|
end
|
111
|
-
end
|
112
105
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
106
|
+
def show_tags_selection()
|
107
|
+
specific_service_option = "deploy specific service"
|
108
|
+
all_services_option = "deploy all services"
|
109
|
+
|
110
|
+
tags = [specific_service_option, all_services_option]
|
111
|
+
tags += service_store
|
112
|
+
.all_definitions
|
113
|
+
.values
|
114
|
+
.map(&:to_service_attrs)
|
115
|
+
.map(&:tags)
|
116
|
+
.flatten
|
117
|
+
.uniq
|
118
|
+
.sort
|
119
|
+
.map(&:to_s)
|
120
|
+
|
121
|
+
selected_tag = ui.prompt("Please select which tag to deploy", tags)
|
122
|
+
|
123
|
+
if selected_tag == specific_service_option
|
124
|
+
show_service_selection
|
125
|
+
elsif selected_tag == all_services_option
|
126
|
+
[["*"], []]
|
127
|
+
else
|
128
|
+
[[], [selected_tag]]
|
129
|
+
end
|
124
130
|
end
|
125
131
|
|
126
|
-
|
127
|
-
|
128
|
-
|
132
|
+
def show_service_selection()
|
133
|
+
services = service_store
|
134
|
+
.all_definitions
|
135
|
+
.values
|
136
|
+
.map(&:service_name)
|
137
|
+
.uniq
|
138
|
+
.sort
|
139
|
+
.map(&:to_s)
|
140
|
+
|
141
|
+
if services.empty?
|
142
|
+
return [[], []]
|
143
|
+
end
|
144
|
+
|
145
|
+
selected_service = ui.prompt("Please select which service to deploy", services)
|
146
|
+
[[selected_service], []]
|
147
|
+
end
|
129
148
|
end
|
data/lib/kuber_kit/cli.rb
CHANGED
@@ -30,7 +30,7 @@ class KuberKit::CLI < Thor
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
desc "deploy -t
|
33
|
+
desc "deploy -t TAG_NAME", "Deploy CONTEXT_NAME with kubectl"
|
34
34
|
method_option :services, :type => :array, aliases: ["-s"], repeatable: true
|
35
35
|
method_option :tags, :type => :array, aliases: ["-t"], repeatable: true
|
36
36
|
method_option :skip_compile, :type => :boolean, aliases: ["-B"]
|
@@ -86,6 +86,15 @@ class KuberKit::CLI < Thor
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
desc "check", "Check to make sure that all services are deployed"
|
90
|
+
def check()
|
91
|
+
setup(options)
|
92
|
+
|
93
|
+
if KuberKit::Container['actions.configuration_loader'].call(options)
|
94
|
+
KuberKit::Container['actions.service_checker'].call(options)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
89
98
|
desc "apply FILE_PATH", "Apply FILE_PATH with kubectl"
|
90
99
|
def apply(file_path)
|
91
100
|
setup(options)
|
@@ -132,6 +141,24 @@ class KuberKit::CLI < Thor
|
|
132
141
|
end
|
133
142
|
end
|
134
143
|
|
144
|
+
desc "env", "Show environment variables for given configuration"
|
145
|
+
def env()
|
146
|
+
setup(options)
|
147
|
+
|
148
|
+
if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
|
149
|
+
KuberKit::Container['actions.kubectl_env'].call(options)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "get RESOURCE_NAME", "List pods matching RESOURCE_NAME using kubectl"
|
154
|
+
def get(pod_name = nil)
|
155
|
+
setup(options)
|
156
|
+
|
157
|
+
if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
|
158
|
+
KuberKit::Container['actions.kubectl_get'].call(pod_name, options)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
135
162
|
desc "version", "Print current version"
|
136
163
|
def version
|
137
164
|
puts KuberKit::VERSION
|
data/lib/kuber_kit/configs.rb
CHANGED
@@ -4,7 +4,7 @@ class KuberKit::Configs
|
|
4
4
|
AVAILABLE_CONFIGS = [
|
5
5
|
:image_dockerfile_name, :image_build_context_dir, :image_tag, :docker_ignore_list, :image_compile_dir,
|
6
6
|
:kuber_kit_dirname, :kuber_kit_min_version, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
|
7
|
-
:artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit,
|
7
|
+
:artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit, :deploy_simultaneous_limit,
|
8
8
|
:additional_images_paths, :deprecation_warnings_disabled, :log_file_path
|
9
9
|
]
|
10
10
|
DOCKER_IGNORE_LIST = [
|
@@ -49,6 +49,7 @@ class KuberKit::Configs
|
|
49
49
|
set :service_config_dir, "/tmp/kuber_kit/services"
|
50
50
|
set :deployer_strategy, :kubernetes
|
51
51
|
set :compile_simultaneous_limit, 5
|
52
|
+
set :deploy_simultaneous_limit, 5
|
52
53
|
set :additional_images_paths, []
|
53
54
|
set :deprecation_warnings_disabled, false
|
54
55
|
set :log_file_path, "/tmp/kuber_kit.log"
|
data/lib/kuber_kit/container.rb
CHANGED
@@ -21,6 +21,10 @@ class KuberKit::Container
|
|
21
21
|
KuberKit::Actions::ServiceDeployer.new
|
22
22
|
end
|
23
23
|
|
24
|
+
register "actions.service_checker" do
|
25
|
+
KuberKit::Actions::ServiceChecker.new
|
26
|
+
end
|
27
|
+
|
24
28
|
register "actions.configuration_loader" do
|
25
29
|
KuberKit::Actions::ConfigurationLoader.new
|
26
30
|
end
|
@@ -41,10 +45,18 @@ class KuberKit::Container
|
|
41
45
|
KuberKit::Actions::KubectlDescribe.new
|
42
46
|
end
|
43
47
|
|
48
|
+
register "actions.kubectl_get" do
|
49
|
+
KuberKit::Actions::KubectlGet.new
|
50
|
+
end
|
51
|
+
|
44
52
|
register "actions.kubectl_logs" do
|
45
53
|
KuberKit::Actions::KubectlLogs.new
|
46
54
|
end
|
47
55
|
|
56
|
+
register "actions.kubectl_env" do
|
57
|
+
KuberKit::Actions::KubectlEnv.new
|
58
|
+
end
|
59
|
+
|
48
60
|
register "configs" do
|
49
61
|
KuberKit::Configs.new
|
50
62
|
end
|
@@ -249,6 +261,10 @@ class KuberKit::Container
|
|
249
261
|
KuberKit::ServiceDeployer::ServiceListResolver.new
|
250
262
|
end
|
251
263
|
|
264
|
+
register "service_deployer.service_dependency_resolver" do
|
265
|
+
KuberKit::ServiceDeployer::ServiceDependencyResolver.new
|
266
|
+
end
|
267
|
+
|
252
268
|
register "service_deployer.strategies.kubernetes" do
|
253
269
|
KuberKit::ServiceDeployer::Strategies::Kubernetes.new
|
254
270
|
end
|
@@ -269,6 +285,10 @@ class KuberKit::Container
|
|
269
285
|
KuberKit::ServiceReader::Reader.new
|
270
286
|
end
|
271
287
|
|
288
|
+
register "kubernetes.resource_selector" do
|
289
|
+
KuberKit::Kubernetes::ResourceSelector.new
|
290
|
+
end
|
291
|
+
|
272
292
|
register "kubernetes.resources_fetcher" do
|
273
293
|
KuberKit::Kubernetes::ResourcesFetcher.new
|
274
294
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class KuberKit::Core::Configuration
|
2
2
|
attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path,
|
3
|
-
:services_attributes, :enabled_services, :build_servers, :global_build_vars,
|
3
|
+
:services_attributes, :enabled_services, :disabled_services, :build_servers, :global_build_vars,
|
4
4
|
:deployer_strategy, :deployer_namespace, :deployer_require_confirimation
|
5
5
|
|
6
6
|
Contract KeywordArgs[
|
@@ -12,6 +12,7 @@ class KuberKit::Core::Configuration
|
|
12
12
|
kubeconfig_path: Maybe[String],
|
13
13
|
services_attributes: HashOf[Symbol => Hash],
|
14
14
|
enabled_services: ArrayOf[Symbol],
|
15
|
+
disabled_services: ArrayOf[Symbol],
|
15
16
|
build_servers: ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer],
|
16
17
|
global_build_vars: HashOf[Symbol => Any],
|
17
18
|
deployer_strategy: Symbol,
|
@@ -19,7 +20,7 @@ class KuberKit::Core::Configuration
|
|
19
20
|
deployer_require_confirimation: Bool,
|
20
21
|
] => Any
|
21
22
|
def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:,
|
22
|
-
services_attributes:, enabled_services:, build_servers:, global_build_vars:,
|
23
|
+
services_attributes:, enabled_services:, disabled_services:, build_servers:, global_build_vars:,
|
23
24
|
deployer_strategy:, deployer_namespace:, deployer_require_confirimation:)
|
24
25
|
@name = name
|
25
26
|
@artifacts = artifacts
|
@@ -30,6 +31,7 @@ class KuberKit::Core::Configuration
|
|
30
31
|
@build_servers = build_servers
|
31
32
|
@services_attributes = services_attributes
|
32
33
|
@enabled_services = enabled_services
|
34
|
+
@disabled_services = disabled_services
|
33
35
|
@global_build_vars = global_build_vars
|
34
36
|
@deployer_strategy = deployer_strategy
|
35
37
|
@deployer_namespace = deployer_namespace
|
@@ -12,6 +12,7 @@ class KuberKit::Core::ConfigurationDefinition
|
|
12
12
|
@templates = {}
|
13
13
|
@build_servers = []
|
14
14
|
@enabled_services = []
|
15
|
+
@disabled_services = []
|
15
16
|
@services_attributes = {}
|
16
17
|
end
|
17
18
|
|
@@ -24,6 +25,7 @@ class KuberKit::Core::ConfigurationDefinition
|
|
24
25
|
templates: @templates,
|
25
26
|
kubeconfig_path: @kubeconfig_path,
|
26
27
|
enabled_services: @enabled_services,
|
28
|
+
disabled_services: @disabled_services,
|
27
29
|
build_servers: @build_servers,
|
28
30
|
services_attributes: @services_attributes,
|
29
31
|
global_build_vars: @global_build_vars,
|
@@ -116,6 +118,11 @@ class KuberKit::Core::ConfigurationDefinition
|
|
116
118
|
raise KuberKit::Error, "#enabled_services method accepts only Array or Hash"
|
117
119
|
end
|
118
120
|
|
121
|
+
def disabled_services(services)
|
122
|
+
@disabled_services += services.map(&:to_sym)
|
123
|
+
return self
|
124
|
+
end
|
125
|
+
|
119
126
|
def service_attributes(services)
|
120
127
|
@services_attributes = @services_attributes.merge(services)
|
121
128
|
self
|
@@ -29,6 +29,7 @@ class KuberKit::Core::ConfigurationFactory
|
|
29
29
|
build_servers: build_servers,
|
30
30
|
services_attributes: configuration_attrs.services_attributes,
|
31
31
|
enabled_services: configuration_attrs.enabled_services,
|
32
|
+
disabled_services: configuration_attrs.disabled_services,
|
32
33
|
global_build_vars: configuration_attrs.global_build_vars || {},
|
33
34
|
deployer_strategy: configuration_attrs.deployer_strategy || configs.deployer_strategy,
|
34
35
|
deployer_namespace: configuration_attrs.deployer_namespace,
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class KuberKit::Core::Dependencies::AbstractDependencyResolver
|
2
|
+
CircularDependencyError = Class.new(KuberKit::Error)
|
3
|
+
DependencyNotFoundError = Class.new(KuberKit::NotFoundError)
|
4
|
+
|
5
|
+
# Iterate over list of dependencies for items (including the items themself).
|
6
|
+
# Iteration will send the list to the callback block function
|
7
|
+
Contract Or[Symbol, ArrayOf[Symbol]], Proc => Any
|
8
|
+
def each_with_deps(item_names, &block)
|
9
|
+
resolved_dependencies = []
|
10
|
+
# Get first list of dependencies ready to resolve
|
11
|
+
next_dependencies = get_next(item_names, limit: dependency_batch_size)
|
12
|
+
|
13
|
+
# Call the block for each list of dependencies ready to resolve, then calculate the next list
|
14
|
+
while (next_dependencies - resolved_dependencies).any?
|
15
|
+
block.call(next_dependencies)
|
16
|
+
resolved_dependencies += next_dependencies
|
17
|
+
next_dependencies = get_next(item_names, resolved: resolved_dependencies, limit: dependency_batch_size)
|
18
|
+
end
|
19
|
+
|
20
|
+
(item_names - resolved_dependencies).each_slice(dependency_batch_size) do |group|
|
21
|
+
block.call(group)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns next list of dependencies ready to resolve.
|
26
|
+
# Item is not ready to resolve if it has personal dependency.
|
27
|
+
# E.g. if "A" depends on "B" and "C", "C" depends on "D", then only "B" and "D" will be returned.
|
28
|
+
Contract Or[Symbol, ArrayOf[Symbol]], KeywordArgs[
|
29
|
+
resolved: Optional[ArrayOf[Symbol]],
|
30
|
+
limit: Optional[Maybe[Num]]
|
31
|
+
] => Any
|
32
|
+
def get_next(item_names, resolved: [], limit: nil)
|
33
|
+
deps = Array(item_names).map { |i| get_recursive_deps(i) }.flatten.uniq
|
34
|
+
|
35
|
+
# Find out which dependencies are ready to resolve,
|
36
|
+
# they should not have unresolved personal dependencies
|
37
|
+
ready_to_resolve = deps.select do |dep_name|
|
38
|
+
unresolved_deps = get_deps(dep_name) - resolved
|
39
|
+
unresolved_deps.empty?
|
40
|
+
end
|
41
|
+
unresolved_deps = ready_to_resolve - resolved
|
42
|
+
unresolved_deps = unresolved_deps.take(limit) if limit
|
43
|
+
unresolved_deps
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get all dependencies for items (including the items themself), without any limitations
|
47
|
+
Contract Or[Symbol, ArrayOf[Symbol]] => Any
|
48
|
+
def get_all(item_names)
|
49
|
+
deps = Array(item_names).map { |i| get_recursive_deps(i) }.flatten
|
50
|
+
(deps + item_names).uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_recursive_deps(item_name, dependency_tree: [])
|
54
|
+
deps = get_deps(item_name)
|
55
|
+
|
56
|
+
if dependency_tree.include?(item_name)
|
57
|
+
raise CircularDependencyError, "Circular dependency found for #{item_name}. Dependency tree: #{dependency_tree.inspect}"
|
58
|
+
end
|
59
|
+
|
60
|
+
child_deps = []
|
61
|
+
deps.each do |i|
|
62
|
+
child_deps += get_recursive_deps(i, dependency_tree: dependency_tree + [item_name])
|
63
|
+
end
|
64
|
+
|
65
|
+
(deps + child_deps).uniq
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_deps(item_name)
|
69
|
+
raise "This method should be overriden"
|
70
|
+
end
|
71
|
+
|
72
|
+
def dependency_batch_size
|
73
|
+
raise "This method should be overriden"
|
74
|
+
end
|
75
|
+
end
|
data/lib/kuber_kit/core/image.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class KuberKit::Core::Image
|
2
|
-
attr_reader :name, :dependencies, :registry, :dockerfile_path, :build_vars, :build_context_dir, :tag,
|
2
|
+
attr_reader :name, :dependencies, :registry, :dockerfile_path, :build_vars, :build_context_dir, :tag,
|
3
|
+
:before_build_callback, :after_build_callback
|
3
4
|
|
4
5
|
Contract KeywordArgs[
|
5
6
|
name: Symbol,
|
@@ -1,18 +1,20 @@
|
|
1
1
|
class KuberKit::Core::Service
|
2
2
|
AttributeNotSet = Class.new(Indocker::Error)
|
3
3
|
|
4
|
-
attr_reader :name, :template_name, :tags, :images, :attributes, :deployer_strategy
|
4
|
+
attr_reader :name, :dependencies, :template_name, :tags, :images, :attributes, :deployer_strategy
|
5
5
|
|
6
6
|
Contract KeywordArgs[
|
7
7
|
name: Symbol,
|
8
|
+
dependencies: ArrayOf[Symbol],
|
8
9
|
template_name: Maybe[Symbol],
|
9
10
|
tags: ArrayOf[Symbol],
|
10
11
|
images: ArrayOf[Symbol],
|
11
12
|
attributes: HashOf[Symbol => Any],
|
12
13
|
deployer_strategy: Maybe[Symbol]
|
13
14
|
] => Any
|
14
|
-
def initialize(name:, template_name:, tags:, images:, attributes:, deployer_strategy:)
|
15
|
+
def initialize(name:, dependencies:, template_name:, tags:, images:, attributes:, deployer_strategy:)
|
15
16
|
@name = name
|
17
|
+
@dependencies = dependencies
|
16
18
|
@template_name = template_name
|
17
19
|
@tags = tags
|
18
20
|
@images = images
|
@@ -1,22 +1,29 @@
|
|
1
1
|
class KuberKit::Core::ServiceDefinition
|
2
|
-
attr_reader :service_name, :template_name
|
2
|
+
attr_reader :service_name, :template_name, :dependencies
|
3
3
|
|
4
4
|
Contract Or[Symbol, String] => Any
|
5
5
|
def initialize(service_name)
|
6
6
|
@service_name = service_name.to_sym
|
7
|
+
@dependencies = []
|
7
8
|
end
|
8
9
|
|
9
10
|
def to_service_attrs
|
10
11
|
OpenStruct.new(
|
11
|
-
name:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
name: @service_name,
|
13
|
+
dependencies: @dependencies,
|
14
|
+
template_name: get_value(@template_name),
|
15
|
+
tags: Array(get_value(@tags)).map(&:to_sym),
|
16
|
+
images: Array(get_value(@images)).map(&:to_sym),
|
17
|
+
attributes: get_value(@attributes),
|
16
18
|
deployer_strategy: get_value(@deployer_strategy),
|
17
19
|
)
|
18
20
|
end
|
19
21
|
|
22
|
+
def depends_on(*value, &block)
|
23
|
+
@dependencies = Array(value).flatten
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
20
27
|
def template(value = nil, &block)
|
21
28
|
@template_name = block_given? ? block : value
|
22
29
|
|
@@ -1,62 +1,14 @@
|
|
1
|
-
class KuberKit::ImageCompiler::ImageDependencyResolver
|
2
|
-
CircularDependencyError = Class.new(KuberKit::Error)
|
3
|
-
DependencyNotFoundError = Class.new(KuberKit::NotFoundError)
|
4
|
-
|
1
|
+
class KuberKit::ImageCompiler::ImageDependencyResolver < KuberKit::Core::Dependencies::AbstractDependencyResolver
|
5
2
|
include KuberKit::Import[
|
6
3
|
"core.image_store",
|
7
4
|
"configs"
|
8
5
|
]
|
9
|
-
|
10
|
-
Contract Or[Symbol, ArrayOf[Symbol]], Proc => Any
|
11
|
-
def each_with_deps(image_names, &block)
|
12
|
-
compile_limit = configs.compile_simultaneous_limit
|
13
|
-
|
14
|
-
resolved_dependencies = []
|
15
|
-
next_dependencies = get_next(image_names, limit: compile_limit)
|
16
|
-
|
17
|
-
while (next_dependencies - resolved_dependencies).any?
|
18
|
-
block.call(next_dependencies)
|
19
|
-
resolved_dependencies += next_dependencies
|
20
|
-
next_dependencies = get_next(image_names, resolved: resolved_dependencies, limit: compile_limit)
|
21
|
-
end
|
22
|
-
|
23
|
-
(image_names - resolved_dependencies).each_slice(compile_limit) do |group|
|
24
|
-
block.call(group)
|
25
|
-
end
|
26
|
-
end
|
27
6
|
|
28
|
-
Contract Or[Symbol, ArrayOf[Symbol]], KeywordArgs[
|
29
|
-
resolved: Optional[ArrayOf[Symbol]],
|
30
|
-
limit: Optional[Maybe[Num]]
|
31
|
-
] => Any
|
32
|
-
def get_next(image_names, resolved: [], limit: nil)
|
33
|
-
deps = Array(image_names).map { |i| get_recursive_deps(i) }.flatten.uniq
|
34
|
-
|
35
|
-
ready_to_resolve = deps.select do |dep_name|
|
36
|
-
unresolved_deps = get_deps(dep_name) - resolved
|
37
|
-
unresolved_deps.empty?
|
38
|
-
end
|
39
|
-
unresolved_deps = ready_to_resolve - resolved
|
40
|
-
unresolved_deps = unresolved_deps.take(limit) if limit
|
41
|
-
unresolved_deps
|
42
|
-
end
|
43
|
-
|
44
|
-
def get_recursive_deps(image_name, dependency_tree: [])
|
45
|
-
deps = get_deps(image_name)
|
46
|
-
|
47
|
-
if dependency_tree.include?(image_name)
|
48
|
-
raise CircularDependencyError, "Circular dependency found for #{image_name}. Dependency tree: #{dependency_tree.inspect}"
|
49
|
-
end
|
50
|
-
|
51
|
-
child_deps = []
|
52
|
-
deps.each do |i|
|
53
|
-
child_deps += get_recursive_deps(i, dependency_tree: dependency_tree + [image_name])
|
54
|
-
end
|
55
|
-
|
56
|
-
(deps + child_deps).uniq
|
57
|
-
end
|
58
|
-
|
59
7
|
def get_deps(image_name)
|
60
8
|
image_store.get_definition(image_name).dependencies
|
61
9
|
end
|
10
|
+
|
11
|
+
def dependency_batch_size
|
12
|
+
configs.compile_simultaneous_limit
|
13
|
+
end
|
62
14
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class KuberKit::Kubernetes::ResourceSelector
|
2
|
+
include KuberKit::Import[
|
3
|
+
"kubernetes.resources_fetcher",
|
4
|
+
"shell.local_shell",
|
5
|
+
"ui"
|
6
|
+
]
|
7
|
+
|
8
|
+
Contract String, KeywordArgs[
|
9
|
+
include_ingresses: Optional[Bool],
|
10
|
+
include_pods: Optional[Bool]
|
11
|
+
] => Any
|
12
|
+
def call(action_name, include_ingresses: false, include_pods: false)
|
13
|
+
deployments = resources_fetcher.call("deployments")
|
14
|
+
options = deployments.map{|d| "deploy/#{d}" }
|
15
|
+
options << "ingresses" if include_ingresses
|
16
|
+
options << "pods" if include_pods
|
17
|
+
option = ui.prompt("Please select resource to #{action_name}", options)
|
18
|
+
|
19
|
+
if option == "ingresses" && include_ingresses
|
20
|
+
ingresses = resources_fetcher.call("ingresses")
|
21
|
+
options = ingresses.map{|d| "ingresses/#{d}" }
|
22
|
+
return ui.prompt("Please select ingress to #{action_name}", options)
|
23
|
+
end
|
24
|
+
|
25
|
+
if option == "pods" && include_pods
|
26
|
+
ingresses = resources_fetcher.call("pods")
|
27
|
+
options = ingresses.map{|d| "pods/#{d}" }
|
28
|
+
return ui.prompt("Please select pod to #{action_name}", options)
|
29
|
+
end
|
30
|
+
|
31
|
+
option
|
32
|
+
end
|
33
|
+
end
|
@@ -2,40 +2,17 @@ class KuberKit::Kubernetes::ResourcesFetcher
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"shell.kubectl_commands",
|
4
4
|
"shell.local_shell",
|
5
|
-
"ui"
|
6
5
|
]
|
7
6
|
|
8
|
-
Contract String
|
9
|
-
|
10
|
-
|
11
|
-
] => Any
|
12
|
-
def call(action_name, include_ingresses: false, include_pods: false)
|
13
|
-
deployments = get_resources("deployments")
|
14
|
-
options = deployments.split(" ").map{|d| "deploy/#{d}" }
|
15
|
-
options << "ingresses" if include_ingresses
|
16
|
-
options << "pods" if include_pods
|
17
|
-
option = ui.prompt("Please select resource to #{action_name}", options)
|
18
|
-
|
19
|
-
if option == "ingresses" && include_ingresses
|
20
|
-
ingresses = get_resources("ingresses")
|
21
|
-
options = ingresses.split(" ").map{|d| "ingresses/#{d}" }
|
22
|
-
return ui.prompt("Please select ingress to #{action_name}", options)
|
23
|
-
end
|
24
|
-
|
25
|
-
if option == "pods" && include_pods
|
26
|
-
ingresses = get_resources("pods")
|
27
|
-
options = ingresses.split(" ").map{|d| "pods/#{d}" }
|
28
|
-
return ui.prompt("Please select pod to #{action_name}", options)
|
29
|
-
end
|
7
|
+
Contract String => ArrayOf[String]
|
8
|
+
def call(resource_type)
|
9
|
+
current_configuration = KuberKit.current_configuration
|
30
10
|
|
31
|
-
option
|
32
|
-
end
|
33
|
-
|
34
|
-
def get_resources(type)
|
35
11
|
kubectl_commands.get_resources(
|
36
|
-
local_shell,
|
37
|
-
jsonpath:
|
38
|
-
|
12
|
+
local_shell, resource_type,
|
13
|
+
jsonpath: ".items[*].metadata.name",
|
14
|
+
kubeconfig_path: current_configuration.kubeconfig_path,
|
15
|
+
namespace: current_configuration.deployer_namespace
|
39
16
|
)
|
40
17
|
end
|
41
18
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class KuberKit::ServiceDeployer::ServiceDependencyResolver < KuberKit::Core::Dependencies::AbstractDependencyResolver
|
2
|
+
include KuberKit::Import[
|
3
|
+
"core.service_store",
|
4
|
+
"configs"
|
5
|
+
]
|
6
|
+
|
7
|
+
def get_deps(service_name)
|
8
|
+
service_store.get_definition(service_name).dependencies
|
9
|
+
end
|
10
|
+
|
11
|
+
def dependency_batch_size
|
12
|
+
configs.deploy_simultaneous_limit
|
13
|
+
end
|
14
|
+
end
|
@@ -4,11 +4,12 @@ class KuberKit::ServiceDeployer::ServiceListResolver
|
|
4
4
|
]
|
5
5
|
|
6
6
|
Contract KeywordArgs[
|
7
|
-
services:
|
8
|
-
tags:
|
9
|
-
enabled_services:
|
7
|
+
services: Optional[ArrayOf[String]],
|
8
|
+
tags: Optional[ArrayOf[String]],
|
9
|
+
enabled_services: Optional[ArrayOf[String]],
|
10
|
+
disabled_services: Optional[ArrayOf[String]]
|
10
11
|
] => ArrayOf[String]
|
11
|
-
def resolve(services: [], tags: [], enabled_services: [])
|
12
|
+
def resolve(services: [], tags: [], enabled_services: [], disabled_services: [])
|
12
13
|
all_definitions = service_store.all_definitions.values
|
13
14
|
|
14
15
|
included_services, excluded_services = split_by_inclusion(services)
|
@@ -36,14 +37,18 @@ class KuberKit::ServiceDeployer::ServiceListResolver
|
|
36
37
|
included_services = included_services.select{ |s| enabled_services.include?(s) }
|
37
38
|
end
|
38
39
|
|
40
|
+
if disabled_services.any?
|
41
|
+
included_services = included_services.select{ |s| !disabled_services.include?(s) }
|
42
|
+
end
|
43
|
+
|
39
44
|
included_services
|
40
45
|
end
|
41
46
|
|
42
47
|
Contract Array => Array
|
43
48
|
def split_by_inclusion(array)
|
44
|
-
excluded, included = array.partition{|e| e.start_with?('
|
49
|
+
excluded, included = array.partition{|e| e.start_with?('!') }
|
45
50
|
|
46
|
-
excluded.map!{ |item| item.gsub(
|
51
|
+
excluded.map!{ |item| item.gsub(/^\!/, "") }
|
47
52
|
|
48
53
|
[included, excluded]
|
49
54
|
end
|
@@ -9,7 +9,8 @@ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeplo
|
|
9
9
|
:resource_type,
|
10
10
|
:resource_name,
|
11
11
|
:delete_if_exists,
|
12
|
-
:restart_if_exists
|
12
|
+
:restart_if_exists,
|
13
|
+
:wait_for_rollout
|
13
14
|
]
|
14
15
|
|
15
16
|
Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
|
@@ -41,12 +42,18 @@ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeplo
|
|
41
42
|
|
42
43
|
apply_result = kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
43
44
|
|
44
|
-
restart_enabled
|
45
|
+
restart_enabled = strategy_options.fetch(:restart_if_exists, true)
|
46
|
+
wait_for_rollout = strategy_options.fetch(:wait_for_rollout, true)
|
45
47
|
if restart_enabled && resource_exists
|
46
48
|
kubectl_commands.rolling_restart(
|
47
49
|
shell, resource_type, resource_name,
|
48
50
|
kubeconfig_path: kubeconfig_path, namespace: namespace
|
49
51
|
)
|
52
|
+
|
53
|
+
kubectl_commands.rollout_status(
|
54
|
+
shell, resource_type, resource_name, wait: true,
|
55
|
+
kubeconfig_path: kubeconfig_path, namespace: namespace
|
56
|
+
) if wait_for_rollout
|
50
57
|
end
|
51
58
|
|
52
59
|
apply_result
|
@@ -60,19 +60,19 @@ class KuberKit::Shell::Commands::KubectlCommands
|
|
60
60
|
command_parts << "-o jsonpath='{#{jsonpath}}'"
|
61
61
|
end
|
62
62
|
|
63
|
-
result = kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
63
|
+
result = kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace).to_s
|
64
64
|
|
65
65
|
# Hide warnings manually, until appropriate kubectl option will be available
|
66
|
-
result = result.split("\n").reject{|n| n.start_with?("Warning:") }.join("\n")
|
66
|
+
result = result.split("\n").reject{|n| n.start_with?("Warning:") }.join("\n")
|
67
67
|
|
68
|
-
result
|
68
|
+
Array(result.split(" ")).reject(&:empty?)
|
69
69
|
end
|
70
70
|
|
71
71
|
def resource_exists?(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
|
72
72
|
result = get_resources(shell, resource_type,
|
73
73
|
field_selector: "metadata.name=#{resource_name}", kubeconfig_path: kubeconfig_path, namespace: namespace
|
74
74
|
)
|
75
|
-
result
|
75
|
+
result.any?
|
76
76
|
end
|
77
77
|
|
78
78
|
def delete_resource(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
|
@@ -102,4 +102,12 @@ class KuberKit::Shell::Commands::KubectlCommands
|
|
102
102
|
}
|
103
103
|
}, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
104
104
|
end
|
105
|
+
|
106
|
+
def rollout_status(shell, resource_type, resource_name, wait: true, kubeconfig_path: nil, namespace: nil)
|
107
|
+
command_parts = []
|
108
|
+
command_parts << %Q{rollout status #{resource_type} #{resource_name}}
|
109
|
+
command_parts << "-w" if wait
|
110
|
+
|
111
|
+
kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace)
|
112
|
+
end
|
105
113
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
|
4
|
+
MAX_LINES_TO_PRINT = 50
|
5
|
+
|
4
6
|
include KuberKit::Import[
|
5
7
|
"shell.command_counter",
|
6
8
|
"shell.rsync_commands",
|
@@ -20,7 +22,19 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
|
|
20
22
|
end
|
21
23
|
|
22
24
|
if result && result != "" && log_command
|
23
|
-
|
25
|
+
print_result = result
|
26
|
+
print_result_lines = print_result.split("\n")
|
27
|
+
|
28
|
+
if print_result_lines.count >= MAX_LINES_TO_PRINT
|
29
|
+
print_result = [
|
30
|
+
"[Result is too long, showing only first and last items]".yellow,
|
31
|
+
print_result_lines.first,
|
32
|
+
"[#{print_result_lines.count - 2} lines not showing]".yellow,
|
33
|
+
print_result_lines.last
|
34
|
+
].join("\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
ui.print_debug("LocalShell", "Finished [#{command_number}] with result: \n ----\n#{print_result.grey}\n ----")
|
24
38
|
end
|
25
39
|
|
26
40
|
if $?.exitstatus != 0
|
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.5.4
|
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-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: contracts-lite
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- ".ruby-gemset"
|
166
166
|
- ".ruby-version"
|
167
167
|
- ".travis.yml"
|
168
|
+
- CHANGELOG.md
|
168
169
|
- Gemfile
|
169
170
|
- Gemfile.lock
|
170
171
|
- LICENSE.txt
|
@@ -209,7 +210,10 @@ files:
|
|
209
210
|
- lib/kuber_kit/actions/kubectl_attacher.rb
|
210
211
|
- lib/kuber_kit/actions/kubectl_console.rb
|
211
212
|
- lib/kuber_kit/actions/kubectl_describe.rb
|
213
|
+
- lib/kuber_kit/actions/kubectl_env.rb
|
214
|
+
- lib/kuber_kit/actions/kubectl_get.rb
|
212
215
|
- lib/kuber_kit/actions/kubectl_logs.rb
|
216
|
+
- lib/kuber_kit/actions/service_checker.rb
|
213
217
|
- lib/kuber_kit/actions/service_deployer.rb
|
214
218
|
- lib/kuber_kit/actions/service_reader.rb
|
215
219
|
- lib/kuber_kit/actions/template_reader.rb
|
@@ -237,6 +241,7 @@ files:
|
|
237
241
|
- lib/kuber_kit/core/context_helper/context_vars.rb
|
238
242
|
- lib/kuber_kit/core/context_helper/image_helper.rb
|
239
243
|
- lib/kuber_kit/core/context_helper/service_helper.rb
|
244
|
+
- lib/kuber_kit/core/dependencies/abstract_dependency_resolver.rb
|
240
245
|
- lib/kuber_kit/core/env_files/abstract_env_file.rb
|
241
246
|
- lib/kuber_kit/core/env_files/artifact_file.rb
|
242
247
|
- lib/kuber_kit/core/env_files/env_file_store.rb
|
@@ -273,11 +278,13 @@ files:
|
|
273
278
|
- lib/kuber_kit/image_compiler/image_builder.rb
|
274
279
|
- lib/kuber_kit/image_compiler/image_dependency_resolver.rb
|
275
280
|
- lib/kuber_kit/image_compiler/version_tag_builder.rb
|
281
|
+
- lib/kuber_kit/kubernetes/resource_selector.rb
|
276
282
|
- lib/kuber_kit/kubernetes/resources_fetcher.rb
|
277
283
|
- lib/kuber_kit/preprocessing/file_preprocessor.rb
|
278
284
|
- lib/kuber_kit/preprocessing/text_preprocessor.rb
|
279
285
|
- lib/kuber_kit/service_deployer/action_handler.rb
|
280
286
|
- lib/kuber_kit/service_deployer/deployer.rb
|
287
|
+
- lib/kuber_kit/service_deployer/service_dependency_resolver.rb
|
281
288
|
- lib/kuber_kit/service_deployer/service_list_resolver.rb
|
282
289
|
- lib/kuber_kit/service_deployer/strategies/abstract.rb
|
283
290
|
- lib/kuber_kit/service_deployer/strategies/docker.rb
|