kuber_kit 0.1.9 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7fcc957995bcc680107ef41f95ef77d5ee20dda2c0063d31e21bf339ccdae2d
4
- data.tar.gz: 80561e6e2562b9f195e6725c9dfcd785d36d741b4cf1779c7ccf1d071193c5ec
3
+ metadata.gz: 88cc2d5d20c0f1bc958f8ecd8682ff66069cd95867b44e717c29adde0378c0c2
4
+ data.tar.gz: a3ebb9fd30393f45fab0f0ddfcd6aa8569777655a6a407bfe4df653b94e31123
5
5
  SHA512:
6
- metadata.gz: bd95c6391e1880cbe6e92eb43fc13278da1cef2bcf47c0bd0e2aab66932c640bf8c709dae8df5b36961baf19d41acd6c846907f27cab237a7d37113642d6b8ee
7
- data.tar.gz: 433d47c04f1a8f61e55e6dd664ab0818c0e687769cd29e9985acd74886abd2e5f4a2dacede60839c85797d71fa887e1196c61076837f6813c4fb55ac00fc25c2
6
+ metadata.gz: 275c26b658b4f0739a364bbbc58e1ec03bc45bbeeb7d4dec8988ff8f2f7c598ef43e96a15991f0201c271259380a3949b48dccd6f5f3ab6a88c541f3f38f5a68
7
+ data.tar.gz: 7f3780629d0836443d20914551b427ce557e35f336c7640a4da6c70eee0380616a4fbeefab23154306254bf6c86693f44388c527ed7e2490139f5210353a2357
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.1.9)
4
+ kuber_kit (0.2.4)
5
5
  cli-ui
6
6
  contracts-lite
7
7
  dry-auto_inject
@@ -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.4.9)
29
+ dry-core (0.4.10)
30
30
  concurrent-ruby (~> 1.0)
31
31
  dry-equalizer (0.3.0)
32
32
  method_source (1.0.0)
data/README.md CHANGED
@@ -17,13 +17,13 @@ gem 'kuber_kit'
17
17
  ### Launch compilation
18
18
 
19
19
  ```
20
- bin/kit compile ruby_app,ruby_app2 --path=./example
20
+ bundle exec bin/kit compile ruby_app,ruby_app2 --path=./example
21
21
  ```
22
22
 
23
23
  ### Launch deployment
24
24
 
25
25
  ```
26
- bin/kit compile -s ruby_app,ruby_app2 --path=./example
26
+ bundle exec bin/kit compile -s ruby_app,ruby_app2 --path=./example
27
27
  ```
28
28
 
29
29
 
data/TODO.md CHANGED
@@ -1,3 +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
1
6
  - list services and require confirmation before deployment
2
7
  - add build vars support (use images instead of containers)
3
8
  - template should be able to set default attributes
data/bin/kit CHANGED
@@ -2,7 +2,6 @@
2
2
  # -*- encoding: utf-8 -*-
3
3
 
4
4
  require 'rubygems'
5
- require 'bundler/setup'
6
5
  require "kuber_kit"
7
6
 
8
7
  KuberKit::CLI.start(ARGV)
@@ -1,6 +1,7 @@
1
1
  KuberKit
2
2
  .define_service(:env_file)
3
3
  .template(:env_file)
4
+ .tags("env_file")
4
5
  .attributes(
5
6
  deployment_restart_enabled: false
6
7
  )
@@ -1,4 +1,5 @@
1
1
  KuberKit
2
2
  .define_service(:ruby_app)
3
3
  .template(:service)
4
- .images(:ruby_app)
4
+ .images(:ruby_app)
5
+ .tags("app")
@@ -157,6 +157,7 @@ module KuberKit
157
157
  autoload :ServiceDeployer, 'actions/service_deployer'
158
158
  autoload :ConfigurationLoader, 'actions/configuration_loader'
159
159
  autoload :KubectlApplier, 'actions/kubectl_applier'
160
+ autoload :KubectlAttacher, 'actions/kubectl_attacher'
160
161
  end
161
162
 
162
163
  module Extensions
@@ -65,13 +65,17 @@ class KuberKit::Actions::ConfigurationLoader
65
65
  configuration_name ||= :_default_
66
66
  end
67
67
 
68
+ all_configurations = configuration_store.all_definitions.values
68
69
  if configuration_store.count == 1 && configuration_name.nil?
69
- first_configurations = configuration_store.all_definitions.values.first
70
+ first_configurations = all_configurations.first
70
71
  configuration_name = first_configurations.configuration_name
71
72
  end
72
73
 
73
74
  if configuration_store.count > 1 && configuration_name.nil?
74
- raise KuberKit::Error, "Please set configuration name using -C option"
75
+ options = all_configurations.map(&:configuration_name).map(&:to_s)
76
+ ui.prompt("Please select configuration name (or set it using -C option)", options) do |selection|
77
+ configuration_name = selection
78
+ end
75
79
  end
76
80
 
77
81
  KuberKit.set_configuration_name(configuration_name)
@@ -7,9 +7,10 @@ class KuberKit::Actions::KubectlApplier
7
7
 
8
8
  Contract String, Hash => Any
9
9
  def call(file_path, options)
10
- kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
10
+ kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
11
+ deploy_namespace = KuberKit.current_configuration.deploy_namespace
11
12
  ui.create_task("Applying file: #{file_path}") do |task|
12
- kubectl_commands.apply_file(local_shell, file_path, kubeconfig_path: kubeconfig_path)
13
+ kubectl_commands.apply_file(local_shell, file_path, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
13
14
  task.update_title("Applied file: #{file_path}")
14
15
  end
15
16
 
@@ -0,0 +1,26 @@
1
+ class KuberKit::Actions::KubectlAttacher
2
+ include KuberKit::Import[
3
+ "shell.kubectl_commands",
4
+ "shell.local_shell",
5
+ "ui"
6
+ ]
7
+
8
+ Contract String, Hash => Any
9
+ def call(pod_name, options)
10
+ kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
11
+ deploy_namespace = KuberKit.current_configuration.deploy_namespace
12
+
13
+ kubectl_commands.exec(
14
+ local_shell, pod_name, "bash", args: "-it",
15
+ kubeconfig_path: kubeconfig_path,
16
+ interactive: true,
17
+ namespace: deploy_namespace
18
+ )
19
+
20
+ true
21
+ rescue KuberKit::Error => e
22
+ ui.print_error("Error", e.message)
23
+
24
+ false
25
+ end
26
+ end
@@ -14,6 +14,10 @@ class KuberKit::Actions::ServiceDeployer
14
14
  tags: Maybe[ArrayOf[String]],
15
15
  ] => Any
16
16
  def call(services:, tags:)
17
+ if services.empty? && tags.empty?
18
+ services, tags = show_tags_selection
19
+ end
20
+
17
21
  service_names = service_list_resolver.resolve(
18
22
  services: services || [],
19
23
  tags: tags || []
@@ -59,4 +63,41 @@ class KuberKit::Actions::ServiceDeployer
59
63
  def compile_images(images_names)
60
64
  image_compiler.call(images_names, {}) if images_names.any?
61
65
  end
66
+
67
+ def show_tags_selection()
68
+ specific_service_option = "deploy specific service"
69
+
70
+ tags = [specific_service_option]
71
+ tags += service_store
72
+ .all_definitions
73
+ .values
74
+ .map(&:to_service_attrs)
75
+ .map(&:tags)
76
+ .flatten
77
+ .uniq
78
+ .sort
79
+ .map(&:to_s)
80
+
81
+ ui.prompt("Please select which tag to deploy", tags) do |selected_tag|
82
+ if selected_tag == specific_service_option
83
+ show_service_selection
84
+ else
85
+ return [[], [selected_tag]]
86
+ end
87
+ end
88
+ end
89
+
90
+ def show_service_selection()
91
+ services = service_store
92
+ .all_definitions
93
+ .values
94
+ .map(&:service_name)
95
+ .uniq
96
+ .sort
97
+ .map(&:to_s)
98
+
99
+ ui.prompt("Please select which service to deploy", services) do |selected_service|
100
+ return [[selected_service], []]
101
+ end
102
+ end
62
103
  end
@@ -14,11 +14,12 @@ class KuberKit::CLI < Thor
14
14
 
15
15
  image_names = image_names_str.split(",").map(&:strip).map(&:to_sym)
16
16
 
17
- KuberKit::Container['actions.configuration_loader'].call(options)
18
- result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
17
+ if KuberKit::Container['actions.configuration_loader'].call(options)
18
+ result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
19
+ end
19
20
 
21
+ logger = KuberKit::Container['tools.logger']
20
22
  if result
21
- logger = KuberKit::Container['tools.logger']
22
23
  logger.info("---------------------------")
23
24
  logger.info("Image compilation finished!")
24
25
  logger.info("---------------------------")
@@ -29,47 +30,74 @@ class KuberKit::CLI < Thor
29
30
  end
30
31
  end
31
32
 
33
+ desc "deploy CONTEXT_NAME", "Deploy CONTEXT_NAME with kubectl"
34
+ method_option :services, :type => :array, aliases: ["-s"]
35
+ method_option :tags, :type => :array, aliases: ["-t"]
36
+ def deploy
37
+ KuberKit.set_debug_mode(options[:debug])
38
+
39
+ if KuberKit::Container['actions.configuration_loader'].call(options)
40
+ result = KuberKit::Container['actions.service_deployer'].call(
41
+ services: options[:services] || [],
42
+ tags: options[:tags] || []
43
+ )
44
+ end
45
+
46
+ logger = KuberKit::Container['tools.logger']
47
+ if result
48
+ logger.info("---------------------------")
49
+ logger.info("Service deployment finished!")
50
+ logger.info("---------------------------")
51
+ else
52
+ logger.info("-------------------------".red)
53
+ logger.info("Service deployment failed!".red)
54
+ logger.info("-------------------------".red)
55
+ end
56
+ end
57
+
32
58
  desc "env ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
33
59
  def env(env_file_name)
34
60
  KuberKit.set_debug_mode(options[:debug])
35
61
 
36
- KuberKit::Container['actions.configuration_loader'].call(options)
37
- KuberKit::Container['actions.env_file_reader'].call(env_file_name.to_sym, options)
62
+ if KuberKit::Container['actions.configuration_loader'].call(options)
63
+ KuberKit::Container['actions.env_file_reader'].call(env_file_name.to_sym, options)
64
+ end
38
65
  end
39
66
 
40
67
  desc "template TEMPLATE_NAME", "Return content of Template TEMPLATE_NAME"
41
68
  def template(template_name)
42
69
  KuberKit.set_debug_mode(options[:debug])
43
70
 
44
- KuberKit::Container['actions.configuration_loader'].call(options)
45
- KuberKit::Container['actions.template_reader'].call(template_name.to_sym, options)
71
+ if KuberKit::Container['actions.configuration_loader'].call(options)
72
+ KuberKit::Container['actions.template_reader'].call(template_name.to_sym, options)
73
+ end
46
74
  end
47
75
 
48
76
  desc "service SERVICE_NAME", "Return content of Service SERVICE_NAME"
49
77
  def service(service_name)
50
78
  KuberKit.set_debug_mode(options[:debug])
51
79
 
52
- KuberKit::Container['actions.configuration_loader'].call(options)
53
- KuberKit::Container['actions.service_reader'].call(service_name.to_sym, options)
80
+ if KuberKit::Container['actions.configuration_loader'].call(options)
81
+ KuberKit::Container['actions.service_reader'].call(service_name.to_sym, options)
82
+ end
54
83
  end
55
84
 
56
85
  desc "apply FILE_PATH", "Apply FILE_PATH with kubectl"
57
86
  def apply(file_path)
58
87
  KuberKit.set_debug_mode(options[:debug])
59
88
 
60
- KuberKit::Container['actions.configuration_loader'].call(options)
61
- KuberKit::Container['actions.kubectl_applier'].call(File.expand_path(file_path), options)
89
+ if KuberKit::Container['actions.configuration_loader'].call(options)
90
+ KuberKit::Container['actions.kubectl_applier'].call(File.expand_path(file_path), options)
91
+ end
62
92
  end
63
93
 
64
- desc "deploy CONTEXT_NAME", "Deploy CONTEXT_NAME with kubectl"
65
- method_option :services, :type => :array, aliases: ["-s"]
66
- method_option :tags, :type => :array, aliases: ["-t"]
67
- def deploy
94
+ desc "attach POD_NAME", "Attach to POD_NAME with kubectl"
95
+ def attach(pod_name)
68
96
  KuberKit.set_debug_mode(options[:debug])
69
97
 
70
- KuberKit::Container['actions.configuration_loader'].call(options)
71
-
72
- KuberKit::Container['actions.service_deployer'].call(services: options[:services], tags: options[:tags])
98
+ if KuberKit::Container['actions.configuration_loader'].call(options)
99
+ KuberKit::Container['actions.kubectl_attacher'].call(pod_name, options)
100
+ end
73
101
  end
74
102
 
75
103
  def self.exit_on_failure?
@@ -29,6 +29,10 @@ class KuberKit::Container
29
29
  KuberKit::Actions::KubectlApplier.new
30
30
  end
31
31
 
32
+ register "actions.kubectl_attacher" do
33
+ KuberKit::Actions::KubectlAttacher.new
34
+ end
35
+
32
36
  register "configs" do
33
37
  KuberKit::Configs.new
34
38
  end
@@ -1,6 +1,6 @@
1
1
  class KuberKit::Core::Configuration
2
2
  attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path,
3
- :deploy_strategy, :services_attributes, :build_servers
3
+ :deploy_strategy, :deploy_namespace, :services_attributes, :build_servers
4
4
 
5
5
  Contract KeywordArgs[
6
6
  name: Symbol,
@@ -9,12 +9,13 @@ class KuberKit::Core::Configuration
9
9
  env_files: Hash,
10
10
  templates: Hash,
11
11
  kubeconfig_path: Maybe[String],
12
- deploy_strategy: Symbol,
12
+ deploy_strategy: Symbol,
13
+ deploy_namespace: Maybe[Symbol],
13
14
  services_attributes: HashOf[Symbol => Hash],
14
15
  build_servers: ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer]
15
16
  ] => Any
16
17
  def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:,
17
- deploy_strategy:, services_attributes:, build_servers:)
18
+ deploy_strategy:, deploy_namespace:, services_attributes:, build_servers:)
18
19
  @name = name
19
20
  @artifacts = artifacts
20
21
  @registries = registries
@@ -22,6 +23,7 @@ class KuberKit::Core::Configuration
22
23
  @templates = templates
23
24
  @kubeconfig_path = kubeconfig_path
24
25
  @deploy_strategy = deploy_strategy
26
+ @deploy_namespace = deploy_namespace
25
27
  @services_attributes = services_attributes
26
28
  @build_servers = build_servers
27
29
  end
@@ -24,9 +24,10 @@ class KuberKit::Core::ConfigurationDefinition
24
24
  templates: @templates,
25
25
  kubeconfig_path: @kubeconfig_path,
26
26
  deploy_strategy: @deploy_strategy,
27
+ deploy_namespace: @deploy_namespace,
27
28
  enabled_services: @enabled_services,
28
29
  build_servers: @build_servers,
29
- services_attributes: @services_attributes
30
+ services_attributes: @services_attributes,
30
31
  )
31
32
  end
32
33
 
@@ -80,6 +81,12 @@ class KuberKit::Core::ConfigurationDefinition
80
81
  self
81
82
  end
82
83
 
84
+ def deploy_namespace(namespace)
85
+ @deploy_namespace = namespace
86
+
87
+ self
88
+ end
89
+
83
90
  def deploy_strategy(path)
84
91
  @deploy_strategy = path
85
92
 
@@ -27,6 +27,7 @@ class KuberKit::Core::ConfigurationFactory
27
27
  templates: templates,
28
28
  kubeconfig_path: configuration_attrs.kubeconfig_path,
29
29
  deploy_strategy: configuration_attrs.deploy_strategy || configs.deploy_strategy,
30
+ deploy_namespace: configuration_attrs.deploy_namespace,
30
31
  services_attributes: configuration_attrs.services_attributes,
31
32
  build_servers: build_servers
32
33
  )
@@ -1,21 +1,23 @@
1
1
  class KuberKit::Core::Service
2
2
  AttributeNotSet = Class.new(Indocker::Error)
3
3
 
4
- attr_reader :name, :template_name, :tags, :images, :attributes
4
+ attr_reader :name, :template_name, :tags, :images, :attributes, :deploy_strategy
5
5
 
6
6
  Contract KeywordArgs[
7
- name: Symbol,
8
- template_name: Symbol,
9
- tags: ArrayOf[Symbol],
10
- images: ArrayOf[Symbol],
11
- attributes: HashOf[Symbol => Any],
7
+ name: Symbol,
8
+ template_name: Symbol,
9
+ tags: ArrayOf[Symbol],
10
+ images: ArrayOf[Symbol],
11
+ attributes: HashOf[Symbol => Any],
12
+ deploy_strategy: Maybe[Symbol]
12
13
  ] => Any
13
- def initialize(name:, template_name:, tags:, images:, attributes:)
14
+ def initialize(name:, template_name:, tags:, images:, attributes:, deploy_strategy:)
14
15
  @name = name
15
16
  @template_name = template_name
16
17
  @tags = tags
17
18
  @images = images
18
19
  @attributes = attributes
20
+ @deploy_strategy = deploy_strategy
19
21
  end
20
22
 
21
23
  def uri
@@ -8,11 +8,12 @@ class KuberKit::Core::ServiceDefinition
8
8
 
9
9
  def to_service_attrs
10
10
  OpenStruct.new(
11
- name: @service_name,
12
- template_name: get_value(@template_name),
13
- tags: Array(get_value(@tags)).map(&:to_sym),
14
- images: Array(get_value(@images)).map(&:to_sym),
15
- attributes: get_value(@attributes),
11
+ name: @service_name,
12
+ template_name: get_value(@template_name),
13
+ tags: Array(get_value(@tags)).map(&:to_sym),
14
+ images: Array(get_value(@images)).map(&:to_sym),
15
+ attributes: get_value(@attributes),
16
+ deploy_strategy: get_value(@deploy_strategy),
16
17
  )
17
18
  end
18
19
 
@@ -40,6 +41,12 @@ class KuberKit::Core::ServiceDefinition
40
41
  self
41
42
  end
42
43
 
44
+ def deploy_strategy(value = nil, &block)
45
+ @deploy_strategy = block_given? ? block : value
46
+
47
+ self
48
+ end
49
+
43
50
  private
44
51
  def get_value(variable)
45
52
  variable.is_a?(Proc) ? variable.call : variable
@@ -12,11 +12,12 @@ class KuberKit::Core::ServiceFactory
12
12
  attributes = (service_attrs.attributes || {}).merge(configuration_attributes)
13
13
 
14
14
  KuberKit::Core::Service.new(
15
- name: service_attrs.name,
16
- template_name: service_attrs.template_name,
17
- tags: service_attrs.tags,
18
- images: service_attrs.images,
19
- attributes: attributes
15
+ name: service_attrs.name,
16
+ template_name: service_attrs.template_name,
17
+ tags: service_attrs.tags,
18
+ images: service_attrs.images,
19
+ attributes: attributes,
20
+ deploy_strategy: service_attrs.deploy_strategy,
20
21
  )
21
22
  end
22
23
  end
@@ -4,12 +4,15 @@ class KuberKit::ImageCompiler::BuildServerPool
4
4
  def initialize(local_shell:, build_servers:, ssh_shell_class:)
5
5
  @local_shell = local_shell
6
6
  @ssh_shell_class = ssh_shell_class
7
- @ssh_shells = connect_to_ssh_shells(build_servers)
7
+ @build_servers = build_servers
8
+ @ssh_shells = []
8
9
  end
9
10
 
10
11
  def get_shell
11
- if @ssh_shells.any?
12
- @ssh_shells.sample
12
+ if @build_servers.any?
13
+ shell = connect_to_ssh_shell(@build_servers.sample)
14
+ @ssh_shells << shell
15
+ shell
13
16
  else
14
17
  @local_shell
15
18
  end
@@ -20,11 +23,9 @@ class KuberKit::ImageCompiler::BuildServerPool
20
23
  end
21
24
 
22
25
  private
23
- def connect_to_ssh_shells(build_servers)
24
- build_servers.map do |bs|
25
- shell = @ssh_shell_class.new
26
- shell.connect(host: bs.host, user: bs.user, port: bs.port)
27
- shell
28
- end
26
+ def connect_to_ssh_shell(bs)
27
+ shell = @ssh_shell_class.new
28
+ shell.connect(host: bs.host, user: bs.user, port: bs.port)
29
+ shell
29
30
  end
30
31
  end
@@ -11,13 +11,15 @@ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeplo
11
11
  config_path = "#{configs.service_config_dir}/#{service.name}.yml"
12
12
  shell.write(config_path, service_config)
13
13
 
14
- kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
15
- kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path)
14
+ kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
15
+ deploy_namespace = KuberKit.current_configuration.deploy_namespace
16
+
17
+ kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
16
18
 
17
19
  deployment_restart_enabled = service.attribute(:deployment_restart_enabled, default: true)
18
20
  deployment_restart_name = service.attribute(:deployment_restart_name, default: service.uri)
19
21
  if deployment_restart_enabled
20
- kubectl_commands.rolling_restart(shell, deployment_restart_name, kubeconfig_path: kubeconfig_path)
22
+ kubectl_commands.rolling_restart(shell, deployment_restart_name, kubeconfig_path: kubeconfig_path, namespace: deploy_namespace)
21
23
  end
22
24
  end
23
25
  end
@@ -1,6 +1,6 @@
1
1
  class KuberKit::ServiceDeployer::StrategyDetector
2
2
  Contract KuberKit::Core::Service => Symbol
3
3
  def call(service)
4
- KuberKit.current_configuration.deploy_strategy
4
+ service.deploy_strategy || KuberKit.current_configuration.deploy_strategy
5
5
  end
6
6
  end
@@ -2,18 +2,52 @@ require 'json'
2
2
  require 'shellwords'
3
3
 
4
4
  class KuberKit::Shell::Commands::KubectlCommands
5
- def apply_file(shell, file_path, kubeconfig_path: nil)
5
+ def kubectl_run(shell, command_list, kubeconfig_path: nil, namespace: nil, interactive: false)
6
6
  command_parts = []
7
7
  if kubeconfig_path
8
8
  command_parts << "KUBECONFIG=#{kubeconfig_path}"
9
9
  end
10
10
 
11
- command_parts << "kubectl apply -f #{file_path}"
11
+ command_parts << "kubectl"
12
12
 
13
- shell.exec!(command_parts.join(" "))
13
+ if namespace
14
+ command_parts << "-n #{namespace}"
15
+ end
16
+
17
+ command_parts += Array(command_list)
18
+
19
+ # TODO: investigate how to do it with shell.
20
+ if interactive
21
+ system(command_parts.join(" "))
22
+ else
23
+ shell.exec!(command_parts.join(" "))
24
+ end
25
+ end
26
+
27
+ def apply_file(shell, file_path, kubeconfig_path: nil, namespace: nil)
28
+ kubectl_run(shell, "apply -f #{file_path}", kubeconfig_path: kubeconfig_path, namespace: namespace)
14
29
  end
15
30
 
16
- def rolling_restart(shell, deployment_name, kubeconfig_path: nil)
31
+ def exec(shell, pod_name, command, args: nil, kubeconfig_path: nil, interactive: false, namespace: nil)
32
+ command_parts = []
33
+ command_parts << "exec"
34
+
35
+ if args
36
+ command_parts << args
37
+ end
38
+
39
+ command_parts << pod_name
40
+ command_parts << "-- #{command}"
41
+ kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, interactive: interactive, namespace: namespace)
42
+ end
43
+
44
+ def delete_resource(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
45
+ command = %Q{delete #{resource_type} #{resource_name}}
46
+
47
+ kubectl_run(shell, command, kubeconfig_path: kubeconfig_path, namespace: namespace)
48
+ end
49
+
50
+ def rolling_restart(shell, deployment_name, kubeconfig_path: nil, namespace: nil)
17
51
  patch_deployment(shell, deployment_name, {
18
52
  spec: {
19
53
  template: {
@@ -24,19 +58,14 @@ class KuberKit::Shell::Commands::KubectlCommands
24
58
  }
25
59
  }
26
60
  }
27
- }, kubeconfig_path: kubeconfig_path)
61
+ }, kubeconfig_path: kubeconfig_path, namespace: namespace)
28
62
  end
29
63
 
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
-
64
+ def patch_deployment(shell, deployment_name, specs, kubeconfig_path: nil, namespace: nil)
36
65
  specs_json = JSON.dump(specs).gsub('"', '\"')
37
66
 
38
- command_parts << %Q{kubectl patch deployment #{deployment_name} -p "#{specs_json}"}
67
+ command = %Q{patch deployment #{deployment_name} -p "#{specs_json}"}
39
68
 
40
- shell.exec!(command_parts.join(" "))
69
+ kubectl_run(shell, command, kubeconfig_path: kubeconfig_path, namespace: namespace)
41
70
  end
42
71
  end
@@ -1,5 +1,5 @@
1
1
  class KuberKit::Shell::Commands::RsyncCommands
2
- def rsync(shell, source_path, target_path, target_host: nil, exclude: nil)
2
+ def rsync(shell, source_path, target_path, target_host: nil, exclude: nil, delete: true)
3
3
  # Add a trailing slash to directory to have behavior similar to CP command
4
4
  if path_is_directory?(source_path) && !source_path.end_with?("/")
5
5
  source_path = "#{source_path}/"
@@ -13,7 +13,13 @@ class KuberKit::Shell::Commands::RsyncCommands
13
13
 
14
14
  args = [source_path, destination]
15
15
  if exclude
16
- args << "--exclude=#{exclude}"
16
+ Array(exclude).each do |e|
17
+ args << "--exclude=#{e}"
18
+ end
19
+ end
20
+
21
+ if delete
22
+ args << "--delete"
17
23
  end
18
24
 
19
25
  shell.exec!(%Q{rsync -a #{args.join(' ')}})
@@ -30,8 +30,8 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
30
30
  result
31
31
  end
32
32
 
33
- def sync(local_path, remote_path, exclude: nil)
34
- rsync_commands.rsync(self, local_path, remote_path, exclude: exclude)
33
+ def sync(local_path, remote_path, exclude: nil, delete: true)
34
+ rsync_commands.rsync(self, local_path, remote_path, exclude: exclude, delete: delete)
35
35
  end
36
36
 
37
37
  def read(file_path)
@@ -56,5 +56,7 @@ class KuberKit::Shell::SshSession
56
56
  end
57
57
 
58
58
  stdout_data
59
+ rescue Net::SSH::Exception => e
60
+ raise SshSessionError, "Shell command failed: #{command}\r\n#{e.message}"
59
61
  end
60
62
  end
@@ -38,11 +38,12 @@ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell
38
38
  raise ShellError.new(e.message)
39
39
  end
40
40
 
41
- def sync(local_path, remote_path, exclude: nil)
41
+ def sync(local_path, remote_path, exclude: nil, delete: true)
42
42
  rsync_commands.rsync(
43
43
  local_shell, local_path, remote_path,
44
44
  target_host: "#{ssh_session.user}@#{ssh_session.host}",
45
- exclude: exclude
45
+ exclude: exclude,
46
+ delete: delete
46
47
  )
47
48
  end
48
49
 
@@ -26,6 +26,14 @@ class KuberKit::UI::Interactive
26
26
  print_in_frame(title, text, color: :yellow)
27
27
  end
28
28
 
29
+ def prompt(text, options, &callback)
30
+ CLI::UI::Prompt.ask(text) do |handler|
31
+ options.each do |option|
32
+ handler.option(option, &callback)
33
+ end
34
+ end
35
+ end
36
+
29
37
  private
30
38
  def init
31
39
  @initialized = true
@@ -68,6 +68,12 @@ class KuberKit::UI::Simple
68
68
  print_text(title, text, color: String::Colors::YELLOW)
69
69
  end
70
70
 
71
+ def prompt(text, options, &callback)
72
+ print_info("Select", text)
73
+ result = $stdin.gets.chomp
74
+ callback.call(result)
75
+ end
76
+
71
77
  private
72
78
  def print_text(title, text, color:)
73
79
  puts "#{title.colorize(color)}\r\n #{text.colorize(color)}"
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.1.9"
3
- end
2
+ VERSION = "0.2.4"
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.9
4
+ version: 0.2.4
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-11-13 00:00:00.000000000 Z
11
+ date: 2020-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts-lite
@@ -187,6 +187,7 @@ files:
187
187
  - lib/kuber_kit/actions/env_file_reader.rb
188
188
  - lib/kuber_kit/actions/image_compiler.rb
189
189
  - lib/kuber_kit/actions/kubectl_applier.rb
190
+ - lib/kuber_kit/actions/kubectl_attacher.rb
190
191
  - lib/kuber_kit/actions/service_deployer.rb
191
192
  - lib/kuber_kit/actions/service_reader.rb
192
193
  - lib/kuber_kit/actions/template_reader.rb
@@ -282,7 +283,7 @@ homepage: https://github.com/ArtStation/kuber_kit
282
283
  licenses:
283
284
  - MIT
284
285
  metadata: {}
285
- post_install_message:
286
+ post_install_message:
286
287
  rdoc_options: []
287
288
  require_paths:
288
289
  - lib
@@ -298,7 +299,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
299
  version: '0'
299
300
  requirements: []
300
301
  rubygems_version: 3.0.8
301
- signing_key:
302
+ signing_key:
302
303
  specification_version: 4
303
304
  summary: Docker Containers Build & Deployment
304
305
  test_files: []