kuber_kit 0.2.6 → 0.3.1

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +15 -13
  3. data/TODO.md +5 -6
  4. data/example/config.rb +3 -0
  5. data/example/images/ruby_app/Dockerfile +1 -1
  6. data/example/images/ruby_app/image.rb +3 -0
  7. data/lib/kuber_kit.rb +18 -3
  8. data/lib/kuber_kit/actions/configuration_loader.rb +19 -1
  9. data/lib/kuber_kit/actions/template_reader.rb +3 -6
  10. data/lib/kuber_kit/configs.rb +62 -32
  11. data/lib/kuber_kit/container.rb +14 -2
  12. data/lib/kuber_kit/core/configuration.rb +13 -4
  13. data/lib/kuber_kit/core/configuration_definition.rb +24 -4
  14. data/lib/kuber_kit/core/configuration_factory.rb +3 -2
  15. data/lib/kuber_kit/core/context_helper/base_helper.rb +4 -0
  16. data/lib/kuber_kit/core/context_helper/context_helper_factory.rb +3 -2
  17. data/lib/kuber_kit/core/context_helper/context_vars.rb +39 -0
  18. data/lib/kuber_kit/core/context_helper/image_helper.rb +17 -0
  19. data/lib/kuber_kit/core/image_definition.rb +4 -4
  20. data/lib/kuber_kit/env_file_reader/reader.rb +10 -6
  21. data/lib/kuber_kit/extensions/indocker_compat.rb +4 -0
  22. data/lib/kuber_kit/image_compiler/compiler.rb +1 -1
  23. data/lib/kuber_kit/service_deployer/deployer.rb +14 -8
  24. data/lib/kuber_kit/service_deployer/strategies/docker_compose.rb +24 -0
  25. data/lib/kuber_kit/service_deployer/strategies/kubernetes_runner.rb +9 -1
  26. data/lib/kuber_kit/shell/abstract_shell.rb +4 -0
  27. data/lib/kuber_kit/shell/commands/docker_compose_commands.rb +17 -0
  28. data/lib/kuber_kit/shell/commands/kubectl_commands.rb +12 -2
  29. data/lib/kuber_kit/shell/local_shell.rb +10 -0
  30. data/lib/kuber_kit/shell/ssh_shell.rb +4 -0
  31. data/lib/kuber_kit/template_reader/action_handler.rb +13 -0
  32. data/lib/kuber_kit/template_reader/reader.rb +13 -9
  33. data/lib/kuber_kit/template_reader/{abstract_template_reader.rb → strategies/abstract.rb} +1 -1
  34. data/lib/kuber_kit/template_reader/{artifact_file_reader.rb → strategies/artifact_file.rb} +1 -1
  35. data/lib/kuber_kit/version.rb +1 -1
  36. metadata +12 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a60a34aefa8bd114c7bcb0f877495619c6bc5d4060f3178d6810b767264e5d7
4
- data.tar.gz: 8b6771ac06f2c9fb3c86c810657d3f0d0368fbb4f11d37f410b87a3e7586b0c7
3
+ metadata.gz: d3088efcb997e3dda2dbcd85d584265b7a5eec03b20093265842e3396592ab35
4
+ data.tar.gz: a52e92d808c31b2a0f654e8ba2eaa9cf46a0b7352855f7602e63fee7a09a1271
5
5
  SHA512:
6
- metadata.gz: f342d97d51f6b6ad375e8d3a112cd13b186b9ea16ff34a517e62a62c50fb307b74aaeabbfc42de001a3c9a8960c09a0c3c9e5e3bab33f47cefeb260bee8dc992
7
- data.tar.gz: cb67b78fd74831a2bc3b39c9ac035ff06f848c1b63dde2c5725ff2d73fc08247ef9f666f88c88ea3e4ffdfda963cbdcbc96756e591205a80bcc983eaab0742b7
6
+ metadata.gz: 5ab6df03558b78d0d146cd6d77224f048564ae8d84c9c6d18d2b9abddb6d6cd8c1e8306549bad16c254fd5632b83c2cfceb690518216251efc4008983aa31f86
7
+ data.tar.gz: 1a2837bfa4334e33fa3c7aee7274516c297e9df0b92adf0fd7f021576c3682af2b48f9336c80b849bf1c5655a88f4d3cf43a42f6669140f5875e99a6710b5a5e
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.2.6)
4
+ kuber_kit (0.3.1)
5
5
  cli-ui
6
6
  contracts-lite
7
7
  dry-auto_inject
@@ -35,23 +35,25 @@ GEM
35
35
  coderay (~> 1.1)
36
36
  method_source (~> 1.0)
37
37
  rake (10.5.0)
38
- rspec (3.9.0)
39
- rspec-core (~> 3.9.0)
40
- rspec-expectations (~> 3.9.0)
41
- rspec-mocks (~> 3.9.0)
42
- rspec-core (3.9.3)
43
- rspec-support (~> 3.9.3)
44
- rspec-expectations (3.9.3)
38
+ rspec (3.10.0)
39
+ rspec-core (~> 3.10.0)
40
+ rspec-expectations (~> 3.10.0)
41
+ rspec-mocks (~> 3.10.0)
42
+ rspec-core (3.10.0)
43
+ rspec-support (~> 3.10.0)
44
+ rspec-expectations (3.10.0)
45
45
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.9.0)
47
- rspec-mocks (3.9.1)
46
+ rspec-support (~> 3.10.0)
47
+ rspec-mocks (3.10.0)
48
48
  diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.9.0)
50
- rspec-support (3.9.4)
51
- simplecov (0.19.0)
49
+ rspec-support (~> 3.10.0)
50
+ rspec-support (3.10.0)
51
+ simplecov (0.20.0)
52
52
  docile (~> 1.1)
53
53
  simplecov-html (~> 0.11)
54
+ simplecov_json_formatter (~> 0.1)
54
55
  simplecov-html (0.12.3)
56
+ simplecov_json_formatter (0.1.2)
55
57
  thor (1.0.1)
56
58
 
57
59
  PLATFORMS
data/TODO.md CHANGED
@@ -1,9 +1,8 @@
1
- - find a way to launch job on each run, e.g. for migrations
2
- - allow setting default configuration for kuberkit using env variable
3
- - add ability to set container health checks
4
- - implement interactive shell.exec!
5
- - allow deploying only services enabled for specific configuration
6
1
  - list services and require confirmation before deployment
7
- - add build vars support (use images instead of containers)
2
+ - kit attach should list available deployments/pods, and ask for specific container if it has multiple containers
3
+ - add kit logs support, should work similar to kit attach
4
+ - allow deploying only services enabled for specific configuration
5
+ - find a way to always deploy some service, e.g. for migrations and env_files
6
+ - add ability to set container health checks
8
7
  - template should be able to set default attributes
9
8
  - template should be able to depend on image?
@@ -0,0 +1,3 @@
1
+ KuberKit.configure do |config|
2
+ config.kuber_kit_min_version = "0.2.0"
3
+ end
@@ -8,4 +8,4 @@ COPY README.md README.md
8
8
 
9
9
  RUN ruby /app/source.rb
10
10
 
11
- COPY example_file.txt example_file.txt
11
+ COPY example_file.txt <%= build_vars.example_file_name %>
@@ -2,6 +2,9 @@ KuberKit
2
2
  .define_image(:ruby_app)
3
3
  .registry(:default)
4
4
  .depends_on(:ruby, :app_sources)
5
+ .build_vars({
6
+ example_file_name: "example.txt"
7
+ })
5
8
  .before_build do |context_helper, build_dir|
6
9
  # copy file: local artifact
7
10
  source_path = context_helper.artifact_path(:kuber_kit_example_data, "test.txt")
@@ -57,6 +57,7 @@ module KuberKit
57
57
  autoload :ImageHelper, 'core/context_helper/image_helper'
58
58
  autoload :ServiceHelper, 'core/context_helper/service_helper'
59
59
  autoload :ContextHelperFactory, 'core/context_helper/context_helper_factory'
60
+ autoload :ContextVars, 'core/context_helper/context_vars'
60
61
  end
61
62
 
62
63
  module Registries
@@ -87,6 +88,7 @@ module KuberKit
87
88
  module Commands
88
89
  autoload :BashCommands, 'shell/commands/bash_commands'
89
90
  autoload :DockerCommands, 'shell/commands/docker_commands'
91
+ autoload :DockerComposeCommands, 'shell/commands/docker_compose_commands'
90
92
  autoload :GitCommands, 'shell/commands/git_commands'
91
93
  autoload :RsyncCommands, 'shell/commands/rsync_commands'
92
94
  autoload :KubectlCommands, 'shell/commands/kubectl_commands'
@@ -127,9 +129,13 @@ module KuberKit
127
129
  end
128
130
 
129
131
  module TemplateReader
132
+ autoload :ActionHandler, 'template_reader/action_handler'
130
133
  autoload :Reader, 'template_reader/reader'
131
- autoload :AbstractTemplateReader, 'template_reader/abstract_template_reader'
132
- autoload :ArtifactFileReader, 'template_reader/artifact_file_reader'
134
+
135
+ module Strategies
136
+ autoload :Abstract, 'template_reader/strategies/abstract'
137
+ autoload :ArtifactFile, 'template_reader/strategies/artifact_file'
138
+ end
133
139
  end
134
140
 
135
141
  module ServiceDeployer
@@ -140,6 +146,7 @@ module KuberKit
140
146
 
141
147
  module Strategies
142
148
  autoload :Abstract, 'service_deployer/strategies/abstract'
149
+ autoload :DockerCompose, 'service_deployer/strategies/docker_compose'
143
150
  autoload :Kubernetes, 'service_deployer/strategies/kubernetes'
144
151
  autoload :KubernetesRunner, 'service_deployer/strategies/kubernetes_runner'
145
152
  end
@@ -170,9 +177,9 @@ module KuberKit
170
177
  autoload :Simple, 'ui/simple'
171
178
  end
172
179
 
173
- autoload :Configs, 'configs'
174
180
  autoload :CLI, 'cli'
175
181
  autoload :Container, 'container'
182
+ autoload :Configs, 'configs'
176
183
 
177
184
  Import = Dry::AutoInject(Container)
178
185
 
@@ -211,6 +218,10 @@ module KuberKit
211
218
  @current_configuration ||= Container['core.configuration_store'].get_configuration(@configuration_name)
212
219
  end
213
220
 
221
+ def global_build_vars
222
+ KuberKit::Core::ContextHelper::ContextVars.new(current_configuration.global_build_vars)
223
+ end
224
+
214
225
  def add_registry(registry)
215
226
  Container["core.registry_store"].add(registry)
216
227
  end
@@ -234,6 +245,10 @@ module KuberKit
234
245
  def build_helper(&proc)
235
246
  KuberKit::Core::ContextHelper::BaseHelper.class_exec(&proc)
236
247
  end
248
+
249
+ def configure(&proc)
250
+ yield(Container["configs"])
251
+ end
237
252
  end
238
253
  end
239
254
 
@@ -1,4 +1,6 @@
1
1
  class KuberKit::Actions::ConfigurationLoader
2
+ APP_CONFIG_FILENAME = "config.rb".freeze
3
+
2
4
  include KuberKit::Import[
3
5
  "core.registry_store",
4
6
  "core.image_store",
@@ -14,11 +16,18 @@ class KuberKit::Actions::ConfigurationLoader
14
16
  Contract Hash => Any
15
17
  def call(options)
16
18
  root_path = options[:path] || File.join(Dir.pwd, configs.kuber_kit_dirname)
19
+
20
+ # require config file first, in case if other dirs are overriden in config
21
+ config_file_path = File.join(root_path, APP_CONFIG_FILENAME)
22
+ if File.exists?(config_file_path)
23
+ require config_file_path
24
+ end
25
+
17
26
  images_path = options[:images_path] || File.join(root_path, configs.images_dirname)
18
27
  services_path = options[:services_path] || File.join(root_path, configs.services_dirname)
19
28
  infra_path = options[:infra_path] || File.join(root_path, configs.infra_dirname)
20
29
  configurations_path = options[:configurations_path] || File.join(root_path, configs.configurations_dirname)
21
- configuration_name = options[:configuration]
30
+ configuration_name = ENV["KUBER_KIT_CONFIGURATION"] || options[:configuration]
22
31
 
23
32
  logger.info "Launching kuber_kit with:"
24
33
  logger.info " Root path: #{root_path.to_s.yellow}"
@@ -32,6 +41,10 @@ class KuberKit::Actions::ConfigurationLoader
32
41
  ui.print_warning "WARNING", "KuberKit root path #{root_path} doesn't exist. You may want to pass it --path parameter."
33
42
  end
34
43
 
44
+ if Gem::Version.new(KuberKit::VERSION) < Gem::Version.new(configs.kuber_kit_min_version)
45
+ raise KuberKit::Error, "The minimal required kuber_kit version is #{configs.kuber_kit_min_version}"
46
+ end
47
+
35
48
  load_configurations(configurations_path, configuration_name)
36
49
  load_infrastructure(infra_path)
37
50
 
@@ -43,6 +56,11 @@ class KuberKit::Actions::ConfigurationLoader
43
56
 
44
57
  ui.create_task("Loading image definitions") do |task|
45
58
  files = image_store.load_definitions(images_path)
59
+
60
+ configs.additional_images_paths.each do |path|
61
+ files += image_store.load_definitions(path)
62
+ end
63
+
46
64
  task.update_title("Loaded #{files.count} image definitions")
47
65
  end
48
66
 
@@ -1,16 +1,13 @@
1
1
  class KuberKit::Actions::TemplateReader
2
2
  include KuberKit::Import[
3
- "core.template_store",
4
- "template_reader.reader",
5
3
  "shell.local_shell",
6
- "ui"
4
+ "ui",
5
+ template_reader: "template_reader.action_handler",
7
6
  ]
8
7
 
9
8
  Contract Symbol, Hash => Any
10
9
  def call(template_name, options)
11
- template = template_store.get(template_name)
12
-
13
- result = reader.read(local_shell, template)
10
+ result = template_reader.call(local_shell, template_name)
14
11
 
15
12
  ui.print_info(template_name.to_s, result)
16
13
 
@@ -1,8 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class KuberKit::Configs
2
- IMAGE_DOCKERFILE_NAME = "Dockerfile".freeze
3
- IMAGE_BUILD_CONTEXT_DIR = "build_context".freeze
4
- IMAGE_TAG = 'latest'.freeze
5
- IMAGE_COMPILE_DIR = "/tmp/kuber_kit/image_builds"
4
+ AVAILABLE_CONFIGS = [
5
+ :image_dockerfile_name, :image_build_context_dir, :image_tag, :docker_ignore_list, :image_compile_dir,
6
+ :kuber_kit_dirname, :kuber_kit_min_version, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
7
+ :artifact_clone_dir, :service_config_dir, :deploy_strategy, :compile_simultaneous_limit,
8
+ :additional_images_paths
9
+ ]
6
10
  DOCKER_IGNORE_LIST = [
7
11
  'Dockerfile',
8
12
  '.DS_Store',
@@ -14,35 +18,61 @@ class KuberKit::Configs
14
18
  'tmp',
15
19
  'logs'
16
20
  ]
17
- KUBER_KIT_DIRNAME = "kuber_kit".freeze
18
- IMAGES_DIRNAME = "images".freeze
19
- SERVICES_DIRNAME = "services".freeze
20
- INFRA_DIRNAME = "infrastructure".freeze
21
- CONFIGURATIONS_DIRNAME = "configurations".freeze
22
- ARTIFACT_CLONE_DIR = "/tmp/kuber_kit/artifacts"
23
- SERVICE_CONFIG_DIR = "/tmp/kuber_kit/services"
24
- DEPLOY_STRATEGY = :kubernetes
25
- COMPILE_SIMULTANEOUS_LIMIT = 5
26
-
27
- attr_accessor :image_dockerfile_name, :image_build_context_dir, :image_tag,
28
- :docker_ignore_list, :image_compile_dir,
29
- :kuber_kit_dirname, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
30
- :artifact_clone_dir, :service_config_dir, :deploy_strategy, :compile_simultaneous_limit
21
+
22
+ AVAILABLE_CONFIGS.each do |config_name|
23
+ define_method(config_name) do
24
+ get(config_name.to_sym)
25
+ end
26
+
27
+ define_method(:"#{config_name}=") do |value|
28
+ set(config_name.to_sym, value)
29
+ end
30
+ end
31
31
 
32
32
  def initialize
33
- @image_dockerfile_name = IMAGE_DOCKERFILE_NAME
34
- @image_build_context_dir = IMAGE_BUILD_CONTEXT_DIR
35
- @image_tag = IMAGE_TAG
36
- @image_compile_dir = IMAGE_COMPILE_DIR
37
- @docker_ignore_list = DOCKER_IGNORE_LIST
38
- @kuber_kit_dirname = KUBER_KIT_DIRNAME
39
- @images_dirname = IMAGES_DIRNAME
40
- @services_dirname = SERVICES_DIRNAME
41
- @infra_dirname = INFRA_DIRNAME
42
- @configurations_dirname = CONFIGURATIONS_DIRNAME
43
- @artifact_clone_dir = ARTIFACT_CLONE_DIR
44
- @service_config_dir = SERVICE_CONFIG_DIR
45
- @deploy_strategy = DEPLOY_STRATEGY
46
- @compile_simultaneous_limit = COMPILE_SIMULTANEOUS_LIMIT
33
+ add_default_configs unless items.any?
34
+ end
35
+
36
+ def add_default_configs
37
+ set :image_dockerfile_name, "Dockerfile"
38
+ set :image_build_context_dir, "build_context"
39
+ set :image_tag, 'latest'
40
+ set :image_compile_dir, "/tmp/kuber_kit/image_builds"
41
+ set :docker_ignore_list, DOCKER_IGNORE_LIST
42
+ set :kuber_kit_dirname, "kuber_kit"
43
+ set :kuber_kit_min_version, KuberKit::VERSION
44
+ set :images_dirname, "images"
45
+ set :services_dirname, "services"
46
+ set :infra_dirname, "infrastructure"
47
+ set :configurations_dirname, "configurations"
48
+ set :artifact_clone_dir, "/tmp/kuber_kit/artifacts"
49
+ set :service_config_dir, "/tmp/kuber_kit/services"
50
+ set :deploy_strategy, :kubernetes
51
+ set :compile_simultaneous_limit, 5
52
+ set :additional_images_paths, []
53
+ end
54
+
55
+ def items
56
+ @@items ||= {}
57
+ end
58
+
59
+ def set(key, value)
60
+ unless AVAILABLE_CONFIGS.include?(key)
61
+ raise ArgumentError, "#{key} is not a valid configuration key"
62
+ end
63
+
64
+ items[key] = value
65
+ end
66
+
67
+ def get(key)
68
+ unless AVAILABLE_CONFIGS.include?(key)
69
+ raise ArgumentError, "#{key} is not a valid configuration key"
70
+ end
71
+
72
+ items[key]
73
+ end
74
+
75
+ def reset!
76
+ @@items = {}
47
77
  end
48
78
  end
@@ -117,6 +117,10 @@ class KuberKit::Container
117
117
  KuberKit::Shell::Commands::DockerCommands.new
118
118
  end
119
119
 
120
+ register "shell.docker_compose_commands" do
121
+ KuberKit::Shell::Commands::DockerComposeCommands.new
122
+ end
123
+
120
124
  register "shell.git_commands" do
121
125
  KuberKit::Shell::Commands::GitCommands.new
122
126
  end
@@ -197,12 +201,16 @@ class KuberKit::Container
197
201
  KuberKit::EnvFileReader::Strategies::ArtifactFile.new
198
202
  end
199
203
 
204
+ register "template_reader.action_handler" do
205
+ KuberKit::TemplateReader::ActionHandler.new
206
+ end
207
+
200
208
  register "template_reader.reader" do
201
209
  KuberKit::TemplateReader::Reader.new
202
210
  end
203
211
 
204
- register "template_reader.artifact_file_reader" do
205
- KuberKit::TemplateReader::ArtifactFileReader.new
212
+ register "template_reader.strategies.artifact_file" do
213
+ KuberKit::TemplateReader::Strategies::ArtifactFile.new
206
214
  end
207
215
 
208
216
  register "service_deployer.action_handler" do
@@ -229,6 +237,10 @@ class KuberKit::Container
229
237
  KuberKit::ServiceDeployer::Strategies::KubernetesRunner.new
230
238
  end
231
239
 
240
+ register "service_deployer.strategies.docker_compose" do
241
+ KuberKit::ServiceDeployer::Strategies::DockerCompose.new
242
+ end
243
+
232
244
  register "service_reader.action_handler" do
233
245
  KuberKit::ServiceReader::ActionHandler.new
234
246
  end
@@ -1,6 +1,7 @@
1
1
  class KuberKit::Core::Configuration
2
2
  attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path,
3
- :deploy_strategy, :deploy_namespace, :services_attributes, :build_servers
3
+ :deploy_strategy, :deploy_namespace, :services_attributes, :build_servers,
4
+ :global_build_vars
4
5
 
5
6
  Contract KeywordArgs[
6
7
  name: Symbol,
@@ -12,10 +13,12 @@ class KuberKit::Core::Configuration
12
13
  deploy_strategy: Symbol,
13
14
  deploy_namespace: Maybe[Symbol],
14
15
  services_attributes: HashOf[Symbol => Hash],
15
- build_servers: ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer]
16
+ build_servers: ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer],
17
+ global_build_vars: HashOf[Symbol => Any],
16
18
  ] => Any
17
19
  def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:,
18
- deploy_strategy:, deploy_namespace:, services_attributes:, build_servers:)
20
+ deploy_strategy:, deploy_namespace:, services_attributes:, build_servers:,
21
+ global_build_vars:)
19
22
  @name = name
20
23
  @artifacts = artifacts
21
24
  @registries = registries
@@ -24,11 +27,17 @@ class KuberKit::Core::Configuration
24
27
  @kubeconfig_path = kubeconfig_path
25
28
  @deploy_strategy = deploy_strategy
26
29
  @deploy_namespace = deploy_namespace
27
- @services_attributes = services_attributes
28
30
  @build_servers = build_servers
31
+ @services_attributes = services_attributes
32
+ @global_build_vars = global_build_vars
29
33
  end
30
34
 
31
35
  def service_attributes(service_name)
32
36
  services_attributes[service_name.to_sym] || {}
33
37
  end
38
+
39
+ def global_build_args
40
+ puts "WARNING: global_build_args is deprecated, please use global_build_vars instead"
41
+ global_build_vars
42
+ end
34
43
  end
@@ -27,7 +27,8 @@ class KuberKit::Core::ConfigurationDefinition
27
27
  deploy_namespace: @deploy_namespace,
28
28
  enabled_services: @enabled_services,
29
29
  build_servers: @build_servers,
30
- services_attributes: @services_attributes,
30
+ services_attributes: @services_attributes,
31
+ global_build_vars: @global_build_vars,
31
32
  )
32
33
  end
33
34
 
@@ -93,9 +94,28 @@ class KuberKit::Core::ConfigurationDefinition
93
94
  self
94
95
  end
95
96
 
96
- def enabled_services(services_hash)
97
- @enabled_services += services_hash.keys.map(&:to_sym)
98
- @services_attributes = @services_attributes.merge(services_hash)
97
+ def enabled_services(services)
98
+ if services.is_a?(Hash)
99
+ @enabled_services += services.keys.map(&:to_sym)
100
+ @services_attributes = @services_attributes.merge(services)
101
+ return self
102
+ end
103
+
104
+ if services.is_a?(Array)
105
+ @enabled_services += services.map(&:to_sym)
106
+ return self
107
+ end
108
+
109
+ raise KuberKit::Error, "#enabled_services method accepts only Array or Hash"
110
+ end
111
+
112
+ def service_attributes(services)
113
+ @services_attributes = @services_attributes.merge(services)
114
+ self
115
+ end
116
+
117
+ def global_build_vars(variables)
118
+ @global_build_vars = variables
99
119
 
100
120
  self
101
121
  end
@@ -28,8 +28,9 @@ class KuberKit::Core::ConfigurationFactory
28
28
  kubeconfig_path: configuration_attrs.kubeconfig_path,
29
29
  deploy_strategy: configuration_attrs.deploy_strategy || configs.deploy_strategy,
30
30
  deploy_namespace: configuration_attrs.deploy_namespace,
31
- services_attributes: configuration_attrs.services_attributes,
32
- build_servers: build_servers
31
+ build_servers: build_servers,
32
+ services_attributes: configuration_attrs.services_attributes,
33
+ global_build_vars: configuration_attrs.global_build_vars || {},
33
34
  )
34
35
  end
35
36
 
@@ -29,6 +29,10 @@ class KuberKit::Core::ContextHelper::BaseHelper
29
29
  KuberKit.current_configuration.name
30
30
  end
31
31
 
32
+ def global_build_vars
33
+ KuberKit.global_build_vars
34
+ end
35
+
32
36
  def get_binding
33
37
  binding
34
38
  end
@@ -5,12 +5,13 @@ class KuberKit::Core::ContextHelper::ContextHelperFactory
5
5
  env_file_reader: "env_file_reader.action_handler"
6
6
  ]
7
7
 
8
- def build_image_context(shell)
8
+ def build_image_context(shell, image)
9
9
  KuberKit::Core::ContextHelper::ImageHelper.new(
10
10
  image_store: image_store,
11
11
  artifact_store: artifact_store,
12
12
  shell: shell,
13
- env_file_reader: env_file_reader
13
+ env_file_reader: env_file_reader,
14
+ image: image
14
15
  )
15
16
  end
16
17
 
@@ -0,0 +1,39 @@
1
+ class KuberKit::Core::ContextHelper::ContextVars
2
+ attr_reader :parent, :parent_name
3
+
4
+ def initialize(context_vars, parent_name = nil, parent = nil)
5
+ @context_vars = context_vars
6
+ @parent_name = parent_name
7
+ @parent = parent
8
+ end
9
+
10
+ def method_missing(name, *args)
11
+ if args.size > 0
12
+ raise ArgumentError.new("context args does not accept any arguments")
13
+ end
14
+
15
+ value = @context_vars.fetch(name) do
16
+ raise(KuberKit::Error, "build arg '#{format_arg(name)}' is not defined, available args: #{@context_vars.inspect}")
17
+ end
18
+
19
+ if value.is_a?(Hash)
20
+ return self.class.new(value, name, self)
21
+ end
22
+
23
+ value
24
+ end
25
+
26
+ private
27
+
28
+ def format_arg(name)
29
+ string = [@parent_name, name].compact.join(".")
30
+ parent = @parent
31
+
32
+ while parent do
33
+ string = [parent.parent_name, string].compact.join(".")
34
+ parent = parent.parent
35
+ end
36
+
37
+ string
38
+ end
39
+ end
@@ -1,2 +1,19 @@
1
1
  class KuberKit::Core::ContextHelper::ImageHelper < KuberKit::Core::ContextHelper::BaseHelper
2
+ def initialize(image_store:, artifact_store:, shell:, env_file_reader:, image:)
3
+ super(
4
+ image_store: image_store,
5
+ artifact_store: artifact_store,
6
+ shell: shell,
7
+ env_file_reader: env_file_reader
8
+ )
9
+ @image = image
10
+ end
11
+
12
+ def image_name
13
+ @image.name.to_s
14
+ end
15
+
16
+ def build_vars
17
+ KuberKit::Core::ContextHelper::ContextVars.new(@image.build_vars)
18
+ end
2
19
  end
@@ -66,14 +66,14 @@ class KuberKit::Core::ImageDefinition
66
66
  self
67
67
  end
68
68
 
69
- def before_build(&block)
70
- @before_build_callback = block
69
+ def before_build(lambda_arg = nil, &block)
70
+ @before_build_callback = lambda_arg || block
71
71
 
72
72
  self
73
73
  end
74
74
 
75
- def after_build(&block)
76
- @after_build_callback = block
75
+ def after_build(lambda_arg = nil, &block)
76
+ @after_build_callback = lambda_arg || block
77
77
 
78
78
  self
79
79
  end
@@ -5,6 +5,11 @@ class KuberKit::EnvFileReader::Reader
5
5
  "env_file_reader.strategies.artifact_file",
6
6
  ]
7
7
 
8
+ def initialize(**injected_deps)
9
+ super(injected_deps)
10
+ add_default_strategies
11
+ end
12
+
8
13
  def use_reader(env_file_reader, env_file_class:)
9
14
  @@readers ||= {}
10
15
 
@@ -16,8 +21,6 @@ class KuberKit::EnvFileReader::Reader
16
21
  end
17
22
 
18
23
  def read(shell, env_file)
19
- add_default_readers
20
-
21
24
  reader = @@readers[env_file.class]
22
25
 
23
26
  raise ReaderNotFoundError, "Can't find reader for env file #{env_file}" if reader.nil?
@@ -25,11 +28,12 @@ class KuberKit::EnvFileReader::Reader
25
28
  reader.read(shell, env_file)
26
29
  end
27
30
 
28
- def add_default_readers
29
- use_reader(artifact_file, env_file_class: KuberKit::Core::EnvFiles::ArtifactFile)
30
- end
31
-
32
31
  def reset!
33
32
  @@readers = {}
34
33
  end
34
+
35
+ private
36
+ def add_default_strategies
37
+ use_reader(artifact_file, env_file_class: KuberKit::Core::EnvFiles::ArtifactFile)
38
+ end
35
39
  end
@@ -14,6 +14,10 @@ module KuberKit
14
14
  def build_configuration(configuration_name)
15
15
  define_configuration(configuration_name)
16
16
  end
17
+
18
+ def configuration
19
+ current_configuration
20
+ end
17
21
  end
18
22
  end
19
23
  Indocker = KuberKit
@@ -9,7 +9,7 @@ class KuberKit::ImageCompiler::Compiler
9
9
  def compile(shell, image, builds_dir)
10
10
  image_build_dir = File.join(builds_dir, image.name.to_s)
11
11
 
12
- context_helper = context_helper_factory.build_image_context(shell)
12
+ context_helper = context_helper_factory.build_image_context(shell, image)
13
13
  image_build_dir_creator.create(shell, image, image_build_dir, context_helper: context_helper)
14
14
 
15
15
  image_builder.build(shell, image, image_build_dir, context_helper: context_helper)
@@ -4,9 +4,15 @@ class KuberKit::ServiceDeployer::Deployer
4
4
  include KuberKit::Import[
5
5
  "core.service_store",
6
6
  "service_deployer.strategies.kubernetes",
7
- "service_deployer.strategies.kubernetes_runner"
7
+ "service_deployer.strategies.kubernetes_runner",
8
+ "service_deployer.strategies.docker_compose"
8
9
  ]
9
10
 
11
+ def initialize(**injected_deps)
12
+ super(injected_deps)
13
+ add_default_strategies
14
+ end
15
+
10
16
  def register_strategy(strategy_name, strategy)
11
17
  @@strategies ||= {}
12
18
 
@@ -19,8 +25,6 @@ class KuberKit::ServiceDeployer::Deployer
19
25
 
20
26
  Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service, Symbol => Any
21
27
  def deploy(shell, service, strategy_name)
22
- add_default_strategies
23
-
24
28
  deployer = @@strategies[strategy_name]
25
29
 
26
30
  raise StrategyNotFoundError, "Can't find strategy with name #{strategy_name}" if deployer.nil?
@@ -28,12 +32,14 @@ class KuberKit::ServiceDeployer::Deployer
28
32
  deployer.deploy(shell, service)
29
33
  end
30
34
 
31
- def add_default_strategies
32
- register_strategy(:kubernetes, kubernetes)
33
- register_strategy(:kubernetes_runner, kubernetes_runner)
34
- end
35
-
36
35
  def reset!
37
36
  @@strategies = {}
38
37
  end
38
+
39
+ private
40
+ def add_default_strategies
41
+ register_strategy(:kubernetes, kubernetes)
42
+ register_strategy(:kubernetes_runner, kubernetes_runner)
43
+ register_strategy(:docker_compose, docker_compose)
44
+ end
39
45
  end
@@ -0,0 +1,24 @@
1
+ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDeployer::Strategies::Abstract
2
+ include KuberKit::Import[
3
+ "service_reader.reader",
4
+ "shell.docker_compose_commands",
5
+ "configs",
6
+ ]
7
+
8
+ Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
9
+ def deploy(shell, service)
10
+ service_config = reader.read(shell, service)
11
+ config_path = "#{configs.service_config_dir}/#{service.name}.yml"
12
+ shell.write(config_path, service_config)
13
+
14
+ deployment_service_name = service.attribute(:deployment_service_name, default: service.name.to_s)
15
+ deployment_command_name = service.attribute(:deployment_command_name, default: "bash")
16
+ deployment_interactive = service.attribute(:deployment_interactive, default: false)
17
+
18
+ docker_compose_commands.run(shell, config_path,
19
+ service: deployment_service_name,
20
+ command: deployment_command_name,
21
+ interactive: deployment_interactive
22
+ )
23
+ end
24
+ end
@@ -19,9 +19,17 @@ class KuberKit::ServiceDeployer::Strategies::KubernetesRunner < KuberKit::Servic
19
19
 
20
20
  deployment_delete_enabled = service.attribute(:deployment_delete_enabled, default: true)
21
21
  if deployment_delete_enabled
22
- kubectl_commands.delete_resource(shell, deployment_resource_type, deployment_resource_name, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
22
+ delete_resource_if_exists(shell, deployment_resource_type, deployment_resource_name, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
23
23
  end
24
24
 
25
25
  kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
26
26
  end
27
+
28
+ private
29
+ def delete_resource_if_exists(shell, resource_type, resource_name, kubeconfig_path:, namespace: )
30
+ unless kubectl_commands.resource_exists?(shell, resource_type, resource_name, kubeconfig_path: kubeconfig_path, namespace: namespace)
31
+ return false
32
+ end
33
+ kubectl_commands.delete_resource(shell, resource_type, resource_name, kubeconfig_path: kubeconfig_path, namespace: namespace)
34
+ end
27
35
  end
@@ -6,6 +6,10 @@ class KuberKit::Shell::AbstractShell
6
6
  raise KuberKit::NotImplementedError, "must be implemented"
7
7
  end
8
8
 
9
+ def interactive!(command)
10
+ raise KuberKit::NotImplementedError, "must be implemented"
11
+ end
12
+
9
13
  def read(file_path)
10
14
  raise KuberKit::NotImplementedError, "must be implemented"
11
15
  end
@@ -0,0 +1,17 @@
1
+ class KuberKit::Shell::Commands::DockerComposeCommands
2
+ def run(shell, path, service:, command:, interactive: false)
3
+ command_parts = [
4
+ "docker-compose",
5
+ "-f #{path}",
6
+ "run",
7
+ service,
8
+ command
9
+ ]
10
+
11
+ if interactive
12
+ shell.interactive!(command_parts.join(" "))
13
+ else
14
+ shell.exec!(command_parts.join(" "))
15
+ end
16
+ end
17
+ end
@@ -16,9 +16,8 @@ class KuberKit::Shell::Commands::KubectlCommands
16
16
 
17
17
  command_parts += Array(command_list)
18
18
 
19
- # TODO: investigate how to do it with shell.
20
19
  if interactive
21
- system(command_parts.join(" "))
20
+ shell.interactive!(command_parts.join(" "))
22
21
  else
23
22
  shell.exec!(command_parts.join(" "))
24
23
  end
@@ -41,6 +40,17 @@ class KuberKit::Shell::Commands::KubectlCommands
41
40
  kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, interactive: interactive, namespace: namespace)
42
41
  end
43
42
 
43
+ def resource_exists?(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
44
+ result = find_resources(shell, resource_type, resource_name, kubeconfig_path: kubeconfig_path, namespace: namespace)
45
+ result && result != ""
46
+ end
47
+
48
+ def find_resources(shell, resource_type, resource_name, jsonpath: ".items[*].metadata.name", kubeconfig_path: nil, namespace: nil)
49
+ command = %Q{get #{resource_type} --field-selector=metadata.name=#{resource_name} -o jsonpath='{#{jsonpath}}'}
50
+
51
+ kubectl_run(shell, command, kubeconfig_path: kubeconfig_path, namespace: namespace)
52
+ end
53
+
44
54
  def delete_resource(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
45
55
  command = %Q{delete #{resource_type} #{resource_name}}
46
56
 
@@ -30,6 +30,16 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
30
30
  result
31
31
  end
32
32
 
33
+ def interactive!(command, log_command: true)
34
+ command_number = command_counter.get_number.to_s.rjust(2, "0")
35
+
36
+ if log_command
37
+ logger.info("Interactive: [#{command_number}]: #{command.to_s.cyan}")
38
+ end
39
+
40
+ system(command)
41
+ end
42
+
33
43
  def sync(local_path, remote_path, exclude: nil, delete: true)
34
44
  rsync_commands.rsync(self, local_path, remote_path, exclude: exclude, delete: delete)
35
45
  end
@@ -38,6 +38,10 @@ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell
38
38
  raise ShellError.new(e.message)
39
39
  end
40
40
 
41
+ def interactive!(command, log_command: true)
42
+ raise "Currently interactive run is not supported for ssh shell."
43
+ end
44
+
41
45
  def sync(local_path, remote_path, exclude: nil, delete: true)
42
46
  rsync_commands.rsync(
43
47
  local_shell, local_path, remote_path,
@@ -0,0 +1,13 @@
1
+ class KuberKit::TemplateReader::ActionHandler
2
+ include KuberKit::Import[
3
+ "template_reader.reader",
4
+ "core.template_store",
5
+ ]
6
+
7
+ Contract KuberKit::Shell::AbstractShell, Symbol => Any
8
+ def call(shell, template_name)
9
+ template = template_store.get(template_name)
10
+
11
+ reader.read(shell, template)
12
+ end
13
+ end
@@ -2,22 +2,25 @@ class KuberKit::TemplateReader::Reader
2
2
  ReaderNotFoundError = Class.new(KuberKit::NotFoundError)
3
3
 
4
4
  include KuberKit::Import[
5
- "template_reader.artifact_file_reader",
5
+ "template_reader.strategies.artifact_file",
6
6
  ]
7
7
 
8
+ def initialize(**injected_deps)
9
+ super(injected_deps)
10
+ add_default_strategies
11
+ end
12
+
8
13
  def use_reader(template_reader, template_class:)
9
14
  @@readers ||= {}
10
15
 
11
- if !template_reader.is_a?(KuberKit::TemplateReader::AbstractTemplateReader)
12
- raise ArgumentError.new("should be an instance of KuberKit::TemplateReader::AbstractTemplateReader, got: #{template_reader.inspect}")
16
+ if !template_reader.is_a?(KuberKit::TemplateReader::Strategies::Abstract)
17
+ raise ArgumentError.new("should be an instance of KuberKit::TemplateReader::Strategies::Abstract, got: #{template_reader.inspect}")
13
18
  end
14
19
 
15
20
  @@readers[template_class] = template_reader
16
21
  end
17
22
 
18
23
  def read(shell, template)
19
- add_default_readers
20
-
21
24
  reader = @@readers[template.class]
22
25
 
23
26
  raise ReaderNotFoundError, "Can't find reader for template #{template}" if reader.nil?
@@ -25,11 +28,12 @@ class KuberKit::TemplateReader::Reader
25
28
  reader.read(shell, template)
26
29
  end
27
30
 
28
- def add_default_readers
29
- use_reader(artifact_file_reader, template_class: KuberKit::Core::Templates::ArtifactFile)
30
- end
31
-
32
31
  def reset!
33
32
  @@readers = {}
34
33
  end
34
+
35
+ private
36
+ def add_default_strategies
37
+ use_reader(artifact_file, template_class: KuberKit::Core::Templates::ArtifactFile)
38
+ end
35
39
  end
@@ -1,4 +1,4 @@
1
- class KuberKit::TemplateReader::AbstractTemplateReader
1
+ class KuberKit::TemplateReader::Strategies::Abstract
2
2
  def read(shell, template)
3
3
  raise KuberKit::NotImplementedError, "must be implemented"
4
4
  end
@@ -1,4 +1,4 @@
1
- class KuberKit::TemplateReader::ArtifactFileReader < KuberKit::TemplateReader::AbstractTemplateReader
1
+ class KuberKit::TemplateReader::Strategies::ArtifactFile < KuberKit::TemplateReader::Strategies::Abstract
2
2
  include KuberKit::Import[
3
3
  "core.artifact_store"
4
4
  ]
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kuber_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Khaziev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-03 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts-lite
@@ -162,6 +162,7 @@ files:
162
162
  - example/app_data/service.yml
163
163
  - example/app_data/test.env
164
164
  - example/app_data/test.txt
165
+ - example/config.rb
165
166
  - example/configurations/review.rb
166
167
  - example/images/app_sources/Dockerfile
167
168
  - example/images/app_sources/build_context/source.rb
@@ -212,6 +213,7 @@ files:
212
213
  - lib/kuber_kit/core/configuration_store.rb
213
214
  - lib/kuber_kit/core/context_helper/base_helper.rb
214
215
  - lib/kuber_kit/core/context_helper/context_helper_factory.rb
216
+ - lib/kuber_kit/core/context_helper/context_vars.rb
215
217
  - lib/kuber_kit/core/context_helper/image_helper.rb
216
218
  - lib/kuber_kit/core/context_helper/service_helper.rb
217
219
  - lib/kuber_kit/core/env_files/abstract_env_file.rb
@@ -256,6 +258,7 @@ files:
256
258
  - lib/kuber_kit/service_deployer/deployer.rb
257
259
  - lib/kuber_kit/service_deployer/service_list_resolver.rb
258
260
  - lib/kuber_kit/service_deployer/strategies/abstract.rb
261
+ - lib/kuber_kit/service_deployer/strategies/docker_compose.rb
259
262
  - lib/kuber_kit/service_deployer/strategies/kubernetes.rb
260
263
  - lib/kuber_kit/service_deployer/strategies/kubernetes_runner.rb
261
264
  - lib/kuber_kit/service_deployer/strategy_detector.rb
@@ -265,15 +268,17 @@ files:
265
268
  - lib/kuber_kit/shell/command_counter.rb
266
269
  - lib/kuber_kit/shell/commands/bash_commands.rb
267
270
  - lib/kuber_kit/shell/commands/docker_commands.rb
271
+ - lib/kuber_kit/shell/commands/docker_compose_commands.rb
268
272
  - lib/kuber_kit/shell/commands/git_commands.rb
269
273
  - lib/kuber_kit/shell/commands/kubectl_commands.rb
270
274
  - lib/kuber_kit/shell/commands/rsync_commands.rb
271
275
  - lib/kuber_kit/shell/local_shell.rb
272
276
  - lib/kuber_kit/shell/ssh_session.rb
273
277
  - lib/kuber_kit/shell/ssh_shell.rb
274
- - lib/kuber_kit/template_reader/abstract_template_reader.rb
275
- - lib/kuber_kit/template_reader/artifact_file_reader.rb
278
+ - lib/kuber_kit/template_reader/action_handler.rb
276
279
  - lib/kuber_kit/template_reader/reader.rb
280
+ - lib/kuber_kit/template_reader/strategies/abstract.rb
281
+ - lib/kuber_kit/template_reader/strategies/artifact_file.rb
277
282
  - lib/kuber_kit/tools/file_presence_checker.rb
278
283
  - lib/kuber_kit/tools/logger_factory.rb
279
284
  - lib/kuber_kit/ui.rb
@@ -284,7 +289,7 @@ homepage: https://github.com/ArtStation/kuber_kit
284
289
  licenses:
285
290
  - MIT
286
291
  metadata: {}
287
- post_install_message:
292
+ post_install_message:
288
293
  rdoc_options: []
289
294
  require_paths:
290
295
  - lib
@@ -300,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
305
  version: '0'
301
306
  requirements: []
302
307
  rubygems_version: 3.0.8
303
- signing_key:
308
+ signing_key:
304
309
  specification_version: 4
305
310
  summary: Docker Containers Build & Deployment
306
311
  test_files: []