kubernetes-cli 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bb7820fe8fd6c5426e502bfaeab2e5e7b3ae3350900ffdab42acaa3328bd0fd7
4
+ data.tar.gz: ce6976bd46b6a7f98438738fc53910fef7ecce53082bb06062be49833892912c
5
+ SHA512:
6
+ metadata.gz: 53d1088eb10bdcaa0373d595fcc8dede6495f16836a2a985957082f8f33a99f2e1ae8892001eb8c15d0327a02c75e75e6ca71b3cf9d57cd7d5cdd5b2e6396199
7
+ data.tar.gz: 80b1971145ced2eb828df6cf61c63b909faa6a55650c745eaa1725b229e82f355ad1b7128834f38f1f3e6fe0a1205c917ab68ce9aa147f17674582aac209c724
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ # Declare platform-specific gems here so they install correctly.
6
+ # See: https://github.com/rubygems/rubygems/issues/3646
7
+ gem 'kubectl-rb'
8
+
9
+ group :development do
10
+ gem 'rake'
11
+ end
12
+
13
+ group :test do
14
+ gem 'rspec'
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Cameron Dutro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubygems/package_task'
4
+
5
+ require 'kubernetes-cli'
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ task default: :spec
10
+
11
+ desc 'Run specs'
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = './spec/**/*_spec.rb'
14
+ end
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'kubernetes-cli/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'kubernetes-cli'
6
+ s.version = ::KubernetesCLI::VERSION
7
+ s.authors = ['Cameron Dutro']
8
+ s.email = ['camertron@gmail.com']
9
+ s.homepage = 'http://github.com/getkuby/kubernetes-cli'
10
+ s.license = 'MIT'
11
+
12
+ s.description = s.summary = 'Ruby wrapper around the Kubernetes CLI.'
13
+
14
+ s.add_dependency 'kubectl-rb', '~> 0.1'
15
+
16
+ s.require_path = 'lib'
17
+ s.files = Dir['{lib,spec,vendor}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kubernetes-cli.gemspec']
18
+ end
@@ -0,0 +1,217 @@
1
+ require 'kubectl-rb'
2
+
3
+ class KubernetesCLI
4
+ attr_reader :kubeconfig_path, :executable
5
+
6
+ def initialize(kubeconfig_path, executable = KubectlRb.executable)
7
+ @kubeconfig_path = kubeconfig_path
8
+ @executable = executable
9
+ @before_execute = []
10
+ @after_execute = []
11
+ end
12
+
13
+ def before_execute(&block)
14
+ @before_execute << block
15
+ end
16
+
17
+ def after_execute(&block)
18
+ @after_execute << block
19
+ end
20
+
21
+ def last_status
22
+ Thread.current[status_key]
23
+ end
24
+
25
+ def run_cmd(cmd)
26
+ cmd = [executable, '--kubeconfig', kubeconfig_path, *Array(cmd)]
27
+ execc(cmd)
28
+ end
29
+
30
+ def exec_cmd(container_cmd, namespace, pod, tty = true)
31
+ cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace, 'exec']
32
+ cmd += ['-it'] if tty
33
+ cmd += [pod, '--', *Array(container_cmd)]
34
+ execc(cmd)
35
+ end
36
+
37
+ def apply(res, dry_run: false)
38
+ cmd = [executable, '--kubeconfig', kubeconfig_path, 'apply', '--validate']
39
+ cmd << '--dry-run=client' if dry_run
40
+ cmd += ['-f', '-']
41
+
42
+ open3_w(env, cmd) do |stdin, _wait_thread|
43
+ stdin.puts(res.to_resource.to_yaml)
44
+ end
45
+
46
+ unless last_status.success?
47
+ err = InvalidResourceError.new("Could not apply #{res.kind_sym.to_s.humanize.downcase} "\
48
+ "'#{res.metadata.name}': kubectl exited with status code #{last_status.exitstatus}"
49
+ )
50
+
51
+ err.resource = res
52
+ raise err
53
+ end
54
+ end
55
+
56
+ def apply_uri(uri, dry_run: false)
57
+ cmd = [executable, '--kubeconfig', kubeconfig_path, 'apply', '--validate']
58
+ cmd << '--dry-run=client' if dry_run
59
+ cmd += ['-f', uri]
60
+ systemm(cmd)
61
+
62
+ unless last_status.success?
63
+ err = InvalidResourceUriError.new("Could not apply #{uri}: "\
64
+ "kubectl exited with status code #{last_status.exitstatus}"
65
+ )
66
+
67
+ err.resource_uri = uri
68
+ raise err
69
+ end
70
+ end
71
+
72
+ def get_object(type, namespace, name = nil, match_labels = {})
73
+ cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace]
74
+ cmd += ['get', type, name]
75
+
76
+ unless match_labels.empty?
77
+ cmd += ['--selector', match_labels.map { |key, value| "#{key}=#{value}" }.join(',')]
78
+ end
79
+
80
+ cmd += ['-o', 'json']
81
+
82
+ result = backticks(cmd)
83
+
84
+ unless last_status.success?
85
+ raise GetResourceError, "couldn't get resources of type '#{type}' "\
86
+ "in namespace #{namespace}: kubectl exited with status code #{last_status.exitstatus}"
87
+ end
88
+
89
+ JSON.parse(result)
90
+ end
91
+
92
+ def get_objects(type, namespace, match_labels = {})
93
+ cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace]
94
+ cmd += ['get', type]
95
+
96
+ unless match_labels.empty?
97
+ cmd += ['--selector', match_labels.map { |key, value| "#{key}=#{value}" }.join(',')]
98
+ end
99
+
100
+ cmd += ['-o', 'json']
101
+
102
+ result = backticks(cmd)
103
+
104
+ unless last_status.success?
105
+ raise GetResourceError, "couldn't get resources of type '#{type}' "\
106
+ "in namespace #{namespace}: kubectl exited with status code #{last_status.exitstatus}"
107
+ end
108
+
109
+ JSON.parse(result)['items']
110
+ end
111
+
112
+ def annotate(type, namespace, name, annotations, overwrite: true)
113
+ cmd = [
114
+ executable,
115
+ '--kubeconfig', kubeconfig_path,
116
+ '-n', namespace,
117
+ 'annotate'
118
+ ]
119
+
120
+ cmd << '--overwrite' if overwrite
121
+ cmd += [type, name]
122
+
123
+ annotations.each do |key, value|
124
+ cmd << "'#{key}'='#{value}'"
125
+ end
126
+
127
+ systemm(cmd)
128
+
129
+ unless last_status.success?
130
+ raise KubernetesCLIError, "could not annotate resource '#{name}': kubectl "\
131
+ "exited with status code #{last_status.exitstatus}"
132
+ end
133
+ end
134
+
135
+ def logtail(namespace, selector, follow: true)
136
+ cmd = [executable, '--kubeconfig', kubeconfig_path, '-n', namespace, 'logs']
137
+ cmd << '-f' if follow
138
+ cmd << '--selector'
139
+ cmd << selector.map { |k, v| "#{k}=#{v}" }.join(',')
140
+ execc(cmd)
141
+ end
142
+
143
+ def current_context
144
+ cmd = [executable, '--kubeconfig', kubeconfig_path, 'config', 'current-context']
145
+ backticks(cmd).strip
146
+ end
147
+
148
+ private
149
+
150
+ def env
151
+ @env ||= {}
152
+ end
153
+
154
+ def status_key
155
+ :kubernetes_cli_last_status
156
+ end
157
+
158
+ def base_cmd
159
+ [executable, '--kubeconfig', kubeconfig_path]
160
+ end
161
+
162
+ def backticks(cmd)
163
+ cmd_s = cmd.join(' ')
164
+ `#{cmd_s}`.tap do
165
+ self.last_status = $?
166
+ end
167
+ end
168
+
169
+ def execc(cmd)
170
+ run_before_callbacks(cmd)
171
+ cmd_s = cmd.join(' ')
172
+ exec(cmd_s)
173
+ end
174
+
175
+ def systemm(cmd)
176
+ run_before_callbacks(cmd)
177
+ cmd_s = cmd.join(' ')
178
+ system(cmd_s).tap do
179
+ self.last_status = $?
180
+ run_after_callbacks(cmd)
181
+ end
182
+ end
183
+
184
+ def backticks(cmd)
185
+ run_before_callbacks(cmd)
186
+ cmd_s = cmd.join(' ')
187
+ `#{cmd_s}`.tap do
188
+ self.last_status = $?
189
+ run_after_callbacks(cmd)
190
+ end
191
+ end
192
+
193
+ def open3_w(env, cmd, opts = {}, &block)
194
+ run_before_callbacks(cmd)
195
+ cmd_s = cmd.join(' ')
196
+
197
+ Open3.pipeline_w([env, cmd_s], opts) do |stdin, wait_threads|
198
+ yield(stdin, wait_threads).tap do
199
+ stdin.close
200
+ self.last_status = wait_threads.last.value
201
+ run_after_callbacks(cmd)
202
+ end
203
+ end
204
+ end
205
+
206
+ def run_before_callbacks(cmd)
207
+ @before_execute.each { |cb| cb.call(cmd) }
208
+ end
209
+
210
+ def run_after_callbacks(cmd)
211
+ @after_execute.each { |cb| cb.call(cmd, last_status) }
212
+ end
213
+
214
+ def last_status=(status)
215
+ Thread.current[status_key] = status
216
+ end
217
+ end
@@ -0,0 +1,3 @@
1
+ class KubernetesCLI
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kubernetes-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kubectl-rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
27
+ description: Ruby wrapper around the Kubernetes CLI.
28
+ email:
29
+ - camertron@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - Gemfile
36
+ - LICENSE
37
+ - Rakefile
38
+ - kubernetes-cli.gemspec
39
+ - lib/kubernetes-cli.rb
40
+ - lib/kubernetes-cli/version.rb
41
+ homepage: http://github.com/getkuby/kubernetes-cli
42
+ licenses:
43
+ - MIT
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubygems_version: 3.0.6
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: Ruby wrapper around the Kubernetes CLI.
64
+ test_files: []