kuber_kit 0.5.1 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
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