kubeclient 4.8.0 → 4.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of kubeclient might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/kubeclient/config.rb +11 -3
- data/lib/kubeclient/exec_credentials.rb +33 -4
- data/lib/kubeclient/version.rb +1 -1
- data/test/test_exec_credentials.rb +119 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c8f79b61300006829c55c6b13715e6073a1cf9517ad8334959ff64706bee4ca
|
4
|
+
data.tar.gz: 04ae220b4f78422992e34538e5b47a0dbf0a832aa2eb9f1ac86d3f1c221cd088
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7c9ab202ff3e30f5884fd2f80987fe87a3a65a86fa1a3ecdba16383cbb958fdb98f02dd48a00a5ac50fac828b335a33b33f634f7e2cbe7913883e5aa9a81fa4
|
7
|
+
data.tar.gz: 52078faf6ec204c2b08658d83604fb84c7e68ad409d754ada7ae9d0d989fbce01ae53b2c33993dc71a6bed5851904fe22b6cd3688f67fa1c4bf9cd7704c43f71
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,10 @@ Notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
5
5
|
Kubeclient release versioning follows [SemVer](https://semver.org/).
|
6
6
|
|
7
|
+
## 4.9.0 - 2020-08-03
|
8
|
+
### Added
|
9
|
+
- Support for `user: exec` credential plugins using TLS client auth (#453)
|
10
|
+
|
7
11
|
## 4.8.0 — 2020-07-03
|
8
12
|
|
9
13
|
### Added
|
data/lib/kubeclient/config.rb
CHANGED
@@ -41,6 +41,11 @@ module Kubeclient
|
|
41
41
|
def context(context_name = nil)
|
42
42
|
cluster, user, namespace = fetch_context(context_name || @kcfg['current-context'])
|
43
43
|
|
44
|
+
if user.key?('exec')
|
45
|
+
exec_opts = expand_command_option(user['exec'], 'command')
|
46
|
+
user['exec_result'] = ExecCredentials.run(exec_opts)
|
47
|
+
end
|
48
|
+
|
44
49
|
ca_cert_data = fetch_cluster_ca_data(cluster)
|
45
50
|
client_cert_data = fetch_user_cert_data(user)
|
46
51
|
client_key_data = fetch_user_key_data(user)
|
@@ -134,6 +139,8 @@ module Kubeclient
|
|
134
139
|
File.read(ext_file_path(user['client-certificate']))
|
135
140
|
elsif user.key?('client-certificate-data')
|
136
141
|
Base64.decode64(user['client-certificate-data'])
|
142
|
+
elsif user.key?('exec_result') && user['exec_result'].key?('clientCertificateData')
|
143
|
+
user['exec_result']['clientCertificateData']
|
137
144
|
end
|
138
145
|
end
|
139
146
|
|
@@ -142,6 +149,8 @@ module Kubeclient
|
|
142
149
|
File.read(ext_file_path(user['client-key']))
|
143
150
|
elsif user.key?('client-key-data')
|
144
151
|
Base64.decode64(user['client-key-data'])
|
152
|
+
elsif user.key?('exec_result') && user['exec_result'].key?('clientKeyData')
|
153
|
+
user['exec_result']['clientKeyData']
|
145
154
|
end
|
146
155
|
end
|
147
156
|
|
@@ -149,9 +158,8 @@ module Kubeclient
|
|
149
158
|
options = {}
|
150
159
|
if user.key?('token')
|
151
160
|
options[:bearer_token] = user['token']
|
152
|
-
elsif user.key?('
|
153
|
-
|
154
|
-
options[:bearer_token] = Kubeclient::ExecCredentials.token(exec_opts)
|
161
|
+
elsif user.key?('exec_result') && user['exec_result'].key?('token')
|
162
|
+
options[:bearer_token] = user['exec_result']['token']
|
155
163
|
elsif user.key?('auth-provider')
|
156
164
|
options[:bearer_token] = fetch_token_from_provider(user['auth-provider'])
|
157
165
|
else
|
@@ -6,7 +6,7 @@ module Kubeclient
|
|
6
6
|
# Inspired by https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/exec/exec.go
|
7
7
|
class ExecCredentials
|
8
8
|
class << self
|
9
|
-
def
|
9
|
+
def run(opts)
|
10
10
|
require 'open3'
|
11
11
|
require 'json'
|
12
12
|
|
@@ -25,7 +25,7 @@ module Kubeclient
|
|
25
25
|
|
26
26
|
creds = JSON.parse(out)
|
27
27
|
validate_credentials(opts, creds)
|
28
|
-
creds['status']
|
28
|
+
creds['status']
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
@@ -34,6 +34,36 @@ module Kubeclient
|
|
34
34
|
raise KeyError, 'exec command is required' unless opts['command']
|
35
35
|
end
|
36
36
|
|
37
|
+
def validate_client_credentials_status(status)
|
38
|
+
has_client_cert_data = status.key?('clientCertificateData')
|
39
|
+
has_client_key_data = status.key?('clientKeyData')
|
40
|
+
|
41
|
+
if has_client_cert_data && !has_client_key_data
|
42
|
+
raise 'exec plugin didn\'t return client key data'
|
43
|
+
end
|
44
|
+
|
45
|
+
if !has_client_cert_data && has_client_key_data
|
46
|
+
raise 'exec plugin didn\'t return client certificate data'
|
47
|
+
end
|
48
|
+
|
49
|
+
has_client_cert_data && has_client_key_data
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_credentials_status(status)
|
53
|
+
raise 'exec plugin didn\'t return a status field' if status.nil?
|
54
|
+
|
55
|
+
has_client_credentials = validate_client_credentials_status(status)
|
56
|
+
has_token = status.key?('token')
|
57
|
+
|
58
|
+
if has_client_credentials && has_token
|
59
|
+
raise 'exec plugin returned both token and client data'
|
60
|
+
end
|
61
|
+
|
62
|
+
return if has_client_credentials || has_token
|
63
|
+
|
64
|
+
raise 'exec plugin didn\'t return a token or client data' unless has_token
|
65
|
+
end
|
66
|
+
|
37
67
|
def validate_credentials(opts, creds)
|
38
68
|
# out should have ExecCredential structure
|
39
69
|
raise 'invalid credentials' if creds.nil?
|
@@ -45,8 +75,7 @@ module Kubeclient
|
|
45
75
|
"plugin returned version #{creds['apiVersion']}"
|
46
76
|
end
|
47
77
|
|
48
|
-
|
49
|
-
raise 'exec plugin didn\'t return a token' if creds['status']['token'].nil?
|
78
|
+
validate_credentials_status(creds['status'])
|
50
79
|
end
|
51
80
|
|
52
81
|
# Transform name/value pairs to hash
|
data/lib/kubeclient/version.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
require 'open3'
|
3
3
|
|
4
|
-
# Unit tests for the ExecCredentials
|
4
|
+
# Unit tests for the ExecCredentials provider
|
5
5
|
class ExecCredentialsTest < MiniTest::Test
|
6
6
|
def test_exec_opts_missing
|
7
7
|
expected_msg =
|
8
8
|
'exec options are required'
|
9
9
|
exception = assert_raises(ArgumentError) do
|
10
|
-
Kubeclient::ExecCredentials.
|
10
|
+
Kubeclient::ExecCredentials.run(nil)
|
11
11
|
end
|
12
12
|
assert_equal(expected_msg, exception.message)
|
13
13
|
end
|
@@ -16,7 +16,7 @@ class ExecCredentialsTest < MiniTest::Test
|
|
16
16
|
expected_msg =
|
17
17
|
'exec command is required'
|
18
18
|
exception = assert_raises(KeyError) do
|
19
|
-
Kubeclient::ExecCredentials.
|
19
|
+
Kubeclient::ExecCredentials.run({})
|
20
20
|
end
|
21
21
|
assert_equal(expected_msg, exception.message)
|
22
22
|
end
|
@@ -33,34 +33,134 @@ class ExecCredentialsTest < MiniTest::Test
|
|
33
33
|
|
34
34
|
Open3.stub(:capture3, [nil, err, st]) do
|
35
35
|
exception = assert_raises(RuntimeError) do
|
36
|
-
Kubeclient::ExecCredentials.
|
36
|
+
Kubeclient::ExecCredentials.run(opts)
|
37
37
|
end
|
38
38
|
assert_equal(expected_msg, exception.message)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def test_run_with_token_credentials
|
43
43
|
opts = { 'command' => 'dummy' }
|
44
44
|
|
45
|
+
credentials = {
|
46
|
+
'token' => '0123456789ABCDEF0123456789ABCDEF'
|
47
|
+
}
|
48
|
+
|
49
|
+
creds = JSON.dump(
|
50
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
51
|
+
'status' => credentials
|
52
|
+
)
|
53
|
+
|
54
|
+
st = Minitest::Mock.new
|
55
|
+
st.expect(:success?, true)
|
56
|
+
|
57
|
+
Open3.stub(:capture3, [creds, nil, st]) do
|
58
|
+
assert_equal(credentials, Kubeclient::ExecCredentials.run(opts))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_run_with_client_credentials
|
63
|
+
opts = { 'command' => 'dummy' }
|
64
|
+
|
65
|
+
credentials = {
|
66
|
+
'clientCertificateData' => '0123456789ABCDEF0123456789ABCDEF',
|
67
|
+
'clientKeyData' => '0123456789ABCDEF0123456789ABCDEF'
|
68
|
+
}
|
69
|
+
|
70
|
+
creds = JSON.dump(
|
71
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
72
|
+
'status' => credentials
|
73
|
+
)
|
74
|
+
|
75
|
+
st = Minitest::Mock.new
|
76
|
+
st.expect(:success?, true)
|
77
|
+
|
78
|
+
Open3.stub(:capture3, [creds, nil, st]) do
|
79
|
+
assert_equal(credentials, Kubeclient::ExecCredentials.run(opts))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_run_with_missing_client_certificate_data
|
84
|
+
opts = { 'command' => 'dummy' }
|
85
|
+
|
86
|
+
credentials = {
|
87
|
+
'clientKeyData' => '0123456789ABCDEF0123456789ABCDEF'
|
88
|
+
}
|
89
|
+
|
90
|
+
creds = JSON.dump(
|
91
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
92
|
+
'status' => credentials
|
93
|
+
)
|
94
|
+
|
95
|
+
st = Minitest::Mock.new
|
96
|
+
st.expect(:success?, true)
|
97
|
+
|
98
|
+
expected_msg = 'exec plugin didn\'t return client certificate data'
|
99
|
+
|
100
|
+
Open3.stub(:capture3, [creds, nil, st]) do
|
101
|
+
exception = assert_raises(RuntimeError) do
|
102
|
+
Kubeclient::ExecCredentials.run(opts)
|
103
|
+
end
|
104
|
+
assert_equal(expected_msg, exception.message)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_run_with_missing_client_key_data
|
109
|
+
opts = { 'command' => 'dummy' }
|
110
|
+
|
111
|
+
credentials = {
|
112
|
+
'clientCertificateData' => '0123456789ABCDEF0123456789ABCDEF'
|
113
|
+
}
|
114
|
+
|
45
115
|
creds = JSON.dump(
|
46
|
-
'apiVersion'
|
47
|
-
'status'
|
48
|
-
'token': '0123456789ABCDEF0123456789ABCDEF'
|
49
|
-
}
|
116
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
117
|
+
'status' => credentials
|
50
118
|
)
|
51
119
|
|
52
120
|
st = Minitest::Mock.new
|
53
121
|
st.expect(:success?, true)
|
54
122
|
|
123
|
+
expected_msg = 'exec plugin didn\'t return client key data'
|
124
|
+
|
55
125
|
Open3.stub(:capture3, [creds, nil, st]) do
|
56
|
-
|
126
|
+
exception = assert_raises(RuntimeError) do
|
127
|
+
Kubeclient::ExecCredentials.run(opts)
|
128
|
+
end
|
129
|
+
assert_equal(expected_msg, exception.message)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_run_with_client_data_and_token
|
134
|
+
opts = { 'command' => 'dummy' }
|
135
|
+
|
136
|
+
credentials = {
|
137
|
+
'clientCertificateData' => '0123456789ABCDEF0123456789ABCDEF',
|
138
|
+
'clientKeyData' => '0123456789ABCDEF0123456789ABCDEF',
|
139
|
+
'token' => '0123456789ABCDEF0123456789ABCDEF'
|
140
|
+
}
|
141
|
+
|
142
|
+
creds = JSON.dump(
|
143
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
144
|
+
'status' => credentials
|
145
|
+
)
|
146
|
+
|
147
|
+
st = Minitest::Mock.new
|
148
|
+
st.expect(:success?, true)
|
149
|
+
|
150
|
+
expected_msg = 'exec plugin returned both token and client data'
|
151
|
+
|
152
|
+
Open3.stub(:capture3, [creds, nil, st]) do
|
153
|
+
exception = assert_raises(RuntimeError) do
|
154
|
+
Kubeclient::ExecCredentials.run(opts)
|
155
|
+
end
|
156
|
+
assert_equal(expected_msg, exception.message)
|
57
157
|
end
|
58
158
|
end
|
59
159
|
|
60
160
|
def test_status_missing
|
61
161
|
opts = { 'command' => 'dummy' }
|
62
162
|
|
63
|
-
creds = JSON.dump('apiVersion'
|
163
|
+
creds = JSON.dump('apiVersion' => 'client.authentication.k8s.io/v1alpha1')
|
64
164
|
|
65
165
|
st = Minitest::Mock.new
|
66
166
|
st.expect(:success?, true)
|
@@ -69,28 +169,28 @@ class ExecCredentialsTest < MiniTest::Test
|
|
69
169
|
|
70
170
|
Open3.stub(:capture3, [creds, nil, st]) do
|
71
171
|
exception = assert_raises(RuntimeError) do
|
72
|
-
Kubeclient::ExecCredentials.
|
172
|
+
Kubeclient::ExecCredentials.run(opts)
|
73
173
|
end
|
74
174
|
assert_equal(expected_msg, exception.message)
|
75
175
|
end
|
76
176
|
end
|
77
177
|
|
78
|
-
def
|
178
|
+
def test_credentials_missing
|
79
179
|
opts = { 'command' => 'dummy' }
|
80
180
|
|
81
181
|
creds = JSON.dump(
|
82
|
-
'apiVersion'
|
83
|
-
'status'
|
182
|
+
'apiVersion' => 'client.authentication.k8s.io/v1alpha1',
|
183
|
+
'status' => {}
|
84
184
|
)
|
85
185
|
|
86
186
|
st = Minitest::Mock.new
|
87
187
|
st.expect(:success?, true)
|
88
188
|
|
89
|
-
expected_msg = 'exec plugin didn\'t return a token'
|
189
|
+
expected_msg = 'exec plugin didn\'t return a token or client data'
|
90
190
|
|
91
191
|
Open3.stub(:capture3, [creds, nil, st]) do
|
92
192
|
exception = assert_raises(RuntimeError) do
|
93
|
-
Kubeclient::ExecCredentials.
|
193
|
+
Kubeclient::ExecCredentials.run(opts)
|
94
194
|
end
|
95
195
|
assert_equal(expected_msg, exception.message)
|
96
196
|
end
|
@@ -106,7 +206,7 @@ class ExecCredentialsTest < MiniTest::Test
|
|
106
206
|
}
|
107
207
|
|
108
208
|
creds = JSON.dump(
|
109
|
-
'apiVersion'
|
209
|
+
'apiVersion' => api_version
|
110
210
|
)
|
111
211
|
|
112
212
|
st = Minitest::Mock.new
|
@@ -117,7 +217,7 @@ class ExecCredentialsTest < MiniTest::Test
|
|
117
217
|
|
118
218
|
Open3.stub(:capture3, [creds, nil, st]) do
|
119
219
|
exception = assert_raises(RuntimeError) do
|
120
|
-
Kubeclient::ExecCredentials.
|
220
|
+
Kubeclient::ExecCredentials.run(opts)
|
121
221
|
end
|
122
222
|
assert_equal(expected_msg, exception.message)
|
123
223
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubeclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alissa Bonas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|