kuber_kit 0.5.1 → 0.5.6

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/Gemfile.lock +5 -5
  4. data/TODO.md +5 -5
  5. data/example/configurations/review.rb +1 -1
  6. data/example/services/docker_app.rb +2 -1
  7. data/example/services/env_file.rb +1 -1
  8. data/example/services/ruby_app.rb +2 -1
  9. data/lib/kuber_kit.rb +10 -0
  10. data/lib/kuber_kit/actions/kubectl_get.rb +32 -0
  11. data/lib/kuber_kit/actions/service_checker.rb +5 -0
  12. data/lib/kuber_kit/actions/service_deployer.rb +85 -61
  13. data/lib/kuber_kit/cli.rb +14 -3
  14. data/lib/kuber_kit/configs.rb +10 -6
  15. data/lib/kuber_kit/container.rb +20 -0
  16. data/lib/kuber_kit/core/artifacts/artifact_store.rb +3 -0
  17. data/lib/kuber_kit/core/configuration.rb +4 -2
  18. data/lib/kuber_kit/core/configuration_definition.rb +7 -0
  19. data/lib/kuber_kit/core/configuration_factory.rb +1 -0
  20. data/lib/kuber_kit/core/dependencies/abstract_dependency_resolver.rb +75 -0
  21. data/lib/kuber_kit/core/env_files/abstract_env_file.rb +4 -0
  22. data/lib/kuber_kit/core/env_files/artifact_file.rb +4 -0
  23. data/lib/kuber_kit/core/env_files/env_file_store.rb +3 -0
  24. data/lib/kuber_kit/core/env_files/env_group.rb +12 -0
  25. data/lib/kuber_kit/core/image.rb +2 -1
  26. data/lib/kuber_kit/core/registries/registry_store.rb +3 -0
  27. data/lib/kuber_kit/core/service.rb +4 -2
  28. data/lib/kuber_kit/core/service_definition.rb +13 -6
  29. data/lib/kuber_kit/core/service_factory.rb +1 -0
  30. data/lib/kuber_kit/core/templates/template_store.rb +3 -0
  31. data/lib/kuber_kit/env_file_reader/env_file_parser.rb +51 -0
  32. data/lib/kuber_kit/env_file_reader/env_file_tempfile_creator.rb +17 -0
  33. data/lib/kuber_kit/env_file_reader/reader.rb +2 -0
  34. data/lib/kuber_kit/env_file_reader/strategies/artifact_file.rb +9 -65
  35. data/lib/kuber_kit/env_file_reader/strategies/env_group.rb +21 -0
  36. data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +5 -53
  37. data/lib/kuber_kit/service_deployer/service_dependency_resolver.rb +14 -0
  38. data/lib/kuber_kit/service_deployer/service_list_resolver.rb +11 -6
  39. data/lib/kuber_kit/service_deployer/strategies/docker.rb +31 -12
  40. data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +9 -2
  41. data/lib/kuber_kit/shell/commands/kubectl_commands.rb +8 -0
  42. data/lib/kuber_kit/shell/local_shell.rb +15 -1
  43. data/lib/kuber_kit/template_reader/strategies/artifact_file.rb +3 -3
  44. data/lib/kuber_kit/tools/logger_factory.rb +14 -0
  45. data/lib/kuber_kit/version.rb +1 -1
  46. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e92d48eb25df0740824ac18623687080cc2ae9336b6707057ad2be4d8b2c4dad
4
- data.tar.gz: 629b8c6f11674623d3348c390a5bc90776cc3844d45418bbc7311a268aa3fd1f
3
+ metadata.gz: 185201d6f305a1e69b2d5ec982288234454404bb9b87501130f159fb58a3b97a
4
+ data.tar.gz: e411255031c65afe38e7b0faa20e9b578b2d3eca93a3bb9dc013766a59c7d2b1
5
5
  SHA512:
6
- metadata.gz: 44e8c023ad85250859ce0d3029fefe69d285db34604cdfa2c61e4017f01e24c819f68f16397eccd5e89de59aba9ddc6d1b6dcd1d344842716696dce6bbcdee98
7
- data.tar.gz: 3d55ac2765022a978f6925ef477a727da2a8db12df383dc13703414fa66b989944c5fc452936a01b5d7ccf696313fae0f067e7507c482b1e45bba53fa0adcfc0
6
+ metadata.gz: 936fd6032488908db1fffe95f736dd05042c499f2995be2bc28566b2f65d9d5b35150acc0cf08de50442c16408d56d623292bb8e051215bfc15b8aba804266cc
7
+ data.tar.gz: c81b1a227cf5690d675b0b8d269382f0bb6d13ed71cfc3442679e1bd7471b995e02e7177b6c93bfb6955792bd591708c0ea017f9ea52291992bbbd0e5b33c0e2
data/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ **0.5.6**
2
+ - Pre-process env file if it has .erb extension
3
+ - Allow attaching env file from configuration to docker container
4
+ - Change default data paths to use home directory
5
+ - Add env groups support to combine multiple env files
6
+
7
+ **0.5.5**
8
+ - Added ability to skip services during deployment using -S option
9
+
10
+ **0.5.4**
11
+ - Added disabled services support
12
+
13
+ **0.5.3**
14
+ - Change the symbol to exclude service from "-" to "!", you can pass "-s !auth_app" to exclude "auth_app"
15
+ - Added kit get command to find pods
16
+
17
+ **0.5.2**
18
+ - Added dependencies support to services
19
+ - Added an option to deploy all services in `kit deloy`
20
+ - Wait for rollout to finish during service deploy
21
+ - 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.5.1)
4
+ kuber_kit (0.5.6)
5
5
  cli-ui
6
6
  contracts-lite
7
7
  dry-auto_inject
@@ -12,9 +12,9 @@ PATH
12
12
  GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
- cli-ui (1.4.0)
15
+ cli-ui (1.5.1)
16
16
  coderay (1.1.3)
17
- concurrent-ruby (1.1.8)
17
+ concurrent-ruby (1.1.9)
18
18
  contracts-lite (0.15.0)
19
19
  diff-lcs (1.4.4)
20
20
  docile (1.3.2)
@@ -26,7 +26,7 @@ GEM
26
26
  dry-container (0.7.2)
27
27
  concurrent-ruby (~> 1.0)
28
28
  dry-configurable (~> 0.1, >= 0.1.3)
29
- dry-core (0.5.0)
29
+ dry-core (0.6.0)
30
30
  concurrent-ruby (~> 1.0)
31
31
  method_source (1.0.0)
32
32
  net-ssh (6.1.0)
@@ -58,7 +58,7 @@ GEM
58
58
  thor (1.1.0)
59
59
  tty-color (0.6.0)
60
60
  tty-cursor (0.7.1)
61
- tty-prompt (0.23.0)
61
+ tty-prompt (0.23.1)
62
62
  pastel (~> 0.8)
63
63
  tty-reader (~> 0.8)
64
64
  tty-reader (0.9.0)
data/TODO.md CHANGED
@@ -1,8 +1,8 @@
1
- - do not show result for images list, if list is too large (Mikhail)
2
- - add kit get method for interactive kubernetes
3
- - kit status should show the list of services and their status, with ability to select & view logs
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
@@ -2,5 +2,5 @@ KuberKit
2
2
  .define_configuration(:review)
3
3
  .use_registry(:review_default, as: :default)
4
4
  .use_artifact(:kuber_kit_repo, as: :kuber_kit_repo)
5
- #.deployer_require_confirimation
5
+ .deployer_require_confirimation
6
6
  #.use_build_server(:remote_bs)
@@ -7,6 +7,7 @@ KuberKit
7
7
  detached: false,
8
8
  image_name: :ruby_app,
9
9
  container_name: "test_docker_app",
10
- delete_if_exists: true
10
+ delete_if_exists: true,
11
+ env_file_names: [:test]
11
12
  }
12
13
  )
@@ -1,7 +1,7 @@
1
1
  KuberKit
2
2
  .define_service(:env_file)
3
3
  .template(:env_file)
4
- .tags("env_file")
4
+ .tags("env_file", "minimal")
5
5
  .attributes(
6
6
  deployer_restart_enabled: false
7
7
  )
@@ -1,5 +1,6 @@
1
1
  KuberKit
2
2
  .define_service(:ruby_app)
3
+ .depends_on(:env_file)
3
4
  .template(:service)
4
5
  .images(:ruby_app)
5
- .tags("app")
6
+ .tags("app", "minimal")
data/lib/kuber_kit.rb CHANGED
@@ -46,10 +46,15 @@ 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'
52
56
  autoload :ArtifactFile, 'core/env_files/artifact_file'
57
+ autoload :EnvGroup, 'core/env_files/env_group'
53
58
  end
54
59
 
55
60
  module ContextHelper
@@ -123,10 +128,13 @@ module KuberKit
123
128
  module EnvFileReader
124
129
  autoload :ActionHandler, 'env_file_reader/action_handler'
125
130
  autoload :Reader, 'env_file_reader/reader'
131
+ autoload :EnvFileParser, 'env_file_reader/env_file_parser'
132
+ autoload :EnvFileTempfileCreator, 'env_file_reader/env_file_tempfile_creator'
126
133
 
127
134
  module Strategies
128
135
  autoload :Abstract, 'env_file_reader/strategies/abstract'
129
136
  autoload :ArtifactFile, 'env_file_reader/strategies/artifact_file'
137
+ autoload :EnvGroup, 'env_file_reader/strategies/env_group'
130
138
  end
131
139
  end
132
140
 
@@ -145,6 +153,7 @@ module KuberKit
145
153
  autoload :StrategyDetector, 'service_deployer/strategy_detector'
146
154
  autoload :Deployer, 'service_deployer/deployer'
147
155
  autoload :ServiceListResolver, 'service_deployer/service_list_resolver'
156
+ autoload :ServiceDependencyResolver, 'service_deployer/service_dependency_resolver'
148
157
 
149
158
  module Strategies
150
159
  autoload :Abstract, 'service_deployer/strategies/abstract'
@@ -171,6 +180,7 @@ module KuberKit
171
180
  autoload :KubectlAttacher, 'actions/kubectl_attacher'
172
181
  autoload :KubectlConsole, 'actions/kubectl_console'
173
182
  autoload :KubectlDescribe, 'actions/kubectl_describe'
183
+ autoload :KubectlGet, 'actions/kubectl_get'
174
184
  autoload :KubectlLogs, 'actions/kubectl_logs'
175
185
  autoload :KubectlEnv, 'actions/kubectl_env'
176
186
  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
@@ -15,6 +15,11 @@ class KuberKit::Actions::ServiceChecker
15
15
  services = services.select{ |s| enabled_services.include?(s) }
16
16
  end
17
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
+
18
23
  resources = resources_fetcher.call("deployments") + resources_fetcher.call("cronjobs")
19
24
 
20
25
  missing_services = services.select{ |s| !resources.include?(s.gsub("_", "-")) }
@@ -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
  ]
@@ -12,26 +14,37 @@ class KuberKit::Actions::ServiceDeployer
12
14
  Contract KeywordArgs[
13
15
  services: Maybe[ArrayOf[String]],
14
16
  tags: Maybe[ArrayOf[String]],
17
+ skip_services: Maybe[ArrayOf[String]],
15
18
  skip_compile: Maybe[Bool],
16
19
  require_confirmation: Maybe[Bool],
17
20
  ] => Any
18
- def call(services:, tags:, skip_compile: false, require_confirmation: false)
21
+ def call(services:, tags:, skip_services: nil, skip_compile: false, require_confirmation: false)
22
+ current_configuration = KuberKit.current_configuration
23
+
19
24
  if services.empty? && tags.empty?
20
25
  services, tags = show_tags_selection
21
26
  end
22
27
 
28
+
29
+ disabled_services = current_configuration.disabled_services.map(&:to_s)
30
+ disabled_services += skip_services if skip_services
31
+
23
32
  service_names = service_list_resolver.resolve(
24
33
  services: services || [],
25
34
  tags: tags || [],
26
- enabled_services: KuberKit.current_configuration.enabled_services.map(&:to_s)
27
- )
35
+ enabled_services: current_configuration.enabled_services.map(&:to_s),
36
+ disabled_services: disabled_services
37
+ ).map(&:to_sym)
38
+
39
+ # Return the list of services with all dependencies.
40
+ all_service_names = service_dependency_resolver.get_all(service_names)
28
41
 
29
- unless service_names.any?
42
+ unless all_service_names.any?
30
43
  ui.print_warning "ServiceDeployer", "No service found with given options, nothing will be deployed."
31
44
  return false
32
45
  end
33
46
 
34
- services_list = service_names.map(&:to_s).map(&:yellow).join(", ")
47
+ services_list = all_service_names.map(&:to_s).map(&:yellow).join(", ")
35
48
  ui.print_info "ServiceDeployer", "The following services will be deployed: #{services_list}"
36
49
 
37
50
  if require_confirmation
@@ -39,7 +52,7 @@ class KuberKit::Actions::ServiceDeployer
39
52
  return false unless ["confirm".green, "confirm", "yes"].include?(result)
40
53
  end
41
54
 
42
- services = service_names.map do |service_name|
55
+ services = all_service_names.map do |service_name|
43
56
  service_store.get_service(service_name.to_sym)
44
57
  end
45
58
 
@@ -50,9 +63,16 @@ class KuberKit::Actions::ServiceDeployer
50
63
  return false unless compile_result
51
64
  end
52
65
 
53
- deployment_result = deploy_services(service_names)
66
+ deployed_services = []
67
+ deployment_result = {}
68
+ service_dependency_resolver.each_with_deps(service_names) do |dep_service_names|
69
+ ui.print_debug("ServiceDeployer", "Scheduling to compile: #{dep_service_names.inspect}. Limit: #{configs.deploy_simultaneous_limit}")
70
+ result = deploy_simultaneously(dep_service_names)
71
+ deployed_services += dep_service_names
72
+ deployment_result = deployment_result.merge(result)
73
+ end
54
74
 
55
- { services: service_names, deployment: deployment_result }
75
+ { services: all_service_names, deployment: deployment_result }
56
76
  rescue KuberKit::Error => e
57
77
  ui.print_error("Error", e.message)
58
78
 
@@ -61,69 +81,73 @@ class KuberKit::Actions::ServiceDeployer
61
81
  process_cleaner.clean
62
82
  end
63
83
 
64
- def deploy_services(service_names)
65
- task_group = ui.create_task_group
84
+ private
85
+ def deploy_simultaneously(service_names)
86
+ task_group = ui.create_task_group
66
87
 
67
- deployer_result = {}
88
+ deployer_result = {}
68
89
 
69
- service_names.each do |service_name|
90
+ service_names.each do |service_name|
70
91
 
71
- ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
72
- task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
73
- deployer_result[service_name] = service_deployer.call(local_shell, service_name.to_sym)
92
+ ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
93
+ task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
94
+ deployer_result[service_name] = service_deployer.call(local_shell, service_name.to_sym)
74
95
 
75
- task.update_title("Deployed #{service_name.to_s.green}")
76
- ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
96
+ task.update_title("Deployed #{service_name.to_s.green}")
97
+ ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
98
+ end
77
99
  end
78
- end
79
100
 
80
- task_group.wait
81
-
82
- deployer_result
83
- end
101
+ task_group.wait
84
102
 
85
- def compile_images(images_names)
86
- return true if images_names.empty?
87
- image_compiler.call(images_names, {})
88
- end
103
+ deployer_result
104
+ end
89
105
 
90
- def show_tags_selection()
91
- specific_service_option = "deploy specific service"
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]]
106
+ def compile_images(images_names)
107
+ return true if images_names.empty?
108
+ image_compiler.call(images_names, {})
110
109
  end
111
- end
112
110
 
113
- def show_service_selection()
114
- services = service_store
115
- .all_definitions
116
- .values
117
- .map(&:service_name)
118
- .uniq
119
- .sort
120
- .map(&:to_s)
121
-
122
- if services.empty?
123
- return [[], []]
111
+ def show_tags_selection()
112
+ specific_service_option = "deploy specific service"
113
+ all_services_option = "deploy all services"
114
+
115
+ tags = [specific_service_option, all_services_option]
116
+ tags += service_store
117
+ .all_definitions
118
+ .values
119
+ .map(&:to_service_attrs)
120
+ .map(&:tags)
121
+ .flatten
122
+ .uniq
123
+ .sort
124
+ .map(&:to_s)
125
+
126
+ selected_tag = ui.prompt("Please select which tag to deploy", tags)
127
+
128
+ if selected_tag == specific_service_option
129
+ show_service_selection
130
+ elsif selected_tag == all_services_option
131
+ [["*"], []]
132
+ else
133
+ [[], [selected_tag]]
134
+ end
124
135
  end
125
136
 
126
- selected_service = ui.prompt("Please select which service to deploy", services)
127
- [[selected_service], []]
128
- end
137
+ def show_service_selection()
138
+ services = service_store
139
+ .all_definitions
140
+ .values
141
+ .map(&:service_name)
142
+ .uniq
143
+ .sort
144
+ .map(&:to_s)
145
+
146
+ if services.empty?
147
+ return [[], []]
148
+ end
149
+
150
+ selected_service = ui.prompt("Please select which service to deploy", services)
151
+ [[selected_service], []]
152
+ end
129
153
  end
data/lib/kuber_kit/cli.rb CHANGED
@@ -30,9 +30,10 @@ class KuberKit::CLI < Thor
30
30
  end
31
31
  end
32
32
 
33
- desc "deploy -t CONTEXT_NAME", "Deploy CONTEXT_NAME with kubectl"
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
+ method_option :skip_services, :type => :array, aliases: ["-S"], repeatable: true
36
37
  method_option :skip_compile, :type => :boolean, aliases: ["-B"]
37
38
  method_option :require_confirmation, :type => :boolean, aliases: ["-r"]
38
39
  def deploy
@@ -46,6 +47,7 @@ class KuberKit::CLI < Thor
46
47
  result = KuberKit::Container['actions.service_deployer'].call(
47
48
  services: (options[:services] || []).flatten.uniq,
48
49
  tags: (options[:tags] || []).flatten.uniq,
50
+ skip_services: (options[:skip_services] || []).flatten.uniq,
49
51
  skip_compile: options[:skip_compile] || false,
50
52
  require_confirmation: require_confirmation
51
53
  )
@@ -59,8 +61,8 @@ class KuberKit::CLI < Thor
59
61
  end
60
62
  end
61
63
 
62
- desc "env ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
63
- def env(env_file_name)
64
+ desc "envfile ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
65
+ def envfile(env_file_name)
64
66
  setup(options)
65
67
 
66
68
  if KuberKit::Container['actions.configuration_loader'].call(options)
@@ -150,6 +152,15 @@ class KuberKit::CLI < Thor
150
152
  end
151
153
  end
152
154
 
155
+ desc "get RESOURCE_NAME", "List pods matching RESOURCE_NAME using kubectl"
156
+ def get(pod_name = nil)
157
+ setup(options)
158
+
159
+ if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
160
+ KuberKit::Container['actions.kubectl_get'].call(pod_name, options)
161
+ end
162
+ end
163
+
153
164
  desc "version", "Print current version"
154
165
  def version
155
166
  puts KuberKit::VERSION