k8s-ruby 0.16.0 → 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 +4 -4
- data/.github/workflows/tests.yml +25 -18
- data/.gitignore +1 -0
- data/Gemfile +0 -2
- data/VERSION +1 -1
- data/docker-compose.yaml +9 -0
- data/k8s-ruby.gemspec +9 -5
- data/lib/k8s/resource_client/exec.rb +110 -0
- data/lib/k8s/resource_client.rb +6 -0
- data/lib/k8s/ruby/version.rb +1 -1
- data/lib/k8s/transport.rb +45 -0
- metadata +72 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 183bba7baad8957f70d6253e8e5bd85860da8b778555bc295a8343e9f585daa4
|
4
|
+
data.tar.gz: f20f5d31b7c89ad06b36d9c02da854f4821c6579f2fb21d6949d11ab98b3d06b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a011892aa7043af43eafabb831b43b446786011187cbbbea10f122ed3b20b7d441d4e32f12d442c414df4488c497f708bf5b428c3d9cefff980c634fee58260d
|
7
|
+
data.tar.gz: 13b2d5f77b68c1702a27e8c22fff41e39d27854892b18455146b91c0d296b358fa5569573f8ca15e7fd02cc39e257d4d22320fa224a72255adf1b706d09481d0
|
data/.github/workflows/tests.yml
CHANGED
@@ -10,41 +10,48 @@ jobs:
|
|
10
10
|
build-2-6:
|
11
11
|
runs-on: ubuntu-latest
|
12
12
|
steps:
|
13
|
-
- uses: actions/checkout@
|
14
|
-
- run: docker
|
15
|
-
- run: docker
|
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@
|
21
|
-
- run: docker
|
22
|
-
- run: docker
|
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@
|
28
|
-
- run: docker
|
29
|
-
- run: docker
|
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@
|
35
|
-
- run: docker
|
36
|
-
- run: docker
|
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@
|
42
|
-
- run: docker
|
43
|
-
- run: docker
|
41
|
+
- uses: actions/checkout@v4
|
42
|
+
- run: docker compose build rspec-3.2
|
43
|
+
- run: docker compose run rspec-3.2
|
44
44
|
|
45
45
|
build-3-3:
|
46
46
|
runs-on: ubuntu-latest
|
47
47
|
steps:
|
48
|
-
- uses: actions/checkout@
|
49
|
-
- run: docker
|
50
|
-
- run: docker
|
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
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.17.0
|
data/docker-compose.yaml
CHANGED
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 =
|
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
|
30
|
+
spec.add_runtime_dependency "recursive-open-struct", "~> 1.1", ">= 1.1.3"
|
31
|
+
spec.add_runtime_dependency "hashdiff", "~> 1.0"
|
32
32
|
spec.add_runtime_dependency "jsonpath", "~> 1.1"
|
33
|
-
spec.add_runtime_dependency "yajl-ruby", "~> 1.4
|
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
|
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
|
data/lib/k8s/resource_client.rb
CHANGED
@@ -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.
|
data/lib/k8s/ruby/version.rb
CHANGED
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.
|
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:
|
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,14 +93,14 @@ dependencies:
|
|
87
93
|
requirements:
|
88
94
|
- - "~>"
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.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
|
103
|
+
version: '1.0'
|
98
104
|
- !ruby/object:Gem::Dependency
|
99
105
|
name: jsonpath
|
100
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,14 +121,14 @@ dependencies:
|
|
115
121
|
requirements:
|
116
122
|
- - "~>"
|
117
123
|
- !ruby/object:Gem::Version
|
118
|
-
version: 1.4
|
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
|
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
|
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
|
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.4'
|
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.
|
356
|
+
rubygems_version: 3.2.3
|
297
357
|
signing_key:
|
298
358
|
specification_version: 4
|
299
359
|
summary: Kubernetes client library for Ruby
|