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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48d448677cbf44234e974ccb8abd00002c729b059f8857120f11d7a017c63f96
4
- data.tar.gz: 1db9a01ab5819636816562bd60b563db6e1aa20aa45f8e8b1283da35e1c77a37
3
+ metadata.gz: 3c8f79b61300006829c55c6b13715e6073a1cf9517ad8334959ff64706bee4ca
4
+ data.tar.gz: 04ae220b4f78422992e34538e5b47a0dbf0a832aa2eb9f1ac86d3f1c221cd088
5
5
  SHA512:
6
- metadata.gz: f3ba57f5db5c09035f1ae3265203f5eb64858b7383c9cb73a9e2186befc4b7c120db3984634626895143c5409c9b943103d93a106274b4d61f57579d2e22ba93
7
- data.tar.gz: 2154232e7359a4e3eae7191093338cce2f6daa44abf30f663bbe59631435927519f7e342dd103a485726375bdfde5d556c3a825b3dbd063d23f055e5eb16ad1e
6
+ metadata.gz: b7c9ab202ff3e30f5884fd2f80987fe87a3a65a86fa1a3ecdba16383cbb958fdb98f02dd48a00a5ac50fac828b335a33b33f634f7e2cbe7913883e5aa9a81fa4
7
+ data.tar.gz: 52078faf6ec204c2b08658d83604fb84c7e68ad409d754ada7ae9d0d989fbce01ae53b2c33993dc71a6bed5851904fe22b6cd3688f67fa1c4bf9cd7704c43f71
@@ -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
@@ -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?('exec')
153
- exec_opts = expand_command_option(user['exec'], 'command')
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 token(opts)
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']['token']
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
- raise 'exec plugin didn\'t return a status field' if creds['status'].nil?
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
@@ -1,4 +1,4 @@
1
1
  # Kubernetes REST-API Client
2
2
  module Kubeclient
3
- VERSION = '4.8.0'.freeze
3
+ VERSION = '4.9.0'.freeze
4
4
  end
@@ -1,13 +1,13 @@
1
1
  require_relative 'test_helper'
2
2
  require 'open3'
3
3
 
4
- # Unit tests for the ExecCredentials token provider
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.token(nil)
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.token({})
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.token(opts)
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 test_token
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': 'client.authentication.k8s.io/v1alpha1',
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
- assert_equal('0123456789ABCDEF0123456789ABCDEF', Kubeclient::ExecCredentials.token(opts))
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': 'client.authentication.k8s.io/v1alpha1')
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.token(opts)
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 test_token_missing
178
+ def test_credentials_missing
79
179
  opts = { 'command' => 'dummy' }
80
180
 
81
181
  creds = JSON.dump(
82
- 'apiVersion': 'client.authentication.k8s.io/v1alpha1',
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.token(opts)
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': api_version
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.token(opts)
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.8.0
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-07-03 00:00:00.000000000 Z
11
+ date: 2020-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler