kuber_kit 0.1.0 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/TODO.md +2 -0
  4. data/example/app_data/service.yml +22 -4
  5. data/example/services/ruby_app.rb +4 -0
  6. data/lib/kuber_kit.rb +8 -2
  7. data/lib/kuber_kit/actions/configuration_loader.rb +11 -3
  8. data/lib/kuber_kit/actions/image_compiler.rb +1 -1
  9. data/lib/kuber_kit/actions/kubectl_applier.rb +2 -2
  10. data/lib/kuber_kit/actions/service_deployer.rb +52 -0
  11. data/lib/kuber_kit/cli.rb +1 -1
  12. data/lib/kuber_kit/configs.rb +8 -4
  13. data/lib/kuber_kit/container.rb +14 -2
  14. data/lib/kuber_kit/core/configuration.rb +11 -9
  15. data/lib/kuber_kit/core/configuration_definition.rb +15 -8
  16. data/lib/kuber_kit/core/configuration_factory.rb +9 -7
  17. data/lib/kuber_kit/core/configuration_store.rb +2 -0
  18. data/lib/kuber_kit/core/context_helper/base_helper.rb +2 -0
  19. data/lib/kuber_kit/core/context_helper/service_helper.rb +5 -2
  20. data/lib/kuber_kit/core/image_store.rb +2 -0
  21. data/lib/kuber_kit/core/service.rb +20 -2
  22. data/lib/kuber_kit/core/service_definition.rb +15 -1
  23. data/lib/kuber_kit/core/service_factory.rb +3 -1
  24. data/lib/kuber_kit/core/service_store.rb +7 -1
  25. data/lib/kuber_kit/image_compiler/compiler.rb +1 -1
  26. data/lib/kuber_kit/image_compiler/image_builder.rb +2 -3
  27. data/lib/kuber_kit/service_deployer/deployer.rb +15 -0
  28. data/lib/kuber_kit/service_deployer/service_reader.rb +1 -0
  29. data/lib/kuber_kit/service_deployer/service_restarter.rb +37 -0
  30. data/lib/kuber_kit/service_deployer/strategies/abstract.rb +5 -0
  31. data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +18 -0
  32. data/lib/kuber_kit/shell/kubectl_commands.rb +33 -3
  33. data/lib/kuber_kit/version.rb +1 -1
  34. metadata +8 -4
  35. data/example/infrastructure/services.rb +0 -3
  36. data/lib/kuber_kit/actions/service_applier.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9ac91299a59af0f2eec1d7382f3b55f0946931e1d4f87de909d76631242f441
4
- data.tar.gz: d0737d6d217a9c4107fb77536fd36e2c3d59e71adb9dd8c68b6dbc2c12e2eb8f
3
+ metadata.gz: b5df957bf6c31a193caef5d2fc163be4d925ba6dc3bd61f2d98c47f0eee2bb42
4
+ data.tar.gz: 701748c782360287b41acd34dcd33a3c8d9192a2ba91685a5355dddbe4b19789
5
5
  SHA512:
6
- metadata.gz: d9feedc39ab9959d1a3e4bd38a5b6703f6d93f16d03bbd4805732166266e64c4dc9798d6e5d173de2e5058f1ccfc8ad86143c793916efd9936768279eedff14f
7
- data.tar.gz: a9bf6386c3bac7c75c894f82464af2e9e83dd94e56dec4be9da87fd092c81e9cbff568c4432921ff601c11831127f497651beb835d21edc8379675dffc6c0e1a
6
+ metadata.gz: f4d10fbac924851b0552f1b833e8080203277245055717a5a7592437284eb9a5cd0535c369764ca474bc7a09686517254423fec45aeb2ccd8568d22c1851cf63
7
+ data.tar.gz: 1972b5f5cdd6cb8e8b1f33ae210ac783f3ff55e1c36f6304c933c2a43b3b335ff40b9400fd725be957227b3ed8160327d8d19f0352abf9b9596e4f0b0855716d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.1.0)
4
+ kuber_kit (0.1.5)
5
5
  cli-ui
6
6
  contracts-lite
7
7
  dry-auto_inject
data/TODO.md CHANGED
@@ -1,2 +1,4 @@
1
+ - rename service reader to service config reader
2
+ - service factory should make sure that template exists
1
3
  - add build servers support
2
4
  - add build vars support (use images instead of containers)
@@ -1,7 +1,25 @@
1
- apiVersion: v1
2
- kind: Service
1
+
2
+ apiVersion: apps/v1
3
+ kind: Deployment
3
4
  metadata:
4
- name: "<%= service_uri %>"
5
+ labels:
6
+ app: <%= service_uri %>
7
+ name: <%= service_uri %>
5
8
  spec:
9
+ replicas: 1
6
10
  selector:
7
- app: test-app
11
+ matchLabels:
12
+ app: <%= service_uri %>
13
+ strategy: {}
14
+ template:
15
+ metadata:
16
+ labels:
17
+ app: <%= service_uri %>
18
+ spec:
19
+ containers:
20
+ - name: <%= service_uri %>
21
+ image: <%= service_name %>:latest
22
+ imagePullPolicy: Always
23
+ restartPolicy: Always
24
+ imagePullSecrets:
25
+ - name: regcred
@@ -0,0 +1,4 @@
1
+ KuberKit
2
+ .define_service(:ruby_app)
3
+ .template(:service)
4
+ .images(:ruby_app)
@@ -115,9 +115,15 @@ module KuberKit
115
115
  end
116
116
 
117
117
  module ServiceDeployer
118
+ autoload :Deployer, 'service_deployer/deployer'
119
+ autoload :ServiceRestarter, 'service_deployer/service_restarter'
118
120
  autoload :ServiceReader, 'service_deployer/service_reader'
119
- autoload :ServiceApplier, 'service_deployer/service_applier'
120
121
  autoload :ServiceListResolver, 'service_deployer/service_list_resolver'
122
+
123
+ module Strategies
124
+ autoload :Abstract, 'service_deployer/strategies/abstract'
125
+ autoload :Kubernetes, 'service_deployer/strategies/kubernetes'
126
+ end
121
127
  end
122
128
 
123
129
  module Actions
@@ -125,7 +131,7 @@ module KuberKit
125
131
  autoload :EnvFileReader, 'actions/env_file_reader'
126
132
  autoload :TemplateReader, 'actions/template_reader'
127
133
  autoload :ServiceReader, 'actions/service_reader'
128
- autoload :ServiceApplier, 'actions/service_applier'
134
+ autoload :ServiceDeployer, 'actions/service_deployer'
129
135
  autoload :ConfigurationLoader, 'actions/configuration_loader'
130
136
  autoload :KubectlApplier, 'actions/kubectl_applier'
131
137
  end
@@ -2,6 +2,7 @@ class KuberKit::Actions::ConfigurationLoader
2
2
  include KuberKit::Import[
3
3
  "core.registry_store",
4
4
  "core.image_store",
5
+ "core.service_store",
5
6
  "core.configuration_store",
6
7
  "artifacts_sync.artifacts_updater",
7
8
  "tools.logger",
@@ -12,15 +13,17 @@ class KuberKit::Actions::ConfigurationLoader
12
13
 
13
14
  Contract Hash => Any
14
15
  def call(options)
15
- root_path = options[:path] || File.join(Dir.pwd, configs.kuber_kit_dirname)
16
- images_path = options[:images_path] || File.join(root_path, configs.images_dirname)
17
- infra_path = options[:infra_path] || File.join(root_path, configs.infra_dirname)
16
+ root_path = options[:path] || File.join(Dir.pwd, configs.kuber_kit_dirname)
17
+ images_path = options[:images_path] || File.join(root_path, configs.images_dirname)
18
+ services_path = options[:services_path] || File.join(root_path, configs.services_dirname)
19
+ infra_path = options[:infra_path] || File.join(root_path, configs.infra_dirname)
18
20
  configurations_path = options[:configurations_path] || File.join(root_path, configs.configurations_dirname)
19
21
  configuration_name = options[:configuration]
20
22
 
21
23
  logger.info "Launching kuber_kit with:"
22
24
  logger.info " Root path: #{root_path.to_s.yellow}"
23
25
  logger.info " Images path: #{images_path.to_s.yellow}"
26
+ logger.info " Services path: #{services_path.to_s.yellow}"
24
27
  logger.info " Infrastructure path: #{infra_path.to_s.yellow}"
25
28
  logger.info " Configurations path: #{configurations_path.to_s.yellow}"
26
29
  logger.info " Configuration name: #{configuration_name.to_s.yellow}"
@@ -42,6 +45,11 @@ class KuberKit::Actions::ConfigurationLoader
42
45
  files = image_store.load_definitions(images_path)
43
46
  task.update_title("Loaded #{files.count} image definitions")
44
47
  end
48
+
49
+ ui.create_task("Loading service definitions") do |task|
50
+ files = service_store.load_definitions(services_path)
51
+ task.update_title("Loaded #{files.count} service definitions")
52
+ end
45
53
  end
46
54
 
47
55
  def load_configurations(configurations_path, configuration_name)
@@ -43,7 +43,7 @@ class KuberKit::Actions::ImageCompiler
43
43
 
44
44
  def compile_image(image_name, build_id)
45
45
  compile_dir = generate_compile_dir(build_id: build_id)
46
- image_compiler.compile(local_shell, image_name, compile_dir)
46
+ compiler.compile(local_shell, image_name, compile_dir)
47
47
  end
48
48
 
49
49
  def generate_build_id
@@ -7,9 +7,9 @@ class KuberKit::Actions::KubectlApplier
7
7
 
8
8
  Contract String, Hash => Any
9
9
  def call(file_path, options)
10
- kubecfg_path = KuberKit.current_configuration.kubecfg_path
10
+ kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
11
11
  ui.create_task("Applying file: #{file_path}") do |task|
12
- kubectl_commands.apply_file(local_shell, file_path, kubecfg_path: kubecfg_path)
12
+ kubectl_commands.apply_file(local_shell, file_path, kubeconfig_path: kubeconfig_path)
13
13
  task.update_title("Applied file: #{file_path}")
14
14
  end
15
15
  nil
@@ -0,0 +1,52 @@
1
+ class KuberKit::Actions::ServiceDeployer
2
+ include KuberKit::Import[
3
+ "actions.image_compiler",
4
+ "service_deployer.service_list_resolver",
5
+ "service_deployer.deployer",
6
+ "core.service_store",
7
+ "shell.local_shell",
8
+ "tools.logger",
9
+ "ui"
10
+ ]
11
+
12
+ Contract KeywordArgs[
13
+ services: Maybe[ArrayOf[String]],
14
+ tags: Maybe[ArrayOf[String]],
15
+ ] => Any
16
+ def call(services:, tags:)
17
+ service_names = service_list_resolver.resolve(
18
+ services: services || [],
19
+ tags: tags || []
20
+ )
21
+
22
+ services = service_names.map do |service_name|
23
+ service_store.get_service(service_name.to_sym)
24
+ end
25
+
26
+ images_names = services.map(&:images).flatten.uniq
27
+
28
+ compile_images(images_names)
29
+ deploy_services(service_names)
30
+ end
31
+
32
+ def deploy_services(service_names)
33
+ task_group = ui.create_task_group
34
+
35
+ service_names.each do |service_name|
36
+
37
+ logger.info("Started deploying: #{service_name.to_s.green}")
38
+ task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
39
+ deployer.deploy(local_shell, service_name.to_sym)
40
+
41
+ task.update_title("Deployed #{service_name.to_s.green}")
42
+ logger.info("Finished deploying: #{service_name.to_s.green}")
43
+ end
44
+ end
45
+
46
+ task_group.wait
47
+ end
48
+
49
+ def compile_images(images_names)
50
+ image_compiler.call(images_names, {}) if images_names.any?
51
+ end
52
+ end
@@ -63,7 +63,7 @@ class KuberKit::CLI < Thor
63
63
 
64
64
  KuberKit::Container['actions.configuration_loader'].call(options)
65
65
 
66
- KuberKit::Container['actions.service_applier'].call(services: options[:services], tags: options[:tags])
66
+ KuberKit::Container['actions.service_deployer'].call(services: options[:services], tags: options[:tags])
67
67
  end
68
68
 
69
69
  def self.exit_on_failure?
@@ -14,17 +14,19 @@ class KuberKit::Configs
14
14
  'tmp',
15
15
  'logs'
16
16
  ]
17
- INDOCKER_DIRNAME = "kuber_kit".freeze
17
+ KUBER_KIT_DIRNAME = "kuber_kit".freeze
18
18
  IMAGES_DIRNAME = "images".freeze
19
+ SERVICES_DIRNAME = "services".freeze
19
20
  INFRA_DIRNAME = "infrastructure".freeze
20
21
  CONFIGURATIONS_DIRNAME = "configurations".freeze
21
22
  ARTIFACT_CLONE_DIR = "/tmp/kuber_kit/artifacts"
22
23
  SERVICE_CONFIG_DIR = "/tmp/kuber_kit/services"
24
+ DEPLOY_STRATEGY = :kubernetes
23
25
 
24
26
  attr_accessor :image_dockerfile_name, :image_build_context_dir, :image_tag,
25
27
  :docker_ignore_list, :image_compile_dir,
26
- :kuber_kit_dirname, :images_dirname, :infra_dirname, :configurations_dirname,
27
- :artifact_clone_dir, :service_config_dir
28
+ :kuber_kit_dirname, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
29
+ :artifact_clone_dir, :service_config_dir, :deploy_strategy
28
30
 
29
31
  def initialize
30
32
  @image_dockerfile_name = IMAGE_DOCKERFILE_NAME
@@ -32,11 +34,13 @@ class KuberKit::Configs
32
34
  @image_tag = IMAGE_TAG
33
35
  @image_compile_dir = IMAGE_COMPILE_DIR
34
36
  @docker_ignore_list = DOCKER_IGNORE_LIST
35
- @kuber_kit_dirname = INDOCKER_DIRNAME
37
+ @kuber_kit_dirname = KUBER_KIT_DIRNAME
36
38
  @images_dirname = IMAGES_DIRNAME
39
+ @services_dirname = SERVICES_DIRNAME
37
40
  @infra_dirname = INFRA_DIRNAME
38
41
  @configurations_dirname = CONFIGURATIONS_DIRNAME
39
42
  @artifact_clone_dir = ARTIFACT_CLONE_DIR
40
43
  @service_config_dir = SERVICE_CONFIG_DIR
44
+ @deploy_strategy = DEPLOY_STRATEGY
41
45
  end
42
46
  end
@@ -17,8 +17,8 @@ class KuberKit::Container
17
17
  KuberKit::Actions::ServiceReader.new
18
18
  end
19
19
 
20
- register "actions.service_applier" do
21
- KuberKit::Actions::ServiceApplier.new
20
+ register "actions.service_deployer" do
21
+ KuberKit::Actions::ServiceDeployer.new
22
22
  end
23
23
 
24
24
  register "actions.configuration_loader" do
@@ -189,6 +189,14 @@ class KuberKit::Container
189
189
  KuberKit::TemplateReader::ArtifactFileReader.new
190
190
  end
191
191
 
192
+ register "service_deployer.deployer" do
193
+ KuberKit::ServiceDeployer::Deployer.new
194
+ end
195
+
196
+ register "service_deployer.service_restarter" do
197
+ KuberKit::ServiceDeployer::ServiceRestarter.new
198
+ end
199
+
192
200
  register "service_deployer.service_reader" do
193
201
  KuberKit::ServiceDeployer::ServiceReader.new
194
202
  end
@@ -197,6 +205,10 @@ class KuberKit::Container
197
205
  KuberKit::ServiceDeployer::ServiceListResolver.new
198
206
  end
199
207
 
208
+ register "service_deployer.strategies.kubernetes" do
209
+ KuberKit::ServiceDeployer::Strategies::Kubernetes.new
210
+ end
211
+
200
212
  register "ui" do
201
213
  if KuberKit.debug_mode?
202
214
  KuberKit::UI::Simple.new
@@ -1,5 +1,5 @@
1
1
  class KuberKit::Core::Configuration
2
- attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubecfg_path
2
+ attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path, :deploy_strategy
3
3
 
4
4
  Contract KeywordArgs[
5
5
  name: Symbol,
@@ -7,14 +7,16 @@ class KuberKit::Core::Configuration
7
7
  registries: Hash,
8
8
  env_files: Hash,
9
9
  templates: Hash,
10
- kubecfg_path: Maybe[String]
10
+ kubeconfig_path: Maybe[String],
11
+ deploy_strategy: Symbol
11
12
  ] => Any
12
- def initialize(name:, artifacts:, registries:, env_files:, templates:, kubecfg_path:)
13
- @name = name
14
- @artifacts = artifacts
15
- @registries = registries
16
- @env_files = env_files
17
- @templates = templates
18
- @kubecfg_path = kubecfg_path
13
+ def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:, deploy_strategy:)
14
+ @name = name
15
+ @artifacts = artifacts
16
+ @registries = registries
17
+ @env_files = env_files
18
+ @templates = templates
19
+ @kubeconfig_path = kubeconfig_path
20
+ @deploy_strategy = deploy_strategy
19
21
  end
20
22
  end
@@ -14,12 +14,13 @@ class KuberKit::Core::ConfigurationDefinition
14
14
 
15
15
  def to_attrs
16
16
  OpenStruct.new(
17
- name: @configuration_name,
18
- artifacts: @artifacts,
19
- registries: @registries,
20
- env_files: @env_files,
21
- templates: @templates,
22
- kubecfg_path: @kubecfg_path
17
+ name: @configuration_name,
18
+ artifacts: @artifacts,
19
+ registries: @registries,
20
+ env_files: @env_files,
21
+ templates: @templates,
22
+ kubeconfig_path: @kubeconfig_path,
23
+ deploy_strategy: @deploy_strategy
23
24
  )
24
25
  end
25
26
 
@@ -59,8 +60,14 @@ class KuberKit::Core::ConfigurationDefinition
59
60
  self
60
61
  end
61
62
 
62
- def kubecfg_path(path)
63
- @kubecfg_path = path
63
+ def kubeconfig_path(path)
64
+ @kubeconfig_path = path
65
+
66
+ self
67
+ end
68
+
69
+ def deploy_strategy(path)
70
+ @deploy_strategy = path
64
71
 
65
72
  self
66
73
  end
@@ -5,7 +5,8 @@ class KuberKit::Core::ConfigurationFactory
5
5
  "core.registry_store",
6
6
  "core.artifact_store",
7
7
  "core.env_file_store",
8
- "core.template_store"
8
+ "core.template_store",
9
+ "configs"
9
10
  ]
10
11
 
11
12
  def create(definition)
@@ -17,12 +18,13 @@ class KuberKit::Core::ConfigurationFactory
17
18
  templates = fetch_templates(configuration_attrs.templates)
18
19
 
19
20
  KuberKit::Core::Configuration.new(
20
- name: configuration_attrs.name,
21
- artifacts: artifacts,
22
- registries: registries,
23
- env_files: env_files,
24
- templates: templates,
25
- kubecfg_path: configuration_attrs.kubecfg_path
21
+ name: configuration_attrs.name,
22
+ artifacts: artifacts,
23
+ registries: registries,
24
+ env_files: env_files,
25
+ templates: templates,
26
+ kubeconfig_path: configuration_attrs.kubeconfig_path,
27
+ deploy_strategy: configuration_attrs.deploy_strategy || configs.deploy_strategy
26
28
  )
27
29
  end
28
30
 
@@ -25,6 +25,7 @@ class KuberKit::Core::ConfigurationStore
25
25
  @@configuration_definitions[configuration_definition.configuration_name] = configuration_definition
26
26
  end
27
27
 
28
+ Contract Symbol => Any
28
29
  def get_definition(configuration_name)
29
30
  @@configuration_definitions ||= {}
30
31
 
@@ -35,6 +36,7 @@ class KuberKit::Core::ConfigurationStore
35
36
  @@configuration_definitions[configuration_name]
36
37
  end
37
38
 
39
+ Contract Symbol => Any
38
40
  def get_configuration(configuration_name)
39
41
  definition = get_definition(configuration_name)
40
42
 
@@ -1,4 +1,6 @@
1
1
  class KuberKit::Core::ContextHelper::BaseHelper
2
+ CONTRACT = RespondTo[:get_binding]
3
+
2
4
  attr_reader :shell, :artifact_store, :image_store
3
5
 
4
6
  def initialize(image_store:, artifact_store:, shell:)
@@ -13,7 +13,10 @@ class KuberKit::Core::ContextHelper::ServiceHelper < KuberKit::Core::ContextHelp
13
13
  end
14
14
 
15
15
  def service_uri
16
- service_name
17
- .sub("_", "-")
16
+ @service.uri
17
+ end
18
+
19
+ def attribute(attribute_name)
20
+ @service.attribute(attribute_name)
18
21
  end
19
22
  end
@@ -25,6 +25,7 @@ class KuberKit::Core::ImageStore
25
25
  @@image_definitions[image_definition.image_name] = image_definition
26
26
  end
27
27
 
28
+ Contract Symbol => Any
28
29
  def get_definition(image_name)
29
30
  @@image_definitions ||= {}
30
31
 
@@ -35,6 +36,7 @@ class KuberKit::Core::ImageStore
35
36
  @@image_definitions[image_name]
36
37
  end
37
38
 
39
+ Contract Symbol => Any
38
40
  def get_image(image_name)
39
41
  definition = get_definition(image_name)
40
42
 
@@ -1,14 +1,32 @@
1
1
  class KuberKit::Core::Service
2
- attr_reader :name, :template_name, :tags
2
+ AttributeNotSet = Class.new(Indocker::Error)
3
+
4
+ attr_reader :name, :template_name, :tags, :images, :attributes
3
5
 
4
6
  Contract KeywordArgs[
5
7
  name: Symbol,
6
8
  template_name: Symbol,
7
9
  tags: ArrayOf[Symbol],
10
+ images: ArrayOf[Symbol],
11
+ attributes: HashOf[Symbol => Any],
8
12
  ] => Any
9
- def initialize(name:, template_name:, tags:)
13
+ def initialize(name:, template_name:, tags:, images:, attributes:)
10
14
  @name = name
11
15
  @template_name = template_name
12
16
  @tags = tags
17
+ @images = images
18
+ @attributes = attributes
19
+ end
20
+
21
+ def uri
22
+ name.to_s.gsub("_", "-")
23
+ end
24
+
25
+ def attribute(attribute_name)
26
+ unless attributes.has_key?(attribute_name.to_sym)
27
+ raise AttributeNotSet, "attribute #{attribute_name} was not set"
28
+ end
29
+
30
+ attributes[attribute_name.to_sym]
13
31
  end
14
32
  end
@@ -10,7 +10,9 @@ class KuberKit::Core::ServiceDefinition
10
10
  OpenStruct.new(
11
11
  name: @service_name,
12
12
  template_name: get_value(@template_name),
13
- tags: Array(get_value(@tags)).map(&:to_sym)
13
+ tags: Array(get_value(@tags)).map(&:to_sym),
14
+ images: Array(get_value(@images)).map(&:to_sym),
15
+ attributes: get_value(@attributes),
14
16
  )
15
17
  end
16
18
 
@@ -26,6 +28,18 @@ class KuberKit::Core::ServiceDefinition
26
28
  self
27
29
  end
28
30
 
31
+ def images(*value, &block)
32
+ @images = block_given? ? block : Array(value).flatten
33
+
34
+ self
35
+ end
36
+
37
+ def attributes(value = nil, &block)
38
+ @attributes = block_given? ? block : value
39
+
40
+ self
41
+ end
42
+
29
43
  private
30
44
  def get_value(variable)
31
45
  variable.is_a?(Proc) ? variable.call : variable
@@ -11,7 +11,9 @@ class KuberKit::Core::ServiceFactory
11
11
  KuberKit::Core::Service.new(
12
12
  name: service_attrs.name,
13
13
  template_name: service_attrs.template_name,
14
- tags: service_attrs.tags
14
+ tags: service_attrs.tags,
15
+ images: service_attrs.images,
16
+ attributes: service_attrs.attributes || {}
15
17
  )
16
18
  end
17
19
  end
@@ -5,7 +5,8 @@ class KuberKit::Core::ServiceStore
5
5
  include KuberKit::Import[
6
6
  "core.service_factory",
7
7
  "core.service_definition_factory",
8
- "shell.local_shell"
8
+ "shell.local_shell",
9
+ "tools.logger"
9
10
  ]
10
11
 
11
12
  def define(service_name)
@@ -24,6 +25,7 @@ class KuberKit::Core::ServiceStore
24
25
  @@service_definitions[service_definition.service_name] = service_definition
25
26
  end
26
27
 
28
+ Contract Symbol => Any
27
29
  def get_definition(service_name)
28
30
  @@service_definitions ||= {}
29
31
 
@@ -34,6 +36,7 @@ class KuberKit::Core::ServiceStore
34
36
  @@service_definitions[service_name]
35
37
  end
36
38
 
39
+ Contract Symbol => Any
37
40
  def get_service(service_name)
38
41
  definition = get_definition(service_name)
39
42
 
@@ -44,6 +47,9 @@ class KuberKit::Core::ServiceStore
44
47
  files = local_shell.recursive_list_files(dir_path, name: "*.rb").each do |path|
45
48
  load_definition(path)
46
49
  end
50
+ rescue KuberKit::Shell::AbstractShell::DirNotFoundError
51
+ logger.warn("Directory with services not found: #{dir_path}")
52
+ []
47
53
  end
48
54
 
49
55
  def load_definition(file_path)
@@ -15,7 +15,7 @@ class KuberKit::ImageCompiler::Compiler
15
15
  context_helper = context_helper_factory.build_image_context(shell)
16
16
  image_build_dir_creator.create(shell, image, image_build_dir, context_helper: context_helper)
17
17
 
18
- image_builder.build(shell, image, image_build_dir, context_helper: context_helper, args: [])
18
+ image_builder.build(shell, image, image_build_dir, context_helper: context_helper)
19
19
  image_build_dir_creator.cleanup(shell, image_build_dir)
20
20
  end
21
21
  end
@@ -5,10 +5,9 @@ class KuberKit::ImageCompiler::ImageBuilder
5
5
  ]
6
6
 
7
7
  Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Image, String, KeywordArgs[
8
- args: Maybe[Any],
9
- context_helper: Maybe[KuberKit::Core::ContextHelper]
8
+ context_helper: Maybe[KuberKit::Core::ContextHelper::BaseHelper::CONTRACT]
10
9
  ] => Any
11
- def build(shell, image, build_dir, context_helper: nil, args: [])
10
+ def build(shell, image, build_dir, context_helper: nil)
12
11
  image.before_build_callback.call(context_helper, build_dir) if image.before_build_callback
13
12
 
14
13
  docker_commands.build(shell, build_dir, ["-t=#{image.registry_url}"])
@@ -0,0 +1,15 @@
1
+ class KuberKit::ServiceDeployer::Deployer
2
+ include KuberKit::Import[
3
+ "service_deployer.service_restarter",
4
+ "core.service_store",
5
+ ]
6
+
7
+ Contract KuberKit::Shell::AbstractShell, Symbol => Any
8
+ def deploy(shell, service_name)
9
+ service = service_store.get_service(service_name)
10
+
11
+ strategy_name = KuberKit.current_configuration.deploy_strategy
12
+
13
+ service_restarter.restart(shell, service, strategy_name)
14
+ end
15
+ end
@@ -6,6 +6,7 @@ class KuberKit::ServiceDeployer::ServiceReader
6
6
  "preprocessing.text_preprocessor"
7
7
  ]
8
8
 
9
+ Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
9
10
  def read(shell, service)
10
11
  template = template_store.get(service.template_name)
11
12
 
@@ -0,0 +1,37 @@
1
+ class KuberKit::ServiceDeployer::ServiceRestarter
2
+ StrategyNotFoundError = Class.new(KuberKit::NotFoundError)
3
+
4
+ include KuberKit::Import[
5
+ "core.service_store",
6
+ "service_deployer.strategies.kubernetes"
7
+ ]
8
+
9
+ def register_strategy(strategy_name, strategy)
10
+ @@strategies ||= {}
11
+
12
+ if !strategy.is_a?(KuberKit::ServiceDeployer::Strategies::Abstract)
13
+ raise ArgumentError.new("should be an instance of KuberKit::ServiceDeployer::Strategies::Abstract, got: #{strategy.inspect}")
14
+ end
15
+
16
+ @@strategies[strategy_name] = strategy
17
+ end
18
+
19
+ Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service, Symbol => Any
20
+ def restart(shell, service, strategy_name)
21
+ add_default_strategies
22
+
23
+ restarter = @@strategies[strategy_name]
24
+
25
+ raise StrategyNotFoundError, "Can't find strategy with name #{strategy_name}" if restarter.nil?
26
+
27
+ restarter.restart(shell, service)
28
+ end
29
+
30
+ def add_default_strategies
31
+ register_strategy(:kubernetes, kubernetes)
32
+ end
33
+
34
+ def reset!
35
+ @@strategies = {}
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ class KuberKit::ServiceDeployer::Strategies::Abstract
2
+ def restart(shell, service)
3
+ raise KuberKit::NotImplementedError, "must be implemented"
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeployer::Strategies::Abstract
2
+ include KuberKit::Import[
3
+ "service_deployer.service_reader",
4
+ "shell.kubectl_commands",
5
+ "configs",
6
+ ]
7
+
8
+ Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
9
+ def restart(shell, service)
10
+ service_config = service_reader.read(shell, service)
11
+ config_path = "#{configs.service_config_dir}/#{service.name}.yml"
12
+ shell.write(config_path, service_config)
13
+
14
+ kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
15
+ kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path)
16
+ kubectl_commands.rolling_restart(shell, service.uri, kubeconfig_path: kubeconfig_path)
17
+ end
18
+ end
@@ -1,12 +1,42 @@
1
+ require 'json'
2
+ require 'shellwords'
3
+
1
4
  class KuberKit::Shell::KubectlCommands
2
- def apply_file(shell, file_path, kubecfg_path: nil)
5
+ def apply_file(shell, file_path, kubeconfig_path: nil)
3
6
  command_parts = []
4
- if kubecfg_path
5
- command_parts << "KUBECFG=#{kubecfg_path}"
7
+ if kubeconfig_path
8
+ command_parts << "KUBECONFIG=#{kubeconfig_path}"
6
9
  end
7
10
 
8
11
  command_parts << "kubectl apply -f #{file_path}"
9
12
 
10
13
  shell.exec!(command_parts.join(" "))
11
14
  end
15
+
16
+ def rolling_restart(shell, deployment_name, kubeconfig_path: nil)
17
+ patch_deployment(shell, deployment_name, {
18
+ spec: {
19
+ template: {
20
+ metadata: {
21
+ labels: {
22
+ redeploy: "$(date +%s)"
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }, kubeconfig_path: kubeconfig_path)
28
+ end
29
+
30
+ def patch_deployment(shell, deployment_name, specs, kubeconfig_path: nil)
31
+ command_parts = []
32
+ if kubeconfig_path
33
+ command_parts << "KUBECONFIG=#{kubeconfig_path}"
34
+ end
35
+
36
+ specs_json = JSON.dump(specs).gsub('"', '\"')
37
+
38
+ command_parts << %Q{kubectl patch deployment #{deployment_name} -p "#{specs_json}"}
39
+
40
+ shell.exec!(command_parts.join(" "))
41
+ end
12
42
  end
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.5"
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.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Khaziev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-30 00:00:00.000000000 Z
11
+ date: 2020-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts-lite
@@ -162,15 +162,15 @@ files:
162
162
  - example/infrastructure/artifacts.rb
163
163
  - example/infrastructure/env_files.rb
164
164
  - example/infrastructure/registries.rb
165
- - example/infrastructure/services.rb
166
165
  - example/infrastructure/templates.rb
166
+ - example/services/ruby_app.rb
167
167
  - kuber_kit.gemspec
168
168
  - lib/kuber_kit.rb
169
169
  - lib/kuber_kit/actions/configuration_loader.rb
170
170
  - lib/kuber_kit/actions/env_file_reader.rb
171
171
  - lib/kuber_kit/actions/image_compiler.rb
172
172
  - lib/kuber_kit/actions/kubectl_applier.rb
173
- - lib/kuber_kit/actions/service_applier.rb
173
+ - lib/kuber_kit/actions/service_deployer.rb
174
174
  - lib/kuber_kit/actions/service_reader.rb
175
175
  - lib/kuber_kit/actions/template_reader.rb
176
176
  - lib/kuber_kit/artifacts_sync/abstract_artifact_resolver.rb
@@ -227,8 +227,12 @@ files:
227
227
  - lib/kuber_kit/preprocessing/dir_preprocessor.rb
228
228
  - lib/kuber_kit/preprocessing/file_preprocessor.rb
229
229
  - lib/kuber_kit/preprocessing/text_preprocessor.rb
230
+ - lib/kuber_kit/service_deployer/deployer.rb
230
231
  - lib/kuber_kit/service_deployer/service_list_resolver.rb
231
232
  - lib/kuber_kit/service_deployer/service_reader.rb
233
+ - lib/kuber_kit/service_deployer/service_restarter.rb
234
+ - lib/kuber_kit/service_deployer/strategies/abstract.rb
235
+ - lib/kuber_kit/service_deployer/strategies/kubernetes.rb
232
236
  - lib/kuber_kit/shell/abstract_shell.rb
233
237
  - lib/kuber_kit/shell/bash_commands.rb
234
238
  - lib/kuber_kit/shell/command_counter.rb
@@ -1,3 +0,0 @@
1
- KuberKit
2
- .define_service(:auth_app)
3
- .template(:service)
@@ -1,39 +0,0 @@
1
- class KuberKit::Actions::ServiceApplier
2
- include KuberKit::Import[
3
- "core.service_store",
4
- "service_deployer.service_reader",
5
- "service_deployer.service_list_resolver",
6
- "shell.local_shell",
7
- "shell.kubectl_commands",
8
- "configs",
9
- "ui"
10
- ]
11
-
12
- Contract KeywordArgs[
13
- services: Maybe[ArrayOf[String]],
14
- tags: Maybe[ArrayOf[String]],
15
- ] => Any
16
- def call(services:, tags:)
17
- service_names = service_list_resolver.resolve(
18
- services: services || [],
19
- tags: tags || []
20
- )
21
- service_names.each do |service_name|
22
- apply_service(service_name.to_sym)
23
- end
24
- end
25
-
26
- def apply_service(service_name)
27
- service = service_store.get_service(service_name)
28
- kubecfg_path = KuberKit.current_configuration.kubecfg_path
29
-
30
- result = service_reader.read(local_shell, service)
31
- file_path = "#{configs.service_config_dir}/#{service.name}.yml"
32
- local_shell.write(file_path, result)
33
-
34
- ui.create_task("Applying file: #{file_path}") do |task|
35
- kubectl_commands.apply_file(local_shell, file_path, kubecfg_path: kubecfg_path)
36
- task.update_title("Applied file: #{file_path}")
37
- end
38
- end
39
- end