kubeclient-rollback-dev 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +16 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +428 -0
  8. data/Rakefile +12 -0
  9. data/kubeclient.gemspec +29 -0
  10. data/lib/kubeclient/common.rb +512 -0
  11. data/lib/kubeclient/config.rb +126 -0
  12. data/lib/kubeclient/entity_list.rb +16 -0
  13. data/lib/kubeclient/kube_exception.rb +14 -0
  14. data/lib/kubeclient/missing_kind_compatibility.rb +68 -0
  15. data/lib/kubeclient/version.rb +4 -0
  16. data/lib/kubeclient/watch_notice.rb +7 -0
  17. data/lib/kubeclient/watch_stream.rb +80 -0
  18. data/lib/kubeclient.rb +32 -0
  19. data/test/cassettes/kubernetes_guestbook.yml +879 -0
  20. data/test/config/allinone.kubeconfig +20 -0
  21. data/test/config/external-ca.pem +18 -0
  22. data/test/config/external-cert.pem +19 -0
  23. data/test/config/external-key.rsa +27 -0
  24. data/test/config/external.kubeconfig +20 -0
  25. data/test/config/nouser.kubeconfig +16 -0
  26. data/test/config/userauth.kubeconfig +28 -0
  27. data/test/json/bindings_list.json +10 -0
  28. data/test/json/component_status.json +17 -0
  29. data/test/json/component_status_list.json +52 -0
  30. data/test/json/config_map_list.json +9 -0
  31. data/test/json/core_api_resource_list.json +181 -0
  32. data/test/json/core_api_resource_list_without_kind.json +129 -0
  33. data/test/json/core_oapi_resource_list_without_kind.json +197 -0
  34. data/test/json/created_endpoint.json +28 -0
  35. data/test/json/created_namespace.json +20 -0
  36. data/test/json/created_secret.json +16 -0
  37. data/test/json/created_service.json +31 -0
  38. data/test/json/empty_pod_list.json +9 -0
  39. data/test/json/endpoint_list.json +48 -0
  40. data/test/json/entity_list.json +56 -0
  41. data/test/json/event_list.json +35 -0
  42. data/test/json/limit_range.json +23 -0
  43. data/test/json/limit_range_list.json +31 -0
  44. data/test/json/namespace.json +13 -0
  45. data/test/json/namespace_exception.json +8 -0
  46. data/test/json/namespace_list.json +32 -0
  47. data/test/json/node.json +29 -0
  48. data/test/json/node_list.json +37 -0
  49. data/test/json/persistent_volume.json +37 -0
  50. data/test/json/persistent_volume_claim.json +32 -0
  51. data/test/json/persistent_volume_claim_list.json +40 -0
  52. data/test/json/persistent_volume_claims_nil_items.json +8 -0
  53. data/test/json/persistent_volume_list.json +45 -0
  54. data/test/json/pod.json +92 -0
  55. data/test/json/pod_list.json +79 -0
  56. data/test/json/pod_template_list.json +9 -0
  57. data/test/json/processed_template.json +27 -0
  58. data/test/json/replication_controller.json +57 -0
  59. data/test/json/replication_controller_list.json +66 -0
  60. data/test/json/resource_quota.json +46 -0
  61. data/test/json/resource_quota_list.json +54 -0
  62. data/test/json/secret_list.json +44 -0
  63. data/test/json/service.json +33 -0
  64. data/test/json/service_account.json +25 -0
  65. data/test/json/service_account_list.json +82 -0
  66. data/test/json/service_illegal_json_404.json +1 -0
  67. data/test/json/service_list.json +97 -0
  68. data/test/json/service_patch.json +25 -0
  69. data/test/json/service_update.json +22 -0
  70. data/test/json/versions_list.json +6 -0
  71. data/test/json/watch_stream.json +3 -0
  72. data/test/test_common.rb +32 -0
  73. data/test/test_component_status.rb +30 -0
  74. data/test/test_config.rb +72 -0
  75. data/test/test_endpoint.rb +35 -0
  76. data/test/test_guestbook_go.rb +238 -0
  77. data/test/test_helper.rb +10 -0
  78. data/test/test_kubeclient.rb +611 -0
  79. data/test/test_limit_range.rb +27 -0
  80. data/test/test_missing_methods.rb +42 -0
  81. data/test/test_namespace.rb +61 -0
  82. data/test/test_node.rb +33 -0
  83. data/test/test_persistent_volume.rb +30 -0
  84. data/test/test_persistent_volume_claim.rb +30 -0
  85. data/test/test_pod.rb +29 -0
  86. data/test/test_pod_log.rb +50 -0
  87. data/test/test_process_template.rb +44 -0
  88. data/test/test_replication_controller.rb +27 -0
  89. data/test/test_resource_list_without_kind.rb +78 -0
  90. data/test/test_resource_quota.rb +25 -0
  91. data/test/test_secret.rb +70 -0
  92. data/test/test_service.rb +293 -0
  93. data/test/test_service_account.rb +28 -0
  94. data/test/test_watch.rb +119 -0
  95. data/test/txt/pod_log.txt +6 -0
  96. data/test/valid_token_file +1 -0
  97. metadata +343 -0
@@ -0,0 +1,611 @@
1
+ require 'test_helper'
2
+
3
+ # Kubernetes client entity tests
4
+ class KubeClientTest < MiniTest::Test
5
+ def test_json
6
+ our_object = Kubeclient::Resource.new
7
+ our_object.foo = 'bar'
8
+ our_object.nested = {}
9
+ our_object.nested.again = {}
10
+ our_object.nested.again.again = {}
11
+ our_object.nested.again.again.name = 'aaron'
12
+
13
+ expected = {
14
+ 'foo' => 'bar',
15
+ 'nested' => { 'again' => { 'again' => { 'name' => 'aaron' } } }
16
+ }
17
+
18
+ assert_equal(expected, JSON.parse(JSON.dump(our_object.to_h)))
19
+ end
20
+
21
+ def test_pass_uri
22
+ # URI::Generic#hostname= was added in ruby 1.9.3 and will automatically
23
+ # wrap an ipv6 address in []
24
+ uri = URI::HTTP.build(port: 8080)
25
+ uri.hostname = 'localhost'
26
+ client = Kubeclient::Client.new(uri)
27
+ rest_client = client.rest_client
28
+ assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s)
29
+ end
30
+
31
+ def test_no_path_in_uri
32
+ client = Kubeclient::Client.new('http://localhost:8080', 'v1')
33
+ rest_client = client.rest_client
34
+ assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s)
35
+ end
36
+
37
+ def test_no_version_passed
38
+ client = Kubeclient::Client.new('http://localhost:8080')
39
+ rest_client = client.rest_client
40
+ assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s)
41
+ end
42
+
43
+ def test_pass_proxy
44
+ uri = URI::HTTP.build(host: 'localhost', port: 8080)
45
+ proxy_uri = URI::HTTP.build(host: 'myproxyhost', port: 8888)
46
+ stub_request(:get, %r{/api/v1$})
47
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
48
+
49
+ client = Kubeclient::Client.new(uri, http_proxy_uri: proxy_uri)
50
+ rest_client = client.rest_client
51
+ assert_equal(proxy_uri.to_s, rest_client.options[:proxy])
52
+
53
+ watch_client = client.watch_pods
54
+ assert_equal(watch_client.send(:build_client_options)[:proxy][:proxy_address], proxy_uri.host)
55
+ assert_equal(watch_client.send(:build_client_options)[:proxy][:proxy_port], proxy_uri.port)
56
+ end
57
+
58
+ def test_exception
59
+ stub_request(:get, %r{/api/v1$})
60
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
61
+ stub_request(:post, %r{/services})
62
+ .to_return(body: open_test_file('namespace_exception.json'), status: 409)
63
+
64
+ service = Kubeclient::Resource.new
65
+ service.metadata = {}
66
+ service.metadata.name = 'redisslave'
67
+ service.metadata.namespace = 'default'
68
+ # service.port = 80
69
+ # service.container_port = 6379
70
+ # service.protocol = 'TCP'
71
+
72
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
73
+
74
+ exception = assert_raises(KubeException) do
75
+ service = client.create_service service
76
+ end
77
+
78
+ assert_instance_of(KubeException, exception)
79
+ assert_equal("converting to : type names don't match (Pod, Namespace)",
80
+ exception.message)
81
+ assert_equal(409, exception.error_code)
82
+ end
83
+
84
+ def test_api
85
+ stub_request(:get, 'http://localhost:8080/api')
86
+ .to_return(status: 200, body: open_test_file('versions_list.json'))
87
+
88
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
89
+ response = client.api
90
+ assert_includes(response, 'versions')
91
+ end
92
+
93
+ def test_api_ssl_failure
94
+ error_message = 'certificate verify failed'
95
+
96
+ stub_request(:get, 'http://localhost:8080/api')
97
+ .to_raise(OpenSSL::SSL::SSLError.new(error_message))
98
+
99
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
100
+
101
+ exception = assert_raises(KubeException) { client.api }
102
+ assert_equal(error_message, exception.message)
103
+ end
104
+
105
+ def test_api_valid
106
+ stub_request(:get, 'http://localhost:8080/api')
107
+ .to_return(status: 200, body: open_test_file('versions_list.json'))
108
+
109
+ args = ['http://localhost:8080/api/']
110
+
111
+ [nil, 'v1beta3', 'v1'].each do |version|
112
+ client = Kubeclient::Client.new(*(version ? args + [version] : args))
113
+ assert client.api_valid?
114
+ end
115
+ end
116
+
117
+ def test_api_valid_with_invalid_version
118
+ stub_request(:get, 'http://localhost:8080/api')
119
+ .to_return(status: 200, body: open_test_file('versions_list.json'))
120
+
121
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'foobar1')
122
+ refute client.api_valid?
123
+ end
124
+
125
+ def test_api_valid_with_unreported_versions
126
+ stub_request(:get, 'http://localhost:8080/api')
127
+ .to_return(status: 200, body: '{}')
128
+
129
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
130
+ refute client.api_valid?
131
+ end
132
+
133
+ def test_api_valid_with_invalid_json
134
+ stub_request(:get, 'http://localhost:8080/api')
135
+ .to_return(status: 200, body: '[]')
136
+
137
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
138
+ refute client.api_valid?
139
+ end
140
+
141
+ def test_api_valid_with_bad_endpoint
142
+ stub_request(:get, 'http://localhost:8080/api')
143
+ .to_return(status: [404, 'Resource Not Found'])
144
+
145
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
146
+ assert_raises(KubeException) { client.api_valid? }
147
+ end
148
+
149
+ def test_api_valid_with_non_json
150
+ stub_request(:get, 'http://localhost:8080/api')
151
+ .to_return(status: 200, body: '<html></html>')
152
+
153
+ client = Kubeclient::Client.new('http://localhost:8080/api/')
154
+ assert_raises(JSON::ParserError) { client.api_valid? }
155
+ end
156
+
157
+ def test_nonjson_exception
158
+ stub_request(:get, %r{/api/v1$})
159
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
160
+ stub_request(:get, %r{/servic})
161
+ .to_return(body: open_test_file('service_illegal_json_404.json'), status: 404)
162
+
163
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
164
+
165
+ exception = assert_raises(KubeException) do
166
+ client.get_services
167
+ end
168
+
169
+ assert_instance_of(KubeException, exception)
170
+ assert(exception.message.include?('Not Found'))
171
+ assert_equal(404, exception.error_code)
172
+ end
173
+
174
+ def test_entity_list
175
+ stub_request(:get, %r{/api/v1$})
176
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
177
+ stub_request(:get, %r{/services})
178
+ .to_return(body: open_test_file('entity_list.json'), status: 200)
179
+
180
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
181
+ services = client.get_services
182
+
183
+ refute_empty(services)
184
+ assert_instance_of(Kubeclient::Common::EntityList, services)
185
+ assert_equal('Service', services.kind)
186
+ assert_equal(2, services.size)
187
+ assert_instance_of(Kubeclient::Service, services[0])
188
+ assert_instance_of(Kubeclient::Service, services[1])
189
+
190
+ assert_requested(:get, 'http://localhost:8080/api/v1/services', times: 1)
191
+ end
192
+
193
+ def test_entities_with_label_selector
194
+ selector = 'component=apiserver'
195
+
196
+ stub_request(:get, %r{/api/v1$})
197
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
198
+ stub_request(:get, %r{/services})
199
+ .to_return(body: open_test_file('entity_list.json'), status: 200)
200
+
201
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
202
+ services = client.get_services(label_selector: selector)
203
+
204
+ assert_instance_of(Kubeclient::Common::EntityList, services)
205
+ assert_requested(
206
+ :get,
207
+ "http://localhost:8080/api/v1/services?labelSelector=#{selector}",
208
+ times: 1
209
+ )
210
+ end
211
+
212
+ def test_entities_with_field_selector
213
+ selector = 'involvedObject.name=redis-master'
214
+
215
+ stub_request(:get, %r{/api/v1$})
216
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
217
+ stub_request(:get, %r{/services})
218
+ .to_return(body: open_test_file('entity_list.json'), status: 200)
219
+
220
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
221
+ services = client.get_services(field_selector: selector)
222
+
223
+ assert_instance_of(Kubeclient::Common::EntityList, services)
224
+ assert_requested(
225
+ :get,
226
+ "http://localhost:8080/api/v1/services?fieldSelector=#{selector}",
227
+ times: 1
228
+ )
229
+ end
230
+
231
+ def test_empty_list
232
+ stub_request(:get, %r{/api/v1$})
233
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
234
+ stub_request(:get, %r{/pods})
235
+ .to_return(body: open_test_file('empty_pod_list.json'), status: 200)
236
+
237
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
238
+ pods = client.get_pods
239
+ assert_instance_of(Kubeclient::Common::EntityList, pods)
240
+ assert_equal(0, pods.size)
241
+ end
242
+
243
+ def test_get_all
244
+ stub_request(:get, %r{/api/v1$})
245
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
246
+
247
+ stub_request(:get, %r{/bindings})
248
+ .to_return(body: open_test_file('bindings_list.json'), status: 404)
249
+
250
+ stub_request(:get, %r{/configmaps})
251
+ .to_return(body: open_test_file('config_map_list.json'), status: 200)
252
+
253
+ stub_request(:get, %r{/podtemplates})
254
+ .to_return(body: open_test_file('pod_template_list.json'), status: 200)
255
+
256
+ stub_request(:get, %r{/services})
257
+ .to_return(body: open_test_file('service_list.json'), status: 200)
258
+
259
+ stub_request(:get, %r{/pods})
260
+ .to_return(body: open_test_file('pod_list.json'), status: 200)
261
+
262
+ stub_request(:get, %r{/nodes})
263
+ .to_return(body: open_test_file('node_list.json'), status: 200)
264
+
265
+ stub_request(:get, %r{/replicationcontrollers})
266
+ .to_return(body: open_test_file('replication_controller_list.json'), status: 200)
267
+
268
+ stub_request(:get, %r{/events})
269
+ .to_return(body: open_test_file('event_list.json'), status: 200)
270
+
271
+ stub_request(:get, %r{/endpoints})
272
+ .to_return(body: open_test_file('endpoint_list.json'), status: 200)
273
+
274
+ stub_request(:get, %r{/namespaces})
275
+ .to_return(body: open_test_file('namespace_list.json'), status: 200)
276
+
277
+ stub_request(:get, %r{/secrets})
278
+ .to_return(body: open_test_file('secret_list.json'), status: 200)
279
+
280
+ stub_request(:get, %r{/resourcequotas})
281
+ .to_return(body: open_test_file('resource_quota_list.json'), status: 200)
282
+
283
+ stub_request(:get, %r{/limitranges})
284
+ .to_return(body: open_test_file('limit_range_list.json'), status: 200)
285
+
286
+ stub_request(:get, %r{/persistentvolumes})
287
+ .to_return(body: open_test_file('persistent_volume_list.json'), status: 200)
288
+
289
+ stub_request(:get, %r{/persistentvolumeclaims})
290
+ .to_return(body: open_test_file('persistent_volume_claim_list.json'), status: 200)
291
+
292
+ stub_request(:get, %r{/componentstatuses})
293
+ .to_return(body: open_test_file('component_status_list.json'), status: 200)
294
+
295
+ stub_request(:get, %r{/serviceaccounts})
296
+ .to_return(body: open_test_file('service_account_list.json'), status: 200)
297
+
298
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
299
+ result = client.all_entities
300
+ assert_equal(16, result.keys.size)
301
+ assert_instance_of(Kubeclient::Common::EntityList, result['node'])
302
+ assert_instance_of(Kubeclient::Common::EntityList, result['service'])
303
+ assert_instance_of(Kubeclient::Common::EntityList, result['replication_controller'])
304
+ assert_instance_of(Kubeclient::Common::EntityList, result['pod'])
305
+ assert_instance_of(Kubeclient::Common::EntityList, result['event'])
306
+ assert_instance_of(Kubeclient::Common::EntityList, result['namespace'])
307
+ assert_instance_of(Kubeclient::Common::EntityList, result['secret'])
308
+ assert_instance_of(Kubeclient::Service, result['service'][0])
309
+ assert_instance_of(Kubeclient::Node, result['node'][0])
310
+ assert_instance_of(Kubeclient::Event, result['event'][0])
311
+ assert_instance_of(Kubeclient::Endpoint, result['endpoint'][0])
312
+ assert_instance_of(Kubeclient::Namespace, result['namespace'][0])
313
+ assert_instance_of(Kubeclient::Secret, result['secret'][0])
314
+ assert_instance_of(Kubeclient::ResourceQuota, result['resource_quota'][0])
315
+ assert_instance_of(Kubeclient::LimitRange, result['limit_range'][0])
316
+ assert_instance_of(Kubeclient::PersistentVolume, result['persistent_volume'][0])
317
+ assert_instance_of(Kubeclient::PersistentVolumeClaim, result['persistent_volume_claim'][0])
318
+ assert_instance_of(Kubeclient::ComponentStatus, result['component_status'][0])
319
+ assert_instance_of(Kubeclient::ServiceAccount, result['service_account'][0])
320
+ end
321
+
322
+ def test_api_bearer_token_with_params_success
323
+ stub_request(:get, 'http://localhost:8080/api/v1/pods?labelSelector=name=redis-master')
324
+ .with(headers: { Authorization: 'Bearer valid_token' })
325
+ .to_return(body: open_test_file('pod_list.json'), status: 200)
326
+ stub_request(:get, %r{/api/v1$})
327
+ .with(headers: { Authorization: 'Bearer valid_token' })
328
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
329
+
330
+ client = Kubeclient::Client.new(
331
+ 'http://localhost:8080/api/',
332
+ auth_options: { bearer_token: 'valid_token' }
333
+ )
334
+
335
+ pods = client.get_pods(label_selector: 'name=redis-master')
336
+
337
+ assert_equal('Pod', pods.kind)
338
+ assert_equal(1, pods.size)
339
+ end
340
+
341
+ def test_api_bearer_token_success
342
+ stub_request(:get, %r{/api/v1$})
343
+ .to_return(
344
+ body: open_test_file('core_api_resource_list.json'), status: 200
345
+ )
346
+ stub_request(:get, 'http://localhost:8080/api/v1/pods')
347
+ .with(headers: { Authorization: 'Bearer valid_token' })
348
+ .to_return(
349
+ body: open_test_file('pod_list.json'), status: 200
350
+ )
351
+
352
+ client = Kubeclient::Client.new(
353
+ 'http://localhost:8080/api/',
354
+ auth_options: { bearer_token: 'valid_token' }
355
+ )
356
+
357
+ pods = client.get_pods
358
+
359
+ assert_equal('Pod', pods.kind)
360
+ assert_equal(1, pods.size)
361
+ end
362
+
363
+ def test_api_bearer_token_failure
364
+ error_message =
365
+ '"/api/v1" is forbidden because ' \
366
+ 'system:anonymous cannot list on pods in'
367
+ response = OpenStruct.new(code: 401, message: error_message)
368
+
369
+ stub_request(:get, 'http://localhost:8080/api/v1')
370
+ .with(headers: { Authorization: 'Bearer invalid_token' })
371
+ .to_raise(KubeException.new(403, error_message, response))
372
+
373
+ client = Kubeclient::Client.new(
374
+ 'http://localhost:8080/api/',
375
+ auth_options: { bearer_token: 'invalid_token' }
376
+ )
377
+
378
+ exception = assert_raises(KubeException) { client.get_pods }
379
+ assert_equal(403, exception.error_code)
380
+ assert_equal(error_message, exception.message)
381
+ assert_equal(response, exception.response)
382
+ end
383
+
384
+ def test_api_basic_auth_success
385
+ stub_request(:get, 'http://username:password@localhost:8080/api/v1')
386
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
387
+ stub_request(:get, 'http://username:password@localhost:8080/api/v1/pods')
388
+ .to_return(body: open_test_file('pod_list.json'), status: 200)
389
+
390
+ client = Kubeclient::Client.new(
391
+ 'http://localhost:8080/api/',
392
+ auth_options: { username: 'username', password: 'password' }
393
+ )
394
+
395
+ pods = client.get_pods
396
+
397
+ assert_equal('Pod', pods.kind)
398
+ assert_equal(1, pods.size)
399
+ assert_requested(
400
+ :get,
401
+ 'http://username:password@localhost:8080/api/v1/pods',
402
+ times: 1
403
+ )
404
+ end
405
+
406
+ def test_api_basic_auth_back_comp_success
407
+ stub_request(:get, 'http://username:password@localhost:8080/api/v1')
408
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
409
+ stub_request(:get, 'http://username:password@localhost:8080/api/v1/pods')
410
+ .to_return(body: open_test_file('pod_list.json'), status: 200)
411
+
412
+ client = Kubeclient::Client.new(
413
+ 'http://localhost:8080/api/',
414
+ auth_options: { user: 'username', password: 'password' }
415
+ )
416
+
417
+ pods = client.get_pods
418
+
419
+ assert_equal('Pod', pods.kind)
420
+ assert_equal(1, pods.size)
421
+ assert_requested(:get, 'http://username:password@localhost:8080/api/v1/pods', times: 1)
422
+ end
423
+
424
+ def test_api_basic_auth_failure
425
+ error_message = 'HTTP status code 401, 401 Unauthorized'
426
+ response = OpenStruct.new(code: 401, message: '401 Unauthorized')
427
+
428
+ stub_request(:get, 'http://username:password@localhost:8080/api/v1')
429
+ .to_raise(KubeException.new(401, error_message, response))
430
+
431
+ client = Kubeclient::Client.new(
432
+ 'http://localhost:8080/api/',
433
+ auth_options: { username: 'username', password: 'password' }
434
+ )
435
+
436
+ exception = assert_raises(KubeException) { client.get_pods }
437
+ assert_equal(401, exception.error_code)
438
+ assert_equal(error_message, exception.message)
439
+ assert_equal(response, exception.response)
440
+ assert_requested(:get, 'http://username:password@localhost:8080/api/v1', times: 1)
441
+ end
442
+
443
+ def test_init_username_no_password
444
+ expected_msg = 'Basic auth requires both username & password'
445
+ exception = assert_raises(ArgumentError) do
446
+ Kubeclient::Client.new(
447
+ 'http://localhost:8080',
448
+ auth_options: { username: 'username' }
449
+ )
450
+ end
451
+ assert_equal(expected_msg, exception.message)
452
+ end
453
+
454
+ def test_init_user_no_password
455
+ expected_msg = 'Basic auth requires both username & password'
456
+ exception = assert_raises(ArgumentError) do
457
+ Kubeclient::Client.new(
458
+ 'http://localhost:8080',
459
+ auth_options: { user: 'username' }
460
+ )
461
+ end
462
+ assert_equal(expected_msg, exception.message)
463
+ end
464
+
465
+ def test_init_username_and_bearer_token
466
+ expected_msg = 'Invalid auth options: specify only one of username/password,' \
467
+ ' bearer_token or bearer_token_file'
468
+ exception = assert_raises(ArgumentError) do
469
+ Kubeclient::Client.new(
470
+ 'http://localhost:8080',
471
+ auth_options: { username: 'username', bearer_token: 'token' }
472
+ )
473
+ end
474
+ assert_equal(expected_msg, exception.message)
475
+ end
476
+
477
+ def test_init_user_and_bearer_token
478
+ expected_msg = 'Invalid auth options: specify only one of username/password,' \
479
+ ' bearer_token or bearer_token_file'
480
+ exception = assert_raises(ArgumentError) do
481
+ Kubeclient::Client.new(
482
+ 'http://localhost:8080',
483
+ auth_options: { username: 'username', bearer_token: 'token' }
484
+ )
485
+ end
486
+ assert_equal(expected_msg, exception.message)
487
+ end
488
+
489
+ def test_bearer_token_and_bearer_token_file
490
+ expected_msg =
491
+ 'Invalid auth options: specify only one of username/password,' \
492
+ ' bearer_token or bearer_token_file'
493
+ exception = assert_raises(ArgumentError) do
494
+ Kubeclient::Client.new(
495
+ 'http://localhost:8080',
496
+ auth_options: { bearer_token: 'token', bearer_token_file: 'token-file' }
497
+ )
498
+ end
499
+ assert_equal(expected_msg, exception.message)
500
+ end
501
+
502
+ def test_bearer_token_file_not_exist
503
+ expected_msg = 'Token file token-file does not exist'
504
+ exception = assert_raises(ArgumentError) do
505
+ Kubeclient::Client.new(
506
+ 'http://localhost:8080',
507
+ auth_options: { bearer_token_file: 'token-file' }
508
+ )
509
+ end
510
+ assert_equal(expected_msg, exception.message)
511
+ end
512
+
513
+ def test_api_bearer_token_file_success
514
+ stub_request(:get, %r{/api/v1$})
515
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
516
+ stub_request(:get, 'http://localhost:8080/api/v1/pods')
517
+ .with(headers: { Authorization: 'Bearer valid_token' })
518
+ .to_return(body: open_test_file('pod_list.json'), status: 200)
519
+
520
+ file = File.join(File.dirname(__FILE__), 'valid_token_file')
521
+ client = Kubeclient::Client.new(
522
+ 'http://localhost:8080/api/',
523
+ auth_options: { bearer_token_file: file }
524
+ )
525
+
526
+ pods = client.get_pods
527
+
528
+ assert_equal('Pod', pods.kind)
529
+ assert_equal(1, pods.size)
530
+ end
531
+
532
+ def test_proxy_url
533
+ stub_request(:get, %r{/api/v1$})
534
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
535
+
536
+ client = Kubeclient::Client.new('http://host:8080', 'v1')
537
+ assert_equal(
538
+ 'http://host:8080/api/v1/proxy/namespaces/ns/services/srvname:srvportname',
539
+ client.proxy_url('service', 'srvname', 'srvportname', 'ns')
540
+ )
541
+
542
+ assert_equal(
543
+ 'http://host:8080/api/v1/proxy/namespaces/ns/services/srvname:srvportname',
544
+ client.proxy_url('services', 'srvname', 'srvportname', 'ns')
545
+ )
546
+
547
+ assert_equal(
548
+ 'http://host:8080/api/v1/namespaces/ns/pods/srvname:srvportname/proxy',
549
+ client.proxy_url('pod', 'srvname', 'srvportname', 'ns')
550
+ )
551
+
552
+ assert_equal(
553
+ 'http://host:8080/api/v1/namespaces/ns/pods/srvname:srvportname/proxy',
554
+ client.proxy_url('pods', 'srvname', 'srvportname', 'ns')
555
+ )
556
+
557
+ # Check no namespace provided
558
+ assert_equal(
559
+ 'http://host:8080/api/v1/proxy/nodes/srvname:srvportname',
560
+ client.proxy_url('nodes', 'srvname', 'srvportname')
561
+ )
562
+
563
+ assert_equal(
564
+ 'http://host:8080/api/v1/proxy/nodes/srvname:srvportname',
565
+ client.proxy_url('node', 'srvname', 'srvportname')
566
+ )
567
+
568
+ # Check integer port
569
+ assert_equal(
570
+ 'http://host:8080/api/v1/proxy/nodes/srvname:5001',
571
+ client.proxy_url('nodes', 'srvname', 5001)
572
+ )
573
+
574
+ assert_equal(
575
+ 'http://host:8080/api/v1/proxy/nodes/srvname:5001',
576
+ client.proxy_url('node', 'srvname', 5001)
577
+ )
578
+ end
579
+
580
+ def test_attr_readers
581
+ client = Kubeclient::Client.new(
582
+ 'http://localhost:8080/api/',
583
+ ssl_options: { client_key: 'secret' },
584
+ auth_options: { bearer_token: 'token' }
585
+ )
586
+ assert_equal('/api', client.api_endpoint.path)
587
+ assert_equal('secret', client.ssl_options[:client_key])
588
+ assert_equal('token', client.auth_options[:bearer_token])
589
+ assert_equal('Bearer token', client.headers[:Authorization])
590
+ end
591
+
592
+ def test_nil_items
593
+ # handle https://github.com/kubernetes/kubernetes/issues/13096
594
+ stub_request(:get, %r{/api/v1$})
595
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
596
+ stub_request(:get, %r{/persistentvolumeclaims})
597
+ .to_return(body: open_test_file('persistent_volume_claims_nil_items.json'), status: 200)
598
+
599
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
600
+ client.get_persistent_volume_claims
601
+ end
602
+
603
+ private
604
+
605
+ # dup method creates a shallow copy which is not good in this case
606
+ # since rename_keys changes the input hash
607
+ # hence need to create a deep_copy
608
+ def deep_copy(hash)
609
+ Marshal.load(Marshal.dump(hash))
610
+ end
611
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ # LimitRange tests
4
+ class TestLimitRange < MiniTest::Test
5
+ def test_get_from_json_v1
6
+ stub_request(:get, %r{/api/v1$})
7
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
8
+
9
+ stub_request(:get, %r{/limitranges})
10
+ .to_return(body: open_test_file('limit_range.json'), status: 200)
11
+
12
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
13
+ limit_range = client.get_limit_range 'limits', 'quota-example'
14
+
15
+ assert_instance_of(Kubeclient::LimitRange, limit_range)
16
+ assert_equal('limits', limit_range.metadata.name)
17
+ assert_equal('Container', limit_range.spec.limits[0].type)
18
+ assert_equal('100m', limit_range.spec.limits[0].default.cpu)
19
+ assert_equal('512Mi', limit_range.spec.limits[0].default.memory)
20
+
21
+ assert_requested(
22
+ :get,
23
+ 'http://localhost:8080/api/v1/namespaces/quota-example/limitranges/limits',
24
+ times: 1
25
+ )
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ # Test method_missing, respond_to? and respond_to_missing behaviour
4
+ class TestMissingMethods < MiniTest::Test
5
+ def test_missing
6
+ stub_request(:get, %r{/api/v1$}).to_return(
7
+ body: open_test_file('core_api_resource_list.json'),
8
+ status: 200
9
+ )
10
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
11
+ assert_equal(true, client.respond_to?(:get_pod))
12
+ assert_equal(true, client.respond_to?(:get_pods))
13
+ assert_equal(false, client.respond_to?(:get_pie))
14
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1') # Reset discovery
15
+ assert_equal(false, client.respond_to?(:get_pie))
16
+ assert_equal(true, client.respond_to?(:get_pods))
17
+ assert_equal(true, client.respond_to?(:get_pod))
18
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1') # Reset discovery
19
+ assert_instance_of(Method, client.method(:get_pods))
20
+ assert_raises(NameError) do
21
+ client.method(:get_pies)
22
+ end
23
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1') # Reset discovery
24
+ assert_raises(NameError) do
25
+ client.method(:get_pies)
26
+ end
27
+ assert_instance_of(Method, client.method(:get_pods))
28
+
29
+ stub_request(:get, %r{/api/v1$}).to_return(
30
+ body: '',
31
+ status: 404
32
+ ) # If discovery fails we expect the below raise an exception
33
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
34
+ assert_raises(KubeException) do
35
+ client.method(:get_pods)
36
+ end
37
+ client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
38
+ assert_raises(KubeException) do
39
+ client.respond_to?(:get_pods)
40
+ end
41
+ end
42
+ end