stax-helm 0.0.4 → 0.0.9

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: 4c41b28fe1fde84c9dc771a618e0bfbeccd1718854aea285f41a4e115c73252f
4
- data.tar.gz: '09525e2ae890c6b35306b578ac7099488f734920ac5f8aea250413652f7eebf7'
3
+ metadata.gz: 53e53de7fb96d2b35470594bbb80e1de7bcbcf41aad867d6d20217db8bc20aef
4
+ data.tar.gz: 99f8d5f4a0964e66303803885d4f065d0979606f33cceed2afc7b5e82869f650
5
5
  SHA512:
6
- metadata.gz: f2a5c1f4c00e3211799a516e6645af725c537a7ad96bb4ae4f60dd48be1df90be961a78108fa0a11057f7ba9832a842561d9a47cd3d341b9aacaa83da87b7906
7
- data.tar.gz: 7260772678070aa147160ec8e072fe912a1bd79d772917b9a347fd65565c8ab5b2724f1fddc6d02e6c5e400a4748f9ec0523e01777686a980472c9215ca8d2e1
6
+ metadata.gz: 5cf3d1c0a868fdb26deb92346704bb3dacf507f28c3b70761b6525d3ecca93891fa0e1276533cfd3096913a1944d418469de7b7dbcf2383417803cc11fd7396c
7
+ data.tar.gz: d581092b08654b29454a72ab0c1ff198d47caa0aa1663baa17123898bc0cd738d01994cb4f7f9daf20cd19542124f3e8d630d55188f2bacc632339b889c556b4
@@ -1,7 +1,11 @@
1
+ require 'stax/helm/base'
1
2
  require 'stax/helm/cmd'
2
3
  require 'stax/helm/kubectl'
3
4
  require 'stax/helm/ingress'
4
5
  require 'stax/helm/pod'
5
6
  require 'stax/helm/deployment'
7
+ require 'stax/helm/jobs'
8
+ require 'stax/helm/cronjobs'
6
9
  require 'stax/helm/stern'
10
+ require 'stax/helm/runcmd'
7
11
  Stax.add_command(:helm, Stax::Helm::Cmd)
@@ -0,0 +1,16 @@
1
+ module Stax
2
+ class Base < Thor
3
+
4
+ no_commands do
5
+ def helm_release_name
6
+ @_helm_release_name ||= helm_safe("#{app_name}-#{branch_name}")
7
+ end
8
+
9
+ ## make string safe to use in naming helm stuff
10
+ def helm_safe(string)
11
+ string.slice(0, 53).gsub(/[\W_]/, '-').downcase
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -1,13 +1,10 @@
1
1
  module Stax
2
2
  module Helm
3
+
3
4
  class Cmd < Base
4
5
  class_option :recon, aliases: '--just-print', type: :boolean, default: false, desc: 'print command that would be run'
5
6
 
6
7
  no_commands do
7
- def helm_release_name
8
- @_helm_release_name ||= "#{app_name}-#{branch_name}"
9
- end
10
-
11
8
  ## location of helm chart
12
9
  def helm_dir
13
10
  File.join(Stax.root_path, 'helm')
@@ -0,0 +1,13 @@
1
+ ## tasks to get cronjob details
2
+ module Stax
3
+ module Helm
4
+ class Cmd < Base
5
+
6
+ desc 'cronjobs', 'list cronjobs'
7
+ def cronjobs
8
+ kubectl_run(:get, :cronjobs, '-l', helm_selector)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -3,11 +3,54 @@ module Stax
3
3
  module Helm
4
4
  class Cmd < Base
5
5
 
6
+ no_commands do
7
+ def helm_deployments
8
+ jsonpath = '{.items[*].metadata.name}'
9
+ %x[kubectl get deployments -o=jsonpath='#{jsonpath}' -l #{helm_selector}].split
10
+ end
11
+
12
+ ## prompt user with a list of deployments to choose
13
+ def helm_ask_deployments(msg)
14
+ deployments = helm_deployments
15
+ if deployments.count > 1
16
+ puts deployments.each_with_index.map { |d, i| "#{i}: #{d}" }
17
+ resp = ask(msg, default: 'all')
18
+ if resp != 'all'
19
+ indices = resp.split.map(&:to_i)
20
+ deployments = Array(deployments.slice(*indices))
21
+ end
22
+ end
23
+ deployments
24
+ end
25
+ end
26
+
6
27
  desc 'deployments', 'list deployments'
7
28
  def deployments
8
29
  kubectl_run(:get, :deployments, '-l', helm_selector)
9
30
  end
10
31
 
32
+ desc 'restart', 'restart deployments'
33
+ def restart
34
+ helm_ask_deployments('choose deployments').each do |deployment|
35
+ kubectl_run(:rollout, :restart, :deployment, deployment)
36
+ end
37
+ end
38
+
39
+ desc 'scale', 'show/set scale for deployments'
40
+ method_option :replicas, aliases: '-r', type: :numeric, default: nil, desc: 'replicas'
41
+ def scale
42
+ if options[:replicas]
43
+ deployments = helm_ask_deployments('choose deployments').join(' ')
44
+ kubectl_run(:scale, :deployment, deployments, '--replicas', options[:replicas])
45
+ else
46
+ debug("Deployment replicas for #{helm_release_name}")
47
+ deployments = kubectl_json(:get, :deployments, '-l', helm_selector)
48
+ print_table deployments['items'].map { |i|
49
+ [ i['metadata']['name'], i['status']['replicas'] || 0 ]
50
+ }
51
+ end
52
+ end
53
+
11
54
  end
12
55
  end
13
56
  end
@@ -0,0 +1,13 @@
1
+ ## tasks to get job details
2
+ module Stax
3
+ module Helm
4
+ class Cmd < Base
5
+
6
+ desc 'jobs', 'list jobs'
7
+ def jobs
8
+ kubectl_run(:get, :jobs, '-l', helm_selector)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -12,6 +12,12 @@ module Stax
12
12
  options[:recon] ? puts(cmd) : system(cmd)
13
13
  end
14
14
 
15
+ def kubectl_json(*args)
16
+ args.push('-o=json')
17
+ cmd = [kubectl_bin, *args].join(' ')
18
+ options[:recon] ? puts(cmd) : JSON.parse(%x(#{cmd}))
19
+ end
20
+
15
21
  ## override this to match all objects in your helm release
16
22
  def helm_selector
17
23
  "app.kubernetes.io/instance=#{helm_release_name}"
@@ -33,6 +33,7 @@ module Stax
33
33
 
34
34
  desc 'logs [OPTIONS]', 'run kubectl logs with same options'
35
35
  def logs(*args)
36
+ trap('SIGINT', 'EXIT') # clean exit with ctrl-c
36
37
  args = [ '--all-containers', '--prefix', '--follow' ] if args.empty? # helpful default args
37
38
  kubectl_run(:logs, '-l', helm_selector, *args)
38
39
  end
@@ -0,0 +1,108 @@
1
+ require 'securerandom'
2
+
3
+ module Stax
4
+ module Helm
5
+ class Cmd
6
+
7
+ no_commands do
8
+ ## construct a Job template
9
+ def helm_run_template(name)
10
+ {
11
+ apiVersion: 'batch/v1',
12
+ kind: :Job,
13
+ metadata: {
14
+ name: name,
15
+ labels: {
16
+ 'app.kubernetes.io/managed-by' => :stax
17
+ }
18
+ },
19
+ spec: {
20
+ template: {
21
+ spec: {
22
+ restartPolicy: :Never
23
+ }
24
+ }
25
+ }
26
+ }
27
+ end
28
+
29
+ ## Deployment to clone for container
30
+ def helm_run_deployment
31
+ "#{helm_release_name}-web"
32
+ end
33
+
34
+ ## name of container to clone from Deployment
35
+ def helm_run_container
36
+ 'web'
37
+ end
38
+
39
+ ## name for Job to create based on container
40
+ def helm_run_job
41
+ "#{helm_release_name}-run-#{SecureRandom.hex(4)}"
42
+ end
43
+
44
+ ## default command to run
45
+ def helm_run_cmd
46
+ 'bash'
47
+ end
48
+ end
49
+
50
+ ## task creates a dedicated unique kubernetes Job, with
51
+ ## container spec based on the helm release deployment
52
+ ## requested, then does an interactive exec to the pod and
53
+ ## container created, and deletes the Job on exit
54
+ desc 'runcmd [CMD]', 'run dedicated interactive container'
55
+ method_option :sleep, type: :string, default: '1h', description: 'kill container after time'
56
+ method_option :keep, type: :boolean, default: false, description: 'do not delete job'
57
+ def runcmd(*cmd)
58
+ ## use default if not set
59
+ cmd = Array(helm_run_cmd) if cmd.empty?
60
+
61
+ ## name of k8s Job to create, and basic template
62
+ job = helm_run_job
63
+ template = helm_run_template(job)
64
+
65
+ ## get deployment and extract container spec
66
+ deployment = kubectl_json(:get, :deployment, helm_run_deployment)
67
+ spec = deployment.dig('spec', 'template', 'spec', 'containers').find do |c|
68
+ c['name'] == helm_run_container
69
+ end
70
+
71
+ ## cleanup the container spec so we can use it in a Job
72
+ spec.delete('livenessProbe')
73
+ spec.delete('readinessProbe')
74
+ spec.delete('volumeMounts')
75
+ spec['name'] = 'run'
76
+ spec['args'] = ['sleep', options[:sleep]]
77
+
78
+ ## add container to Job template
79
+ template[:spec][:template][:spec][:containers] = [ spec ]
80
+
81
+ ## get service account and add to template
82
+ service_account = deployment.dig('spec', 'template', 'spec', 'serviceAccountName')
83
+ template[:spec][:template][:spec][:serviceAccountName] = service_account if service_account
84
+
85
+ ## create new unique Job based on the container spec
86
+ debug("Creating job #{job}")
87
+ Open3.popen2('kubectl create -f -') { |stdin, stdout, _|
88
+ stdin.print(template.to_json)
89
+ stdin.close
90
+ puts stdout.gets
91
+ }
92
+
93
+ ## get name of the Pod created by the Job
94
+ pod = kubectl_json(:get, :pod, '-l', "job-name=#{job}")['items'].first['metadata']['name']
95
+
96
+ ## exec into the pod and run interactive command
97
+ debug("Connecting to pod #{pod}")
98
+ kubectl_run(:wait, '--for=condition=Ready', '--timeout=5m', :pod, pod)
99
+ kubectl_run(:exec, '-it', pod, '--', *cmd)
100
+ rescue JSON::ParserError
101
+ fail_task('cannot get kubernetes resource')
102
+ ensure
103
+ ## delete Job
104
+ kubectl_run(:delete, :job, job) unless options[:keep]
105
+ end
106
+ end
107
+ end
108
+ end
@@ -16,6 +16,7 @@ module Stax
16
16
  ## pass through args to stern
17
17
  desc 'stern [STERN_ARGS]', 'use stern to show logs'
18
18
  def stern(*args)
19
+ trap('SIGINT', 'EXIT') # clean exit with ctrl-c
19
20
  stern_run('-l', helm_selector, *args)
20
21
  end
21
22
 
@@ -1,5 +1,5 @@
1
1
  module Stax
2
2
  module Helm
3
- VERSION = '0.0.4'
3
+ VERSION = '0.0.9'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stax-helm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Lister
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-08 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: bundler
@@ -67,11 +67,15 @@ files:
67
67
  - README.md
68
68
  - Rakefile
69
69
  - lib/stax/helm.rb
70
+ - lib/stax/helm/base.rb
70
71
  - lib/stax/helm/cmd.rb
72
+ - lib/stax/helm/cronjobs.rb
71
73
  - lib/stax/helm/deployment.rb
72
74
  - lib/stax/helm/ingress.rb
75
+ - lib/stax/helm/jobs.rb
73
76
  - lib/stax/helm/kubectl.rb
74
77
  - lib/stax/helm/pod.rb
78
+ - lib/stax/helm/runcmd.rb
75
79
  - lib/stax/helm/stern.rb
76
80
  - lib/stax/helm/version.rb
77
81
  - stax-helm.gemspec