k8s-ruby 0.15.1 → 0.17.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad7875d61420834647e84ae563ade83f3a0b5c81d8c105c5cf94a15452d3127b
4
- data.tar.gz: 729cedef48bbb59522d178a9f6f189f9c4a7b20f5a4bfe9292e733f14a31ab7e
3
+ metadata.gz: 183bba7baad8957f70d6253e8e5bd85860da8b778555bc295a8343e9f585daa4
4
+ data.tar.gz: f20f5d31b7c89ad06b36d9c02da854f4821c6579f2fb21d6949d11ab98b3d06b
5
5
  SHA512:
6
- metadata.gz: d900ec75b985d43ebd8b48aff686564a21769b97d0ea63de7af4e9ec5696983bfce4770bc545b18e9c6dfc8e992e143871e54838f82211fc53f4df04d50118ce
7
- data.tar.gz: de2f4f643bc5a8e631678fcbdcb02d2360c10c429c21e90e726ce76c92e5d3ce8d62c5bf92b9b6acd9e66336e33c0a8f2750d811fceae5fe5f74c19d5ea533d5
6
+ metadata.gz: a011892aa7043af43eafabb831b43b446786011187cbbbea10f122ed3b20b7d441d4e32f12d442c414df4488c497f708bf5b428c3d9cefff980c634fee58260d
7
+ data.tar.gz: 13b2d5f77b68c1702a27e8c22fff41e39d27854892b18455146b91c0d296b358fa5569573f8ca15e7fd02cc39e257d4d22320fa224a72255adf1b706d09481d0
@@ -10,34 +10,48 @@ jobs:
10
10
  build-2-6:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v3
14
- - run: docker-compose build rspec-2.6
15
- - run: docker-compose run rspec-2.6
13
+ - uses: actions/checkout@v4
14
+ - run: docker compose build rspec-2.6
15
+ - run: docker compose run rspec-2.6
16
16
 
17
17
  build-2-7:
18
18
  runs-on: ubuntu-latest
19
19
  steps:
20
- - uses: actions/checkout@v3
21
- - run: docker-compose build rspec-2.7
22
- - run: docker-compose run rspec-2.7
20
+ - uses: actions/checkout@v4
21
+ - run: docker compose build rspec-2.7
22
+ - run: docker compose run rspec-2.7
23
23
 
24
24
  build-3-0:
25
25
  runs-on: ubuntu-latest
26
26
  steps:
27
- - uses: actions/checkout@v3
28
- - run: docker-compose build rspec-3.0
29
- - run: docker-compose run rspec-3.0
27
+ - uses: actions/checkout@v4
28
+ - run: docker compose build rspec-3.0
29
+ - run: docker compose run rspec-3.0
30
30
 
31
31
  build-3-1:
32
32
  runs-on: ubuntu-latest
33
33
  steps:
34
- - uses: actions/checkout@v3
35
- - run: docker-compose build rspec-3.1
36
- - run: docker-compose run rspec-3.1
34
+ - uses: actions/checkout@v4
35
+ - run: docker compose build rspec-3.1
36
+ - run: docker compose run rspec-3.1
37
37
 
38
38
  build-3-2:
39
39
  runs-on: ubuntu-latest
40
40
  steps:
41
- - uses: actions/checkout@v3
42
- - run: docker-compose build rspec-3.2
43
- - run: docker-compose run rspec-3.2
41
+ - uses: actions/checkout@v4
42
+ - run: docker compose build rspec-3.2
43
+ - run: docker compose run rspec-3.2
44
+
45
+ build-3-3:
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - uses: actions/checkout@v4
49
+ - run: docker compose build rspec-3.3
50
+ - run: docker compose run rspec-3.3
51
+
52
+ build-3-4:
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ - run: docker compose build rspec-3.4
57
+ - run: docker compose run rspec-3.4
data/.gitignore CHANGED
@@ -10,6 +10,7 @@
10
10
  .ruby-version
11
11
  .tool-versions
12
12
  /.byebug_history
13
+ Gemfile.lock
13
14
 
14
15
  # rspec failure tracking
15
16
  .rspec_status
data/Gemfile CHANGED
@@ -2,7 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
- # forked and upgraded to be compatible with ruby 3.1
6
- gem 'yaml-safe_load_stream3', '~> 0.1.2'
7
5
  # Specify your gem's dependencies in k8s-ruby.gemspec
8
6
  gemspec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.15.1
1
+ 0.17.0
data/docker-compose.yaml CHANGED
@@ -35,3 +35,20 @@ services:
35
35
  volumes:
36
36
  - .:/app
37
37
  entrypoint: bundle exec rspec
38
+ rspec-3.3:
39
+ build:
40
+ context: .
41
+ args:
42
+ BASE_IMAGE: ruby:3.3
43
+ volumes:
44
+ - .:/app
45
+ entrypoint: bundle exec rspec
46
+ rspec-3.4:
47
+ build:
48
+ context: .
49
+ args:
50
+ BASE_IMAGE: ruby:3.4
51
+ volumes:
52
+ - .:/app
53
+ entrypoint: bundle exec rspec
54
+
data/k8s-ruby.gemspec CHANGED
@@ -21,22 +21,26 @@ Gem::Specification.new do |spec|
21
21
  spec.bindir = "bin"
22
22
  spec.executables = []
23
23
  spec.require_paths = ["lib"]
24
- spec.required_ruby_version = spec.required_ruby_version = [">= 2.4", "<= 3.2.2"]
24
+ spec.required_ruby_version = ">= 2.4"
25
25
 
26
26
  spec.add_runtime_dependency "excon", "~> 0.71"
27
27
  spec.add_runtime_dependency "dry-struct"
28
28
  spec.add_runtime_dependency "dry-types"
29
29
  spec.add_runtime_dependency "dry-configurable"
30
- spec.add_runtime_dependency "recursive-open-struct", "~> 1.1.3"
31
- spec.add_runtime_dependency "hashdiff", "~> 1.0.0"
32
- spec.add_runtime_dependency "jsonpath", "~> 0.9.5"
33
- spec.add_runtime_dependency "yajl-ruby", "~> 1.4.0"
30
+ spec.add_runtime_dependency "recursive-open-struct", "~> 1.1", ">= 1.1.3"
31
+ spec.add_runtime_dependency "hashdiff", "~> 1.0"
32
+ spec.add_runtime_dependency "jsonpath", "~> 1.1"
33
+ spec.add_runtime_dependency "yajl-ruby", "~> 1.4"
34
34
  spec.add_runtime_dependency "yaml-safe_load_stream3"
35
+ spec.add_runtime_dependency "base64"
36
+ spec.add_runtime_dependency "eventmachine", "~> 1.2"
37
+ spec.add_runtime_dependency "faye-websocket", "~> 0.11"
38
+ spec.add_runtime_dependency "ruby-termios", "~> 1.1"
35
39
 
36
40
  spec.add_development_dependency "bundler", ">= 1.17", "< 3.0"
37
41
  spec.add_development_dependency "rake", ">= 12.3.3"
38
42
  spec.add_development_dependency "rspec", "~> 3.7"
39
- spec.add_development_dependency "webmock", "~> 3.6.2"
43
+ spec.add_development_dependency "webmock", "~> 3.6"
40
44
  spec.add_development_dependency "rubocop", "~> 0.82"
41
45
  spec.add_development_dependency "byebug", "~> 11.1"
42
46
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module K8s
4
+ class ResourceClient
5
+ module Exec
6
+ def self.included(base)
7
+ base.include(InstanceMethods)
8
+ base.include(Logging)
9
+ end
10
+
11
+ module InstanceMethods
12
+ require "eventmachine"
13
+ require "faye/websocket"
14
+ require "termios"
15
+ require "tempfile"
16
+
17
+ # Executes arbitrary commands in a container.
18
+ #
19
+ # @param name [String] name of the pod
20
+ # @param namespace [String]
21
+ # @param container [String] name of the container to execute the command in
22
+ # @param command [Array<String>|String] command to execute. It accepts a single string or an array of strings if multiple arguments are needed.
23
+ # @param stdin [Boolean] whether to stream stdin to the container
24
+ # @param stdout [Boolean] whether to stream stdout from the container
25
+ # @param tty [Boolean] whether to allocate a tty for the container
26
+ # @yield [String] Optional block to yield the output of the command
27
+ # @return [String, nil] output of the command. It returns nil if a block is given or tty is true.
28
+ #
29
+ # @example
30
+ # client.api('v1').resource('pods', namespace: 'default').exec(
31
+ # name: 'test-pod',
32
+ # container: 'shell',
33
+ # command: '/bin/sh'
34
+ # )
35
+ # @example Open a shell:
36
+ # exec(name: 'my-pod', container: 'my-container', command: '/bin/sh')
37
+ # @example Execute single command:
38
+ # exec(name: 'my-pod', container: 'my-container', command: 'date')
39
+ # @example Pass multiple arguments:
40
+ # exec(name: 'my-pod', container: 'my-container', command: ['ls', '-la'])
41
+ # @example Yield the output of the command:
42
+ # exec(
43
+ # name: "test-pod",
44
+ # container: "shell",
45
+ # command: [ "watch", "date" ],
46
+ # ) do |out|
47
+ # puts "local time #{Time.now}"
48
+ # puts "server time #{out}"
49
+ # end
50
+ def exec(name:, namespace: @namespace, command:, container:, stdin: true, stdout: true, tty: true)
51
+ query = {
52
+ command: [command].flatten,
53
+ container: container,
54
+ stdin: !!stdin,
55
+ stdout: !!stdout,
56
+ tty: !!tty
57
+ }
58
+
59
+ exec_path = path(name, namespace: namespace, subresource: "exec")
60
+ output = StringIO.new
61
+
62
+ EM.run do
63
+ ws = @transport.build_ws_conn(exec_path, query)
64
+
65
+ ws.on :message do |event|
66
+ out = event.data.pack("C*")
67
+
68
+ if block_given?
69
+ yield(out)
70
+ elsif tty
71
+ print out
72
+ else
73
+ output.write(out)
74
+ end
75
+ end
76
+
77
+ ws.on :error do |event|
78
+ logger.error(event.message)
79
+ end
80
+
81
+ term_attributes_original = Termios.tcgetattr($stdin)
82
+ if tty
83
+ term_attributes = term_attributes_original.dup
84
+ term_attributes.lflag &= ~Termios::ECHO
85
+ term_attributes.lflag &= ~Termios::ICANON
86
+ Termios.tcsetattr($stdin, Termios::TCSANOW, term_attributes)
87
+
88
+ EM.open_keyboard(Module.new do
89
+ define_method(:receive_data) do |input|
90
+ input = [0] + input.unpack("C*")
91
+ ws.send(input)
92
+ end
93
+ end)
94
+ end
95
+
96
+ ws.on :close do
97
+ Termios.tcsetattr($stdin, Termios::TCSANOW, term_attributes_original)
98
+ EM.stop
99
+ end
100
+ end
101
+
102
+ return if tty
103
+
104
+ output.rewind
105
+ output.read
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "resource_client/exec"
4
+
3
5
  module K8s
4
6
  # Per-APIResource type client.
5
7
  #
6
8
  # Used to get/list/update/patch/delete specific types of resources, optionally in some specific namespace.
9
+ #
7
10
  class ResourceClient
8
11
  # Common helpers used in both class/instance methods
9
12
  module Utils
@@ -36,6 +39,9 @@ module K8s
36
39
  include Utils
37
40
  extend Utils
38
41
 
42
+ # @!parse include K8s::ResourceClient::Exec
43
+ include Exec
44
+
39
45
  # Pipeline list requests for multiple resource types.
40
46
  #
41
47
  # Returns flattened array with mixed resource kinds.
@@ -3,6 +3,6 @@
3
3
  module K8s
4
4
  class Ruby
5
5
  # Updated on releases using semver.
6
- VERSION = "0.15.1"
6
+ VERSION = "0.17.0"
7
7
  end
8
8
  end
data/lib/k8s/transport.rb CHANGED
@@ -388,5 +388,50 @@ module K8s
388
388
  **options
389
389
  )
390
390
  end
391
+
392
+ # Returns a websocket connection using part of the current transport configuration.
393
+ # Will use same host and port returned by #server.
394
+ # @param resource_path [String]
395
+ # @param query [Hash]
396
+ # @return [Faye::WebSocket::Client]
397
+ def build_ws_conn(resource_path, query = {})
398
+ private_key_file = nil
399
+ cert_chain_file = nil
400
+
401
+ on_open_callbacks = []
402
+
403
+ if options[:client_cert] && options[:client_key]
404
+ private_key_file = options[:client_key]
405
+ cert_chain_file = options[:client_cert]
406
+ elsif options[:client_cert_data] && options[:client_key_data]
407
+ temp_file_path_from_data = lambda do |data|
408
+ temp_file = Tempfile.new
409
+ temp_file.write(data)
410
+ temp_file.close
411
+ on_open_callbacks << -> { temp_file.unlink }
412
+ temp_file.path
413
+ end
414
+ private_key_file = temp_file_path_from_data.call(options[:client_key_data])
415
+ cert_chain_file = temp_file_path_from_data.call(options[:client_cert_data])
416
+ end
417
+
418
+ url = server.gsub("http", "ws") +
419
+ resource_path +
420
+ Excon::Utils.query_string(query: query)
421
+
422
+ ws = Faye::WebSocket::Client.new(
423
+ url,
424
+ [],
425
+ headers: request_options[:headers],
426
+ tls: {
427
+ verify_peer: !!options[:ssl_verify_peer],
428
+ private_key_file: private_key_file,
429
+ cert_chain_file: cert_chain_file
430
+ }
431
+ )
432
+
433
+ ws.on(:open) { on_open_callbacks.each(&:call) }
434
+ ws
435
+ end
391
436
  end
392
437
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k8s-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rdx.net
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-08-30 00:00:00.000000000 Z
12
+ date: 2025-03-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: excon
@@ -72,6 +72,9 @@ dependencies:
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.1'
77
+ - - ">="
75
78
  - !ruby/object:Gem::Version
76
79
  version: 1.1.3
77
80
  type: :runtime
@@ -79,6 +82,9 @@ dependencies:
79
82
  version_requirements: !ruby/object:Gem::Requirement
80
83
  requirements:
81
84
  - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '1.1'
87
+ - - ">="
82
88
  - !ruby/object:Gem::Version
83
89
  version: 1.1.3
84
90
  - !ruby/object:Gem::Dependency
@@ -87,42 +93,42 @@ dependencies:
87
93
  requirements:
88
94
  - - "~>"
89
95
  - !ruby/object:Gem::Version
90
- version: 1.0.0
96
+ version: '1.0'
91
97
  type: :runtime
92
98
  prerelease: false
93
99
  version_requirements: !ruby/object:Gem::Requirement
94
100
  requirements:
95
101
  - - "~>"
96
102
  - !ruby/object:Gem::Version
97
- version: 1.0.0
103
+ version: '1.0'
98
104
  - !ruby/object:Gem::Dependency
99
105
  name: jsonpath
100
106
  requirement: !ruby/object:Gem::Requirement
101
107
  requirements:
102
108
  - - "~>"
103
109
  - !ruby/object:Gem::Version
104
- version: 0.9.5
110
+ version: '1.1'
105
111
  type: :runtime
106
112
  prerelease: false
107
113
  version_requirements: !ruby/object:Gem::Requirement
108
114
  requirements:
109
115
  - - "~>"
110
116
  - !ruby/object:Gem::Version
111
- version: 0.9.5
117
+ version: '1.1'
112
118
  - !ruby/object:Gem::Dependency
113
119
  name: yajl-ruby
114
120
  requirement: !ruby/object:Gem::Requirement
115
121
  requirements:
116
122
  - - "~>"
117
123
  - !ruby/object:Gem::Version
118
- version: 1.4.0
124
+ version: '1.4'
119
125
  type: :runtime
120
126
  prerelease: false
121
127
  version_requirements: !ruby/object:Gem::Requirement
122
128
  requirements:
123
129
  - - "~>"
124
130
  - !ruby/object:Gem::Version
125
- version: 1.4.0
131
+ version: '1.4'
126
132
  - !ruby/object:Gem::Dependency
127
133
  name: yaml-safe_load_stream3
128
134
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +143,62 @@ dependencies:
137
143
  - - ">="
138
144
  - !ruby/object:Gem::Version
139
145
  version: '0'
146
+ - !ruby/object:Gem::Dependency
147
+ name: base64
148
+ requirement: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ type: :runtime
154
+ prerelease: false
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ - !ruby/object:Gem::Dependency
161
+ name: eventmachine
162
+ requirement: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.2'
167
+ type: :runtime
168
+ prerelease: false
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.2'
174
+ - !ruby/object:Gem::Dependency
175
+ name: faye-websocket
176
+ requirement: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.11'
181
+ type: :runtime
182
+ prerelease: false
183
+ version_requirements: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.11'
188
+ - !ruby/object:Gem::Dependency
189
+ name: ruby-termios
190
+ requirement: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.1'
195
+ type: :runtime
196
+ prerelease: false
197
+ version_requirements: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '1.1'
140
202
  - !ruby/object:Gem::Dependency
141
203
  name: bundler
142
204
  requirement: !ruby/object:Gem::Requirement
@@ -191,14 +253,14 @@ dependencies:
191
253
  requirements:
192
254
  - - "~>"
193
255
  - !ruby/object:Gem::Version
194
- version: 3.6.2
256
+ version: '3.6'
195
257
  type: :development
196
258
  prerelease: false
197
259
  version_requirements: !ruby/object:Gem::Requirement
198
260
  requirements:
199
261
  - - "~>"
200
262
  - !ruby/object:Gem::Version
201
- version: 3.6.2
263
+ version: '3.6'
202
264
  - !ruby/object:Gem::Dependency
203
265
  name: rubocop
204
266
  requirement: !ruby/object:Gem::Requirement
@@ -267,6 +329,7 @@ files:
267
329
  - lib/k8s/logging.rb
268
330
  - lib/k8s/resource.rb
269
331
  - lib/k8s/resource_client.rb
332
+ - lib/k8s/resource_client/exec.rb
270
333
  - lib/k8s/ruby/version.rb
271
334
  - lib/k8s/stack.rb
272
335
  - lib/k8s/transport.rb
@@ -284,16 +347,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
347
  - - ">="
285
348
  - !ruby/object:Gem::Version
286
349
  version: '2.4'
287
- - - "<="
288
- - !ruby/object:Gem::Version
289
- version: 3.2.2
290
350
  required_rubygems_version: !ruby/object:Gem::Requirement
291
351
  requirements:
292
352
  - - ">="
293
353
  - !ruby/object:Gem::Version
294
354
  version: '0'
295
355
  requirements: []
296
- rubygems_version: 3.1.4
356
+ rubygems_version: 3.2.3
297
357
  signing_key:
298
358
  specification_version: 4
299
359
  summary: Kubernetes client library for Ruby